2015年9月30日水曜日

AndroidStudio で Lombok を使用する方法

概要

AndroidStudio だとデフォルトでは Lombok が使えないようです

環境

  • AndroidStudio 1.3.2
  • Lombok plugin 0.9.6

プラグインインストール

  • AndroidStudio -> Preferences
    preferences.png

  • Plugins -> 「lom」と入力 -> Browse をクリック
    search_lombok.png

  • 「Lombok Plugin」を選択 -> Install plugin をクリック
    install_lombok.png

  • 確認ダイアログで Yes をクリック
    confirm.png

あとは再起動を実施すればプラグインが有効になり Lombok を使っていてもエラーとなりません

もちろんプラグインをインストールしただけだと Lombok は使えないので build.gradle の dependencies に以下を記載してください

compile 'org.projectlombok:lombok:1.16.6'

2015年9月29日火曜日

【Cygwin】MD5 sum did not match, exiting

概要

apt-cyg 実行時にタイトルのエラーが出現したので対応しました

環境

  • Windows7 64bit
  • Cygwin 2.2.1
  • apt-cyg 0.59

apt-cyg のコマンドを編集

apt-cyg コマンドを /usr/bin/apt-cyg にインストールしているものとします

  • cp /usr/bin/apt-cyg{,.back}
  • vim /usr/bin/apt-cyg
    で以下となるように編集してください
$ diff /usr/bin/apt-cyg{,.back}
343,344c343
<     #digactual=`md5sum $file | awk '{print $1}'`
<     digactual=`sha512sum $file | awk '{print $1}'`
---
>     digactual=`md5sum $file | awk '{print $1}'`

md5sum となっている部分を sha512sum に書き換えます
これで再度 install を実施すれば該当のエラーは出なくなると思います

apt-cyg のバージョンによっては書き換える部分が異なると思いますので注意してください

参考サイト

2015年9月28日月曜日

Mongo のスロークエリを ElasticSearch に集約してみる

概要

MongoDB のスロークエリログを td-agent に食わせて、ElasticSearch にスロークエリログを溜め込んでみました

環境

  • CentOS release 6.3 (Final)
  • td-agent 0.12.12
    • fluent-plugin-mongo-slow-query (0.1.1)
    • fluent-plugin-secure-forward (0.3.2)
  • ElasticSearch 1.5.2-1

Mongo のスロークエリを td-agent に食わす

fluent-plugin-mongo-slow-query のインストール

  • td-agent-gem install fluent-plugin-mongo-slow-query fluent-plugin-secure-forward

今回は fluent-plugin-secure-forward も使うのでインストールしておきます
もちろんなくても OK です

送信側の td-agent.conf の編集

  • vim /etc/td-agent/td-agent.conf
<source>
  type mongo_slow_query
  path /var/log/mongodb/mongod.log
  tag mongod.log
</source>

<match mongod.log>
  secure no
  type secure_forward
  shared_key xxxxxxxxxx
  self_hostname mongo001
  <server>
    host elastic001
    port 24284
  </server>
</match>

source に解析対象の mongod.log の指定します
mongod.log にはあらかじめ「–slowms」オプションを使ってスロークエリが出力されるようにしておきます
tag も設定しておきましょう

match で設定した tag の情報を受け取ります
受け取ったあとは secure_forward を使って ElasticSearch サーバに送信します
secure_forward の port はデフォルトの 24284 を使っています

受け取り側 (ElasticSearch側) の td-agent.conf の設定

受け取り側でも td-agent を起動して送信側から secure_forward で送信されたデータを受け取ります

  • vim /etc/td-agent/td-agent.conf
<source>
  type secure_forward
  shared_key xxxxxxxxxx
  self_hostname elastic001
  cert_auto_generate yes
</source>

<match mongod.log>
  type elasticsearch
  logstash_format true
  logstash_prefix mongod_log
</match>

secure_forward で飛んできた情報を source で受け取り、受け取った情報に含まれている tag を元に match で処理させます

type elasticsearch を指定することで ElasticSearch にデータを送信することができます
port や host パラメータを指定しないとデフォルトの localhost:9200 に接続しにいきます
なので、あらかじめ ElasticSearch のインストールおよび設定、起動は実施しておきましょう

td-agent がいい感じに ElasticSearch にデータを入れてくれるので ElasticSearch 側は特に何も設定しないで起動しておけば OK だと思います

動作確認

各種 td-agent, ElasticSearch を起動しましょう
起動したら mongod.log にスロークエリが出るようなクエリを投げます
mongod.log にスロークエリログが出たら ElasticSearch 側にデータ入っているか確認してみます

