oranie's blog

旧:iをgに変えると・・・なんだっけ・・・

【追記あり】td-agent2 + fluent-plugin-bigqueryで、起動時にエラーになる問題

【追記】

https://twitter.com/tagomoris/status/546981761385639937
との事で直りました。このエントリの寿命1時間くらいでした!

                                                                                                                                  • -

もうISSUE上がっているけど、同様のエラーが出た。
https://github.com/kaizenplatform/fluent-plugin-bigquery/pull/31
要するにgoogle-api-clientが古い。ただ、

/opt/td-agent/usr/sbin/td-agent-gem update google-api-client

でやってもfluent-plugin-bigqueryが使うのが
https://github.com/kaizenplatform/fluent-plugin-bigquery/blob/master/fluent-plugin-bigquery.gemspec
にも書かれているが、

 spec.add_runtime_dependency "google-api-client", "~> 0.7.1"

なので、以下は自己責任でお願いします。とりあえず

git clone https://github.com/kaizenplatform/fluent-plugin-bigquery.git

で現行のソース拾ってきて、

fluent-plugin-bigquery.gemspec
の
 spec.add_runtime_dependency "google-api-client", "~> 0.7.1"
を
https://github.com/hakobera/fluent-plugin-bigquery/commit/57253b092d3d023755f167741c2c7eb0aed515ea
で修正されている
 spec.add_runtime_dependency "google-api-client", "~> 0.8.0"

に書き換えて

rake build
して出来上がったやつを
/opt/td-agent/usr/sbin/td-agent-gem install -l ./pkg/fluent-plugin-bigquery-0.2.5.gem
で入れた

以上です。

CentOS 6.5でgo get gopkg.in/hogehogeした時に固まる事象

結論:gitのVerが古いから。多分1.7.1系とかが入っているとダメで、2.0系とかにアップデートすると解決した。

ソース
https://github.com/spf13/hugo/issues/297

解決方法
http://www.torutk.com/projects/swe/wiki/CentOS_6%E3%81%A7git%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%82%92%E4%B8%8A%E3%81%92%E3%82%8B

とりあえずこれでgo get gopkg.in/hogehogeが問題無く出来る様になりました。

Go + mgo (MongoDB)でauto increment的な事をやる。

自分メモなので簡単に。

  1. MongoDB側にcounter用コレクション作る
  2. Go側でcounter用のstructを定義しておく。
  3. Apply()を利用してcounterをインクリメントし、その値を使ってドキュメントをINSERTする。

という流れになる。
mgoのドライバ公式にApplyの代表的な使い方として書かれているが初め良く分からずハマったのでメモ。
http://godoc.org/labix.org/v2/mgo#Query.Apply

MongoDB側にcounter用コレクション作る

とりあえずここを読みましょう。
http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/
コンソールからauto incrementする方法がオフィシャルドキュメントに書いてあります。

Go側でcounter用のstructを定義しておく。

こんな感じ。

	type  Counter struct {
		Object_Id  bson.ObjectId`json:"_id" bson:"_id,omitempty"`
		Id string `json:"id"`
		Seq int64`json:"seq"`
	}

これはなんで定義するかというと、インクリメント処理が終わった際にそのドキュメントを受け取るインターフェイスが必要で、そこに格納された値を用いてINSERTする時にインクリメントされた値をセットする。なので、MySQLのテーブルスキーマに設定するauto incrementとかと一緒かというと、別に採番テーブルを作成してその値を使った用いた処理と一緒になる。
DeNAさんが前に技術ブログで書いた
http://engineer.dena.jp/2010/11/mysql-for-socialgame.html
ログIDの払い出しの時と同じイメージですね。

Apply()を利用してcounterをインクリメントし、その値を使ってドキュメントをINSERTする。

	change := mgo.Change{
		Update: bson.M{"$inc": bson.M{"seq": 1}},
		ReturnNew: true,
	}

こんな感じでまずincrementする処理を書き、

	var result Counter //change処理結果のドキュメントを受け取る変数
	info,err := t.Find(bson.M{"id":"seqNo"}).Apply(change,&result) //change処理が成功したら、&resultに更新したドキュメントが格納される。
	fmt.Println(result.Seq) //resultのseqメンバの値を標準出力してみる

という形でインクリメントした値を標準出力出来るので、これを用いてINSERT処理に使えば良い。

で、さっきも書いたけど、採番テーブルを使うパターン + transactionが無いからincrementは成功したけど、その後INSERTする時にアプリがダウンとかすると、counterは進んだけどその値を持ったドキュメントはいないとかになるので、そのレベルになる事を注意。

あと、公式に書いてあるようなMongoDB側にincrementする関数を設定して、それをクエリ時に使おうと

db.users.insert(
   {
     _id: getNextSequence("userid"),
     name: "Sarah C."
   }
)

こんな感じのクエリを投げようとしても、getNextSequence()を実行したいがそれがただの文字列に扱われてしまったので、こんな感じになった。もしmgoを使ってこれを叩く方法があれば教えて下さい><

開発中にAndroidアプリでSQLiteに格納したデータをデータファイルコピーせずに確認する方法

【追記】
このブログ書いた後に改めてググったら普通にこの方法見つかるね。俺が見逃していただけですな・・・。

                                                                                                                                    • -

表題のままで、開発中にAndroid アプリで定義したSQLiteスキーマをちゃんと確認したいとか、中にどんなデータが入ったかを確認したかったが、ググっても出てくるのが「SQLite3のファイルをローカルにコピーしてきて、それを見る」ばっかりだったので、面倒くせーと思ったらファイルコピーしなくても出来た。
環境はMac + Android Studio + Genymotion上のNexus端末なので、実機ではRoot権限を取らないと多分この方法はムリ。試しにやったらroot権限無くて対象のディレクトリに入れないので出来なかった。

