布団の中にいたい

最近Androidのアプリ開発の勉強をし始めた人.資料作りの会社から転職して、最近はgoを書いてる

ubuntu16.04にelasticsearch + kibanaを導入する

前の記事でkibanaの前にnginxをおいて認証をかけるみたいな記事を書きましたが、elasticsearch + kibana自体のインストールも少し手こずったのでメモ書き程度にまとめます。

やること

javaのインストー

elasticsearchはjavaで書かれたソフトウェアなので実行環境としてjavaを入れる必要があります。

sudo apt-get update
sudo apt-get install openjdk-8-jdk-headless

elasticsearch

インストールは公式のドキュメントに従います

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
sudo apt-get install apt-transport-https
echo "deb https://artifacts.elastic.co/packages/5.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-5.x.list

sudo apt-get update
sudo apt-get install elasticsearch

起動は以下

sudo service elasticsearch start

細かい設定ファイルは/etc/elasticsearch以下にあるので、メモリを調整したかったりするときは、この辺のファイルをいじるといいと思います。

elasticsearchはリクエストを受け付けるように9200ポート、他ノードとの連携用に9300ポートを利用しているみたいです。その辺のポートが開いていなければ順次ポートをずらしていくみたいです。

kibana

elasticsearchが導入できていたらそのままapt-getで入れられます。

sudo apt-get update
sudo apt-get install kibana

kibanaの起動は以下

sudo service kibana start

kibanaって前まで静的コンテツをelasticsearch配下に置くイメージだったんですが、いつの間にかnodejsのアプリケーションになってたんですね。調べて見る限りでは、elasticsearch 5系からsite pluginが廃止になった影響で使えなくなったのが理由みたいです。 elasticsearch-headとかも使えないっぽいので注意が必要そうです。

まとめ

今回はubuntuにelasticsearchとkibanaを導入しました。kibanaがnodejsのアプリケーションになってるのは衝撃でしたが、問題なくインストールできました。今度は管理系UIを調べて導入してみようかと思います。

nginxでbasic認証をかける

localで運用しているelasticsearch + kibanaをクラウドに移行しようと考えていたのですが、 awsのelasticsearchは予想外に金額が高かったのでconohaのVPSで運用することにしました。 X-Packを使えばkibana自体に認証をかけられますが、それも有料なのでどうしたもんかと考えた結果、 kibanaの前にnginxをおいて、そこに認証をかけてしまうことにしました。

ちらっと聞いた話でnginxでbasic認証をかけるのは簡単という話を聞いたので試してみました。

やることは以下

  • htpasswdでアカウントとパスワードを設定する
  • nginx側で認証をかける

htpasswdでアカウントとパスワードを設定する

htpasswdはbasic認証で利用できるファイルを生成してくれるコマンドです。便利ですね。インストールは以下のコマンドでできます。

sudo apt-get install apache2-utils

ファイル生成は以下

sudo htpasswd -c /etc/nginx/.htpasswd account_name

nginx側で認証をかける

htpasswdで生成したファイルをnginx.confで指定してあげます。全体に認証をかけることもできますし、任意の部分にかけることもできます。 今回はkibanaへのアクセス部分にかけるのでlocationにかきます。

upstream elasticsearch {
  server localhost:9200;
}

upstream kibana {
  server localhost:5601;
}

http {
  server {
    listen 80;
    server_name localhost;

    location / {
      auth_basic "Restricted";
      auth_basic_user_file /etc/nginx/.htpasswd;
      proxy_pass http://kibana;
    }
  }
}

設定したあと、nginxをrestartすればできます。大変楽でいいですね。

まとめ

今回はnginxでさくっとbasic認証をかけてみました。今までは割とクライアント周りばかりを触っていたのでweb serverなどをほとんど触っていなかったのですが、大雑把な部分は簡単にできるようでよかったです。細かい部分についてはまたおいおいやっていければと思います。

vimでRustを書く(環境構築)

周囲の人たちから「Rustいいよ」、「Rust書こうよ」とポツポツ言われるので流れにのって入門してみることにしました。

といっても今回やるのは環境構築のみ。Rustさっぱりなので、慣れてきたら適当にメモを書いていきます。

私が普段vimでコードを書いているのでvimで書くまでを目標にします。

やること

  • Rustのインストー
  • rustfmtとracerのインストー
  • rust.vimvim-racerをインストー
  • 自動でフォーマットするようにする

Rustのインストー

macでhomebrewを使うと以下でできるみたいですが、私はmac使いじゃないので公式ページに書かれてる方法を使います

brew install rust

公式ページは以下

www.rust-lang.org

インストール方法は以下

curl https://sh.rustup.rs -sSf | sh

上記のコマンドで、rustrcとcargoが入ります。

rustfmtとracerのインストー

rustfmtとracerについて簡単に説明すると、rustfmtはRustのガイドラインにしたがって、Rustで書かれたソースをフォーマットしてくれるツールです。racerはRustのコード補完ツールみたいです(詳しいことは知らない)

これらはそれぞれcargoで入れられます。cargoはRustのパッケージ管理ツールです。 rustfmtとracerのインストールは以下

cargo install rustfmt
cargo install racer

難しいこと考えなくていいのでいいんですね。こういうの好きです。

rust.vimvim-racerのインストー

私がdein.vimを使ってるのでそれに準ずる方法でインストールします。toml使ってplugin管理してる人が多いと思いますが、めんどくさかったのでvimrcに直書きしてます。すいません。

vimrcに追記したのは以下

call dein#add('rust-lang/rust.vim')
call dein#add('racer-rust/vim-racer')

自動でフォーマットするようにする

rustfmtを入れたのでどうせなら保存したら自動でフォーマットしてくれると助かります。

追記したのは以下

let g:rustfmt_autosave = 1