データが ElasticSearch に入っているか確認する

localhost に API をコールして確認してみます

  • curl -X GET ‘localhost:9200/mongod_log-2015.09.24’

みたいなインデックスにアクセスすれば Json データが取得できると思います
もしインデックス名がわからない場合は

  • curl -XGET ‘localhost:9200/_cat/indices?v’ | grep mongo

あたりでインデックスの一覧が確認できます
それでもインデックスがない場合はうまく ElasticSearch にデータが送られていないことになります

今回の場合、secure_forward でデータを連携しているため、サーバ間の ACL を確認したり、secure_forward の文字列が正しいか確認してみてください
それでもダメな場合は一旦、type file を使うなどしてデータが取得 - 連携されているか確認してください

2015年9月25日金曜日

SpringXD 試してみた

概要

SpringXD はリアルタイム解析やバッチ処理、データエクスポートを実現するためのフレームワークです
シングル構成で動作する QuickStart を試してみました

環境

  • CentOS 6.6 64bit
  • SpringXD 1.2.1
  • Java 1.8.0_45

インストール

RHEL 系の OS であれば rpm からインストールすることができます

  • wget https://repo.spring.io/libs-release-local/org/springframework/xd/spring-xd/1.2.1.RELEASE/spring-xd-1.2.1.RELEASE-1.noarch.rpm
  • rpm -ivh spring-xd-1.2.1.RELEASE-1.noarch.rpm

シングルノードで起動

ターミナルを 1 つ開いて SpringXD を起動します

  • /opt/pivotal/spring-xd/xd/bin/xd-singlenode

起動には少し時間がかかります
SpringXD のロゴが表示されて INFO ログが流れ始めて、止まれば起動完了です

試してみる

専用の CLI クライアントがあるのでそれを使って試してみます

  • /opt/pivotal/spring-xd/shell/bin/xd-shell

で専用のシェルが起動します

ストリームの作成

まずストリームなるものを作成します
SpringXD ではストリーム単位で起動や停止を実施します

  • stream create ticktock –definition “time | log”

「ticktock」という名前のストリームを作成します
--definition オプションを指定してストリームが実施する処理を記載します
今回は time | log という処理を実施させます
time は時刻を入力するためのコマンドです
それを | パイプでつないで log で入力を受け取ります
log は受け取った情報を一定間隔でロギングしてくれるコマンドです
なので time | log とすることで一定間隔で現在時刻を表示させることができます

ストリームを起動する

作成したストリームを起動しましょう

  • stream deploy ticktock

起動は deploy コマンドで実行できます
起動すると別のターミナルで起動していた SpringXD に現在時刻が出力され流れ始めます

ストリームを停止する

  • stream undeploy ticktock

undeploy で停止できます
時刻の出力も停止します

ストリームを削除する

  • stream destroy ticktock

destroy で作成したストリームを削除することができます
削除したあとは deploy はできなくなります
また stream list でストリームの一覧を確認できますが、この一覧からもなくなります

最後に

チュートリアルを試しただけ正直何ができるのかよくわからなかったです
Twitterのタイムラインをリアルタイムで処理させるサンプルとかがあるのでこういうのを試してみるといいのかもしれません

今回はシングルノードで動作させたが、本来は Distributed モードがありそれで動作させるみたいです
ただ、他に必要になるミドルウェアが結構あり、構築だけでも結構大変そうでした
機会があれば時間とって触ってみたい

embulk-input-s3 を試してみた

概要

前回 embulk のクイックスタートを試してみました
今回はちょっと実践編ということで AWS の S3 と連携させてみました

環境

  • CentOS 6.6 64bit
  • embulk 0.7.4
  • Java OpenJDK 1.8.0_45
  • embulk-input-s3 0.2.2

インストール

基本的なインストールは前回の記事を参考にインストールしてください

embulk-input-s3 のインストール

プラグインをインストールします

  • embulk gem install embulk-input-s3

設定ファイルの編集

S3 と連携する専用の設定ファイルを作成します
とりあえず設定ファイルの全貌は以下の通りです

  • vim config_s3.yml
in:
  type: s3
  bucket: my-service-bucket
  path_prefix: logs/csv-
  endpoint: s3-ap-northeast-1.amazonaws.com
  access_key_id: xxxxxxxxxx
  secret_access_key: yyyyyyyyyy
  parser:
    charset: UTF-8
    newline: CRLF
    type: csv
    delimiter: ','
    quote: '"'
    trim_if_not_quoted: false
    skip_header_lines: 0
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: id, type: long}
    - {name: name, type: string}
    - {name: lang, type: string}
    - {name: level, type: long}