方法としては

  • adb shellで端末に入る
  • cd /data/data/{アプリ名}/databases/してディレクトリを移動。
  • 中にあるSQLiteデータファイルを指定してSQLite3コマンドラインインターフェイスを起動。
  • 後は普通にクエリを実行して確認する
例えばexample-appという名前のアプリでexample-dbというテーブルを作成していた場合はexample-dbというデータファイルがあると思うので
# adb shell (PATH通っていないとかは知らん)
# cd /data/data/example-app/databases/
# sqlite3 ./exampl-db

SQLite version 3.7.11 2012-03-20 11:35:50
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
で中に入れるので、
sqlite> .databases  
でdatabaseの一覧を見たり
sqlite> .schema example-db
でスキーマを確認したり
sqlite> select * from example-db;
で普通にSELECT文を実行出来る。

という流れになる。Android StudioのTerminalからadb shellを実行すれば良いので確認が楽になった。別に普通のTerminalからでも出来る。

ただ、以前までは普通にadb shellで端末に入れたのに実機のNexus7に一度繋げてから、Genymotionの端末に入ろうとadbコマンド実行すると

$ adb shell
adb server is out of date.  killing...
cannot bind 'tcp:5037'
ADB server didn't ACK
* failed to start daemon *
error: 

とかで入れなくて、これがAndroidの洗礼か・・・誰か助けて・・・。もちろんこの直前にはAndroidStudioからアプリを端末にインストール出来ている。

なので、こういう時はGenymotionを使って端末起動した場合、ps auxwwとかで確認するとそもそもshellで接続しているので

こんな感じ
 /Applications/Genymotion.app/Contents/MacOS/player.app/Contents/MacOS/tools/adb -s 192.168.56.101:5555 shell

このコマンドをコピペすると中に入れる。

fluentd + BigQuery pluginを利用する時に認証処理で「invalid_grant」エラーになる時の対処

結論から言うと、システム時間を確認しましょう。

環境はDocker上のfluentdで

2014-10-02 06:31:47 +0900 [error]: unexpected error error_class=Signet::AuthorizationError error=#<Signet::AuthorizationError: Authorization failed.  Server message:
{
  "error" : "invalid_grant"
}>

というエラーが出て起動出来なかった。でも認証情報は合っているし、GoogleDeveloperConsleで見てもAPIの許可とかはしている。で調べて見ると
https://github.com/abronte/BigQuery
にも記載があるが

Troubleshooting

If you're getting an "invalid_grant" error it usually means your system clock is off.

If you're getting unauthorized requested but you've been able to successfully connect before, you need to refresh your auth by running the "refresh_auth" method.

なので、Doker上の時間を確認するとズレまくっていた。とりあえず

ntpdate -q ntp.nict.jp

を実行して時間を合わせたらフツーに起動出来た。

という訳でDokerを使う場合は時間の確認もちゃんとしましょう。
http://stackoverflow.com/questions/24551592/how-to-make-sure-dockers-time-syncs-with-that-of-the-host
に書いてるように

docker run -v /etc/localtime:/etc/localtime:ro -i -t mattdm/fedora /bin/bash

とかでrunさせるのがベストプラクティスなんですかね。

AndroidでGoogle Maps API v2を叩く時に地図が表示されない時に確認する設定

ハマったのでメモ。環境はAndroid Studio使った。改めてググって見ると
http://9ensan.com/blog/smartphone/android/google-maps-android-api-v2-sample/
の解説が一番丁寧でこの通りになっていれば出来る。

Activityは表示れているっぽいけど、画面が真っ白になっているときは
http://stackoverflow.com/questions/17491400/failed-to-load-map-error-contacting-google-servers-issue-with-android-google-ma
とかで書かれているけど、Logcatに

Could not find class 'com.google.android.gms.location.internal.ParcelableGeofence', referenced from method glt.a

とかのログが出ているので、その場合にでAndroidManifest.xml

使いまわす場合は
Android applications
    Any application allowed
とかになっているか

などの確認をして問題が無いか確認しましょう。このエラーログでググるとstack overflowでヒットしまくるので、みんなもドハマりしている様ですね。

あと若干別件だが、build.gradeに

    compile 'com.google.android.gms:play-services:+'

って書くと端末側がGooglePlayサービスのアップデートをしようとするけど何故かアップデート出来なくて永久にアプリちゃんと起動出来ない問題があったので、

    compile 'com.google.android.gms:play-services:5.0.89'

って明示的にVer書いたら問題が出なくなったのもあった。

Android学習メモ-5

今研修で書いた糞コードをgithubにあげた。
https://github.com/oranie/AndroidStudy

コード自体は本を写経しているものが大半だけど、自分のあんちょこにはなるのでいいメモになる。
動くプロジェクトで見れるのが一番やね。(一部ビルド通らないヤツやまともに動いていないやつもあると思うけど)
現時点ではFragmentがほんとよーわからん。UI・描画周りがほんとダメダメ。思った通りのレイアウトが全然組めない。
データ操作はまあ簡単なやつしかやっていないので一応詰まりはなし。
やったけど
・adapter
・ListView
この辺はもう忘れている感ある。
なんだかんだ言って写経しただけのコードでもそれで実機が操作出来るのは嬉しいね。この辺はスマフォアプリの魅力。
Java自体はとりあえずIDEの力を存分に借りてなんとかってレベル。ただ、IDEのがエラー出している理由や補完候補に出しているものの理由を把握できていないので、Java力というよりEclipseにちょっと慣れた程度。写経力は向上した。