まとめ

今回は自動フォーマットまでをまとめました。結局のところ、まだRust書いてないので、ぼちぼち書いていこうと思います。

追記

衝撃の事実。homebrewでインストールしたrustのcargoを使って、rustfmtをインストールしようとするとエラーで落ちるっぽいです。

github.com

goでconnpassのイベントを検索するslackbotを作ってみた

つい最近のGoogle I/Oでkotlinがandroidアプリ開発の公式言語に追加された影響か、大したこと書いてないですが意外にアクセスが来ていて嬉しい限りです。 とりあえず間違った情報は流さないようにしたいと思います。

今回は今までのandroid + kotlin押しとは打って変わって、golangでslackbotを作ってみたというお話です。

最近仕事でslackを使い始めたので、slackに慣れるついでにslackbotを作ってみましたというのがモチベーションです。 connpassを選んだ理由はAPIで提供している機能が検索しかないので、とりあえずで実装してみる分にはそこまで難しくなさそうというだけです。

書いたコードは以下

github.com

実装内容

使用したライブラリ

詰まったところ

今回botを作る上で実装したいと考えていたのは以下の二点です。 - botを呼び出した人にmentionを飛ばすようにする - コマンドを幾つか用意する

この中で「botを呼び出した人にmentionを飛ばすようにする」で若干つまりました。

やってみると意外に簡単で飛ばすメッセージに"<@飛ばす先のアカウントID>“を付加するだけで大丈夫でした。

まとめ

だいぶざっくりした感じになってしましましたが、やってみると意外に簡単にできるので試しに作ってみてもいいかもしれません。

spark(web framework)で遊んでみようとしたら最初の実行で怒られた

sparkで簡単なWebアプリを作ってみようと思ったのですが、詰まったのでメモ。

詰まったのは起動方法です。 ただHello Worldをさせようと思ったのですが、そこで詰まりました。 エラーは以下です。

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

調べてみると、gradleに記述したライブラリでslf4jを使用しているものがあり、slf4jをインストールする必要があるみたいです。 加えて、slf4jの設定ファイルをsrc/main/resourcesに追加する必要があります。

以下の記事を参考にさせていただきました。

blog.stormcat.io

onBackPressedの落とし穴

onKeyDownをonBackPressedに切り替えて使ってみたら、問答無用で遷移前のActivityに戻されてしまう現象に遭遇しました。正直中途半端な知識で使うのはどうかと思っていたので、内部でどのような動作をしているか少し調べてみました。

ソースコードをどんどん辿っていったところ、onBackPressedが定義されているのは、Activity.javaの内部です。同様にonKeyDownもActivity.javaにありました。

実装されていたonBackPressedは以下です。

コメントを見るだけで何やら不穏な空気が漂っていますね。とりあえず簡単な実装として、何かするためにonBackPressedをoverrideできるときは現在のActivityを終了しますとのこと。

    /**
     * Called when the activity has detected the user's press of the back
     * key.  The default implementation simply finishes the current activity,
     * but you can override this to do whatever you want.
     */
    public void onBackPressed() {
        if (mActionBar != null && mActionBar.collapseActionView()) {
            return;
        }

        if (!mFragments.getFragmentManager().popBackStackImmediate()) {
            finishAfterTransition();
        }
    }

終了処理は、finishAfterTransitionっぽいですね。Fragmentのスタックから何も取り出せないとき(addToBackStackとかしてない)にこの処理に入ります。次にfinishAfterTransitionを見てみます。

ActivityTransitionStateはActivityの遷移状況を管理しているんですかね。ソース眺めてみましたが、他のものと違って色々知識が必要なので、メソッド名の字面から判断します。

    /**
     * Reverses the Activity Scene entry Transition and triggers the calling Activity
     * to reverse its exit Transition. When the exit Transition completes,
     * {@link #finish()} is called. If no entry Transition was used, finish() is called
     * immediately and the Activity exit Transition is run.
     * @see android.app.ActivityOptions#makeSceneTransitionAnimation(Activity, android.util.Pair[])
     */
    public void finishAfterTransition() {
        if (!mActivityTransitionState.startExitBackTransition(this)) {
            finish();
        }
    }

すべてを理解しきれたわけではありませんが、onBackPressedの行き着く先にはfinishがいることがわかりました。ちらっとonKeyDownも眺めてみましたが、実のところ、内部でonBackPressedを呼んでいたので使う際は注意が必要かもしれません。

PS Android Studioのどんどんメソッドを辿っていける機能、ソース読むときにかなり便利だということに気づきました。

SearchViewの背景色を変更する

SearchViewを導入して、クエリを入力して検索するところまで出来たので、今度はSearchViewの見た目自体を変更しようとしたのですが、かなり詰まったので、その際に調べた内容をまとめます。

SearchViewは他のViewとは微妙に異なっていて、SearchView自体が複数のViewから構成されるViewになっています。具体例で言うと、実際にクエリを入力するEditTextや検索アイコンのImageViewなどが内部で定義されています。なので、アイコンを変えたり背景色を変えたいという場合は、その内部で定義されているViewを変更してあげれば大丈夫です。

今回、SearchViewの背景色を変更したかったので、以下のようにしました。

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.main, menu)

    val menuItem = menu.findItem(R.id.action_search)
    val searchView = MenuItemCompat.getActionView(menuItem) as SearchView

    searchView.findViewById(android.support.v7.appcompat.R.id.search_edit_frame)
            .setBackgroundColor(R.color.white)
   
    // 以下任意の処理
}

これでSearchViewの背景色を変更することができました。他にもsearch_mag_icon(検索アイコン)だったり、search_close_button(☓ボタン)があったりします。SearchViewの何かしらを変更する際は、SearchViewの子要素を色々変更するといいかもしれません。