out:
  type: command
  command: "cat -> task.$INDEX.$SEQID.csv.gz"
  encoders:
  - {type: gzip}
  formatter:
    type: csv

処理の流れとしては S3 にアップロードした CSV ファイルを読み込んでサーバ上に圧縮した CSV として保存します

各種パラメータについて

簡単に説明します

in: でインストールしたプラグインを使用します
type: s3 と指定することで S3 にあるデータを参照することができます
指定が必要なパラメータは以下の通りです

  • bucket・・・参照先のバケットを指定します
  • path_prefix・・・バケット配下に存在する解析対象のファイルのプレフィックスを指定します
  • endpoint・・・バケットが存在するエンドポイント (リージョン) を指定します
  • access_key_id・・・S3 にアクセスするためのアクセスキーを記載します
  • secret_access_key・・・S3 にアクセスするためのシークレットキーを記載します

各自の環境に合わせて適当な値を入力すればOKです

parser: も設定が必須になっています
ここの設定は 前回 の CSV ファイルの解析を元にしています
若干違うのは skip_header_lines , columns の部分です
あと、今回は圧縮していない平文の CSV ファイルを対象にするので decoders: の定義も削除しています

今回解析する CSV ファイルのサンプルは以下の通りです

  • csv-user-skills

1,kaka,java,10
2,kiki,ruby,5
3,keke,lisp,6

ファイル名は設定ファイルに記載したプレフィックスで始まるようにしてください
実際に試す際はどんな内容の CSV でも OK ですが、設定ファイルの columns: の数とカラム数は合わせる必要があるので注意してください

CSV ファイルを指定したバケット配下に配置する

配置は UI からでも API からでも何でもOKです
設定ファイルに記載したバケット配下のパスプレフィックスにアップロードしてください

実行する

ここまでくればあとは実行するだけです

  • embulk preview config_s3.yml

で S3 に配置した CSV の情報が出力されることを確認します

  • embulk preview config_s3.yml

out: に記載されている命令が実行され embulk-output-command を使って圧縮済みの CSV ファイルが実行したサーバ上に作成されていることが確認できると思います

S3 に 1 つだけ CSV をアップロードした場合は「task.0.0.csv.gz」という名前の CSV ファイルが 1 つだけ作成されます
S3 上に複数の CSV ファイルをアップロードした場合はアップロードした CSV の数だけ「task.1.0.csv.gz」みたいな感じで、前の数字がインクリメントされたファイルが作成されます

最後に

今回は小さい 1 つの CSV ファイルを対象にしましたが、これが大量の CSV でかつサイズが大きい場合などは、どれくらいの負荷になるのかが気になりました

ファイルの命名規則だけ気をつけて、あとはバケットにアップロードして実行すれば一気に解析してくれるのが便利なポイントだと思いました

定期的に実行する場合とかを考えると、一度解析したファイルは別のバケットに移動したり削除したりしなければいけないのかな?そうなるとちょっと処理を挟まないとダメですね
その辺りもプラグインがあるのだろうか

2015年9月24日木曜日

embulk 試してみた

概要

embulk の QuickStart を試してみました
何事も試して感覚をつかむ

環境

  • CentOS 6.6 64bit
  • embulk 0.7.4
  • Java OpenJDK 1.8.0_45

インストール

以下 root で作業しています
Javaが必要なのでインストールしていない場合は事前にインストールしてください

  • curl –create-dirs -o ~/.embulk/bin/embulk -L “http://dl.embulk.org/embulk-latest.jar
  • chmod +x ~/.embulk/bin/embulk
  • echo 'export PATH="$HOME/.embulk/bin:$PATH"' >> ~/.bashrc
  • source ~/.bashrc

特に考える必要はないと思います
ダウンロードして権限を変えて PATH に通してあげているだけです

Quick Start

インストールしたらサンプルデータで試します

  • mkdir ~/work
  • cd ~/work
  • embulk example ./try1
  • embulk guess ./try1/example.yml -o config.yml
  • embulk preview config.yml
  • embulk run config.yml

exampleでサンプルデータを作成して
guessで設定ファイルを自動生成して
previewで読み込んだデータがちゃんとパースされるかテストして
runで実際に実行させます

だいぶ省略したサブコマンドの説明なので詳細は公式等みてください
とりあえずこれを実行するとexampleで生成された CSV データを読み込んで標準出力にその内容を出力してくれます

2015-09-24 14:00:29.248 +0900: Embulk v0.7.4
2015-09-24 14:00:31.432 +0900 [INFO] (transaction): Listing local files at directory ‘/root/work/embulk/try1/csv’ filtering filename by prefix ‘sample_’
2015-09-24 14:00:31.438 +0900 [INFO] (transaction): Loading files [/root/work/embulk/try1/csv/sample_01.csv.gz]
2015-09-24 14:00:31.524 +0900 [INFO] (transaction): {done: 0 / 1, running: 0}
1,32864,2015-01-27 19:23:49,20150127,embulk
2,14824,2015-01-27 19:01:23,20150127,embulk jruby
3,27559,2015-01-28 02:20:02,20150128,Embulk “csv” parser plugin
4,11270,2015-01-29 11:54:36,20150129,NULL
2015-09-24 14:00:31.815 +0900 [INFO] (transaction): {done: 1 / 1, running: 0}
2015-09-24 14:00:31.822 +0900 [INFO] (main): Committed.
2015-09-24 14:00:31.823 +0900 [INFO] (main): Next config diff: {“in”:{“last_path”:”/root/work/embulk/try1/csv/sample_01.csv.gz”},”out”:{}}

プラグインを試す

プラグインの使い方まで試します
今回使用するプラグインは embulk-output-command です

  • embulk gem install embulk-output-command
  • vim config_try_plugin.yml
in:
  type: file
  path_prefix: /root/work/embulk/try1/csv/sample_
  decoders:
  - {type: gzip}
  parser:
    charset: UTF-8
    newline: CRLF
    type: csv
    delimiter: ','
    quote: '"'
    trim_if_not_quoted: false
    skip_header_lines: 1
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: id, type: long}
    - {name: account, type: long}
    - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: purchase, type: timestamp, format: '%Y%m%d'}
    - {name: comment, type: string}
out:
  type: command
  command: "cat -> task.$INDEX.$SEQID.csv.gz"
  encoders:
  - {type: gzip}
  formatter:
    type: csv

config_try_plugin.ymlはデフォルトで生成されるconfig.ymlを元にするといいです
変わっているのはout:の部分でここでインストールしたプラグインを使っています

これをインストールするとtype: commandが使えるようになりcommand:に指定したコマンドを実行することができます
サンプルの場合in:で読み込んだ CSV ファイルを名前のフォーマットを変更して再度 CSV に出力しています

$INDEX$SEQID について

command:内で変数を使っています

簡単に説明すると $INDEX は読み込んだファイルの数だけインクリメントしてくれる変数です
例えばサンプルで使用した try1/csv/sample_01.csv.gz ともう一つ try1/csv/sample_02.csv.gz というファイルを作成すると $INDEX をインクリメントしてくれます

$SEQID は formatter の数に依存します
formatter が複数あった場合、0 から順番にインクリメントしてくれます

最後に

公式の Quick Start をやっただけなので特に躓くこともなく簡単に使うことができました

実行してみるとわかりますが、embulk は並列実行なので、複数のファイルを in: で読み込んだ場合は 1 つ目のファイルが終わってから 2 つ目のファイルを実行するわけではなく、一気に 2 つのファイルの処理がはじまります

本当に試しただけなので、まだ現場レベルでの有効な使い道は思い浮かびませんが機会があれば使いたいかなと

2015年9月16日水曜日

Zabbix のカスタムスクリプトで Redis を自動で再起動させてみた

概要

Redis を監視してダウンしたら自動で起動するようにしてみました
カスタムスクリプトの使い方のおさらいもしたのでメモしておきます

環境

  • CentOS 6.6 64bit
  • Zabbix 2.4.5
  • Redis 3.0.2-1

各種インストール方法

アイテムおよびトリガーの作成

Redisを監視するアイテムとトリガーを作成します
テンプレートはお好きなテンプレートを作成してください

  • アイテム
    redis_item.png

  • トリガー
    redis_trigger.png

アクションの作成

上記作成したトリガーを元に実行されるアクションを設定します

  • 条件
    redis_action_condition.png

  • 実行内容
    redis_action_plan.png

ポイントは実行内容を「リモートコマンド」にして「現在のホスト」でコマンドを実行される部分でしょうか
このままだと権限の関係でコマンドを実行できない可能性があるので設定ファイルを修正します

zabbix_agentd.conf の修正

以下のパラメータが有効になっているか確認してください

  • EnableRemoteCommands=1
  • AllowRoot=1

今回 service コマンドで redis を再起動しますが、zabbix ユーザだと権限がなく service コマンドを実行できません
また、EnableRemoteCommands を有効にしないとカスタムスクリプト自体使えません
AllowRoot の設定はセキュリティ的に嫌だという場合は sudo 等で権限を与えるようにしてください
修正後は zabbix-agent を再起動してください

ここまで設定できれば完了です
実際に redis を停止すれば設定したリモートコマンドが実行されると思います

トラブルシュート

カスタムスクリプトに指定したコマンドがうまく実行されない場合は Zabbix サーバのログを見てみましょう
デフォルトだとログレベルが warnings (3) になっているため debugging (4) にしてください

  • vim /etc/zabbix/zabbix_server.conf
    • DebugLevel=4

これでリモートコマンドが実行されたときに/var/log/zabbix/zabbix_server.logにログが出るようになります
ただ、ログの量が非常に多いのでtail -f /var/log/zabbix/zabbix_server.log | grep start等で必要なログだけ見るようにしてください
Zabbix サーバのログにエラーが出ていなくてもリモートコマンドが実行されていない場合はコマンドを実行しているホスト側で何かしらが原因で実行されていないのでホスト側を確認しましょう
いろいろと原因は考えられますが、コマンドが間違っていたり、一番多そうなのはやはり権限回りかと思います

最後に

Zabbix はトラブルシュート系が結構面倒だといつも感じます
もう少しログを見やすくしてほしい気もします
一番はUI上で「失敗」や「エラー」となっている状態で、その原因を詳細に確認できるとログもデバッグモードにして見る必要がないので楽かなと思います

2015年9月15日火曜日

ニフティクラウド Timer の HTTP 機能を使ってみた

概要

ニフティクラウド Timer を使ってニフティクラウドmobile backend (以下、NCMB) に定期的にプッシュ通知を送信してみました

環境

  • ニフティクラウド Timer 20150915 時点
  • NCMB 20150915 時点
  • Ruby 2.2.0p0
  • Bundler 1.8.3

事前準備

今回は iOS に対してプッシュ通知を実施します
NCMB を使ってプッシュ通知を実施できる環境が必要なので、まだの方はこちらから設定してください
iOS は厳しいというかたは Android でもOKです
Android であれば公式を元にさらっとできると思います
iOS, Android どちらにせよ実機は必要です

また、ニフティクラウド Timer および NCMB を利用できるアカウントが必要になります
ぶっちゃけ事前準備が一番たいへんだと思います
また、ニフティクラウド Timer は有料のサービスとなります

curl 用のリクエストを作成する

このスクリプトを使って curl 用のリクエストを生成しましょう
ここで生成したリクエストをタイマーにコールされることで NCMB にプッシュ通知を登録します

  • cd work
  • git clone https://gist.github.com/ef34c3a0180961262607.git
  • cd ef34c3a0180961262607
  • vim post_push.rb
    • APPLICATION_KEY と CLIENT_KEY の部分を書き換えます
    • params の message を好きな文字に変えてください、これがプッシュ通知に表示されます
  • bundle install && bundle exec ruby post_push.rb

上記を実行すると標準出力に curl 用のコマンドが出力されます
このコマンドのヘッダ部分とボディ部分、そしてアクセスしている URL をメモしておきましょう

curl -X “POST” -H “Content-Type: application/json” -H “X-NCMB-Application-Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx” -H “X-NCMB-Timestamp: 2015-09-14T08%3A08%3A34.456Z” -H “X-NCMB-Signature: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy” -d ‘{“immediateDeliveryFlag”:true,”target”:[“ios”],”message”:”GoodMorning!”}’ https://mb.api.cloud.nifty.com/2013-09-01/push

タイマー作成

ニフティクラウド Timer のコンパネで作成します

まずタイマーを起動させる時間を設定します
時間の設定は cron っぽく設定できるので cron に慣れている方は cron をイメージするといいと思います
今回は毎日朝7:30にモーニングプッシュをするようにしてみましょう
名前は好きな名前を入力してください、ただよくわからないのですが後から変更できないので注意して入力してください
create_timer.png

次に実行するコマンドの設定です
ニフティクラウド Timer では HTTP をコールすることができます
タイプに「HTTP」を選択します
すると「メソッド」「ヘッダー」「ボディ」を設定する欄が表示されるので、それぞれ入力します
入力する内容は Ruby で作成した curl のリクエスト情報をそのまま入力します
config_request.png

タイマーが実行された際にメール通知を飛ばすこともできます
失敗したときと成功したときで出し分けすることができるようです
また、メールアドレスはカンマ区切りで複数指定することも可能です
必要であれば設定しましょう
config_mail.png

問題なければ確認画面に遷移してタイマーを作成しましょう
確認画面では料金も表示されるので金額を確認して「作成する」を押してください

これでタイマーの作成は完了です

試しに実行してみる

ニフティクラウド Timer では作成したタイマーを手動で実行することができるので、試しに実行してみます

作成したタイマーを選択してプルダウンから「リクエスト実行」を選択します
確認のダイアログが出るのでチェックをONにして実行してみましょう

実行結果を確認する

実行すると特に何も起きていないかのようにタイマーの一覧に戻ります
問題なく実行できているか確認してみましょう
タイマーの右に詳細を確認するボタンがあるのでクリックします
すると「実行履歴」というタブが表示されるので確認します
ここに success と出ていれば問題なく NCMB にリクエストすることができています
confirm_result.png

今回の場合 success になっていれば問題なく NCMB にプッシュが登録されていることになるので、端末にプッシュが届いていると思います
もし届いていない場合は NCMB 側のプッシュの設定に問題がある可能性があるので、プッシュの設定やアプリの設定を見なおしてみてください

トラブルシュート

実行履歴で failure になった場合のトラブルシュートを紹介します
まずこの情報からだと何が原因でエラーになったのかさっぱりわかりません
実はレスポンスの詳細を確認する方法があります(非公式だと思いますが)
Firefox や Chrome を使っている方であれば、ブラウザのデバックツール (Firebug or デベロッパーツール) を使ってみましょう
これのネットワークを確認すると describe-history-instances という URI でレスポンスを確認することができ、ここで StatusCode を確認することができました
ただ、レスポンスボディまで確認することはできなかったので、ステータスコードだけで原因を切り分ける必要があります

今回のように HTTP のタイマーを設定した場合は、まずタイマーを経由しないで直接 HTTP をコールしてみましょう
問題なく通ることが確認できたらタイマーに設定して試してみるといいと思います

最後に

使ってみて感じたのはやはり実行結果が詳細に見れないのが辛かったです
エラーの詳細がわからない状態だと、Try & Error を何度も繰り返して正解にたどり着く必要があり、かなり yac shaving というか無駄なことをしている感じがしました

サービス的には IFTTT と同系列だと思います
ニフティクラウド Timer を使うメリットとしては、タイマーのタイプにニフティクラウドを操作できるタイプが標準で備わっていたので、その辺りのシナジーがあるといったところでしょうか
IFTTT でニフティクラウドのAPIをコールすれば同じことができるとは思いますが

2015年9月14日月曜日

既存の Eclipse プロジェクトを AndroidStudio にコンバートする方法

概要

既存の Eclipse プロジェクトを AndroidStudio で動かせるようにしてみました

環境

  • OS X 10.10.5
  • AndroidStudio 1.3.2
  • Eclipse Luna 4.4.2

AndroidStudio で Eclipse プロジェクトをインポート

  1. AndroidStudio を起動
  2. File -> New -> Import Project
  3. Eclipse のプロジェクトを選択

でインポートが始まります
インポートが成功するとそのままAndroidStudioで使うことができます

git を使ったプロジェクトの場合

.git.gitignore はインポートした後のプロジェクトには含まれていませんでした
一番簡単なのはインポート前のプロジェクトから.gitディレクトリと.gitignoreファイルをそのままコピーすればOKです

あと README.md もなぜか勝手に削除してしまうので、これもインポート前のプロジェクトから持ってきました

トラブルシュート

自分が遭遇したのはインポートするプロジェクトがサポートしている API バージョンが低いというエラーが発生しました
対処としてはインポートしたいプロジェクトの

  • AndroidManifest.xml の android:minSdkVersion と android:targetSdkVersion を適切な値に書き換え
  • project.propertie の target を適切な値に書き換え

を実施しました
インポートした際に AndroidStudio で使っている Android-SDK に対象のバージョンがないとインストールして解決することもできますが、ダウンロードが面倒だったので書き換えてからインポートしました

インポートした際の全差分は以下の通りです
https://github.com/kakakikikeke/android-ncmb-sample/commit/d4db6fb17a55c26c0b6ed845d90975749e798182
ディレクトリの構造自体が大きく変わってしまうのでほぼ差分です
また .gitignore の設定がおかしかったので修正しています
gradlew と settings.gradle を git で管理するように修正しました

2015年9月11日金曜日

今更ながら ssh-agent の使い方について

概要

タイトルの通り
ssh-agentの使い方を紹介します
ssh-agentは簡単に言うとパスワードをキャッシュする感じの機能
ssh-agentにパスワードを登録しておくと ssh の度にパスワードを入力しなくてよくなります

環境

  • CentOS 6.6 64bit
  • ssh-agent OpenSSH 5.3p1

使い方

まずは起動します

ssh-agent bash

引数には起動するシェルを指定します
存在しないシェルを指定すると「hoge: No shuch file or directory」みたいなエラーが出ます

起動したらパスワード情報を登録します

ssh-agent /path/to/secretkey

secretkeyという秘密鍵を使って ssh することを想定しています
この秘密鍵のパスワードを入力します
パスワードの入力に成功すると「Identity added: …」と表示されます

この状態になったらこれまで secretkey を使って ssh していたサーバに接続してみましょう

ssh host001

これでパスワードを入力しないでログインできることが確認できると思います
これまでは「ssh -i /path/to/secretkey host001」としてパスワードを入力してログインしていたのが、それをしないでよくなりました

最後に

ssh-agentは起動後に exit とかで抜けてしまうと停止してしまいます
なので再ログインしたときにはss-agentの起動から実施する必要があります
よくあるケースだと .bashprofile に書いておくとかでしょうか

あと Mac だとキーチェーンを使えばこれを勝手にやってくれます
ターミナルとかで ssh すると「キーチェーンアクセスを使いますか」的なダイアログが出て、OKにすると今後パスワードの入力なしでログインできるようになるあれです

2015年9月10日木曜日

AndroidStudio でプロパティファイルを扱う方法

概要

AndroidStudio での開発でプロパティファイルを使って、そこから値を取得する方法を紹介します

環境

  • OS X 10.10.5
  • AndroidStudio 1.3.2

プロパティファイルの配置

app/src/main/resources/config.properties に配置します

resources ディレクトリはデフォルトだと存在しないので作成してください

プロパティファイルを読み込むソースコード

まず配置したプロパティファイルを読み込むクラスを作成します
app/src/main/java/com/sample/utils/ConfigPropUtil.java を作成します
パッケージ名やクラス名は好きな名前で作成してOKです

package sample.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class ConfigPropUtil {

    private static final String CONFIG_FILE = "config.properties";
    private Properties prop;

    public ConfigPropUtil() {
        prop = new Properties();
        InputStream is;
        try {
            is = this.getClass().getClassLoader().getResourceAsStream(CONFIG_FILE);
            prop.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Object get(String key) {
        return prop.get(key);
    }
}

java.util.Properties を使ってプロパティファイルを読み込みます
プロパティファイル名 (CONFIG_FILE) は配置した名前にすればなんでもOKです
フルパスでは設定せずファイル名だけで指定します

他のクラスから使用する方法

例えば Activity 継承したクラスで onCreate 内では以下のように利用します

private ConfigPropUtil config;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.start_activity);
    config = new ConfigPropUtil();
    String key = (String) config.get("key.name");
}

こんな感じで使えます

最後に

トラブルシュートでとしてはFileNotFoundException or NullPointerExceptionが発生すると思います
原因のほとんどはファイルが見つからない場合です

AndroidStudio でビルドする場合は gradle を利用します
gradle で apk ファイルを作成してから実機なりシミュレータに転送して実行します
なので apk ファイルに config.properties が含まれる必要があるため app/src/main/resources/config.properties にプロパティを配置しました
gradle は app/src/main/resources/ にあるファイルを自動的にビルドに含めてくれるのです

2015年9月7日月曜日

Mac でフォントを追加する方法

概要

Font Bookというアプリを使って Mac にフォントを追加する方法を紹介します

環境

  • OS X 10.10.5
  • Font Book 5.0.2

インストール方法

今回はPixelMplusというフォントをインストールしてみます

Font Bookを開く

Misson Control -> その他 -> Font Book

があるのでこれを開きます

boot_font_book.png

フォントをダウンロードする

追加したいフォントをダウンロードします
解凍して「.ttf」ファイルがあることを確認してください

unzip.png

Font Book でフォントを追加する

以下の手順で追加できます

  • ファイル -> フォントを追加
  • 解凍した .ttf ファイルを選択する -> 開く

で追加完了です
一覧に追加したフォントが表示されることを確認しましょう

list_font.png

動作確認

Mac であれば一番手っ取り早いのは「テキストエディト」だと思います

フォーマット -> フォント -> フォントパネルを表示 -> すべてのフォント

でインストールしたフォントが反映されるか確認しましょう

confirm_font.png

2015年9月4日金曜日

Munin で JMX を監視する方法

概要

Munin で JMX を監視してみました

環境

  • CentOS 6.6 64bit
  • Munin 2.0.25
  • Tomcat 7.0.33

各種インストール

TomcatのJMXを有効にする

  • vim /etc/tomcat/tomcat.conf

CATALINA_OPTS=”-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1616 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false”

を最後の行に追記しましょう

  • service tomcat restart

MuninのJMXプラグインをインストールする

  • git clone https://github.com/munin-monitoring/contrib.git
  • cp contrib/plugins/java/jmx/plugin/jmx
  • cp contrib/plugins/java/jmx/plugin/jmx* /usr/share/munin/plugins/
  • chmod a+x /usr/share/munin/plugins/jmx_
  • cp contrib/plugins/java/jmx/examples/java/java_* /usr/share/munin/plugins/
  • ln -s /usr/share/munin/plugins/jmx_ /etc/munin/plugins/jmx_process_memory
  • cd /usr/share/munin/plugins
  • ln -s java_process_memory.conf process_memory
  • vim /etc/munin/plugin-conf.d/munin-node

[jmx_*]
env.jmxurl service:jmx:rmi:///jndi/rmi://localhost:1616/jmxrmi

最後に追記しましょう

動作確認

  • cd /etc/munin/plugins
  • ./jmx_process_memory config
  • ./jmx_process_memory
  • service munin-node restart

で、しばらくすると「Java」という項目がグラフに表れると思います
jmx_process_memory-day.png

最後に

プラグインを入れるだけでグラフまで簡単に表示することができました
今回は Tomcat の JMX を監視しました
ポートは 1616 で監視しましたが、好きなポートでOKです
また、同一ホストで監視したため別ホストから監視したい場合は設定ファイルの書き方を変更してください

2015年9月2日水曜日

開発合宿やった

概要

やってみたい記事を書いて一ヶ月後に実現したのでどんな感じでやったかメモしておきます

メンバー

4人 (男:女=3:1)

合宿先

沖縄
宿泊先 : にらい恩納

日程

2015/08/29 - 2015/08/31 の 2泊3日

料金

  • 飛行機代 : 37,180円
  • 宿泊代 : 15,500円
  • レンタカー:2,355円
  • 食費:約10,000円

-> 合計:65,035円/1人

合宿の記録 (時系列)

  • 初日
    • 7時起床
    • 7:30 - 9:30 成田空港移動
    • 9:30 - 10:30 出発準備 (出発が11時に遅れる)
    • 11:00 - 14:30 飛行機内 (30分くらい開発)
    • 14:30 - 15:00 レンタカー手配
    • 15:00 - 15:30 食事へ
    • 15:30 - 16:20 食事完了
    • 16:20 - 18:00 宿泊地へ移動
    • 18:00 - 18:30 買い出し
    • 18:30 宿舎到着
    • 18:30 - 20:00 開発
    • 20:00 - 21:00 夕食 (食べながら開発)
    • 21:00 - 23:00 開発
    • 23:00 - 24:00 就寝準備
    • 24:00 就寝
  • 二日目
    • 10:00 起床 (他の人は 8:00 とかに起きて開発していた)
    • 10:00 - 13:00 開発
    • 13:00 - 15:30 食事+買い出し
    • 15:30 - 16:30 海
    • 16:30 - 17:30 開発
    • 17:30 - 20:00 BBQ
    • 20:00 - 23:00 開発+プレゼン作成
    • 23:00 - 24:00 全員でプレゼン
    • 24:00 就寝
  • 三日目
    • 10:00 起床 (他の人は 8:00 とかに起きて開発していた)
    • 10:00 - 11:00 チェックアウト準備
    • 11:00 チェックアウト
    • 11:00 - 16:00 フリー行動
    • 16:00 - 18:00 那覇空港へ
    • 18:00 - 18:30 出発準備
    • 18:30 - 21:40 飛行機
    • 21:40 - 22:30 空港から電車に乗り換え
    • 22:30 - 24:00 電車で帰宅
    • 24:00 帰宅

まとめ

開発時間:10時間30分+α
(+αは移動の時間や食事の時間もちょろちょろやっていた分)

所感

  • Bad
    • とにかく移動が多すぎた
    • 移動中開発したが、集中できない
    • コテージが内陸にあり、WiMAXが届かなかった (キャリアの回線は届いた)
    • コテージに電源プラグが少なく、電源タップがなかったらやばかった
  • Good
    • とくかく楽しめた
    • 一応全員アウトプットすることができた
    • 宿泊したコテージの雰囲気は開発合宿にピッタリ
    • 普段とは違う開発環境を味わうことができた

感想

ガチで開発するなら会議室のある近場の民宿がやっぱりいいなと感じた
いいわけだが、今回は旅行も兼ねていたので開発が少なくなってしまったのは仕方ない感じか
(会社にコミットメントも約束していなかったので、、、)

費用が少し高くついてしまった
ツアーではなく、それぞれ別で申し込んだのでそうなってしまった

とりあえず楽しかったのでOK
たまには南国で開発するのもいいなと思った