metabaseの設定画面で一瞬でもロケールにtrに選択すると詰む。

詰んだ。

バージョンはv0.30.3です。
最初何が起こったのか全くわかりませんでしたが、エラー内容的に言語設定があやしそうだったので、 metabase.db.mv.dbの中身を直接見て、SETTINGのsite-localeをen-USに設定したら無事に復旧しました。
ゆとりなので修正にはGUIのH2 Consoleを使用しました。あと、DBのIDとPWはそれぞれ空文字でした。

翻訳しなくてもいいところが翻訳されまくっててわかりにくいので英語に戻したいんですが、ブラウザのロケールで強制的に言語が決まってしまうので大変に辛いです。

Metabaseを使ってポケモンGOで孵化したタマゴの情報を可視化する。

旦那さんとポケモンGOをプレイしているのですが、タマゴから孵るポケモンに偏りがあるかを知りたかったので、記録を取るようにしています。
記録の方法は以下の通り。

  1. タマゴが孵化したらLINEグループ宛に報告する
  2. 報告をLINE botが拾ってDB(SQLite3)に書き込む

LINE botと会話して統計を取れるようにはなっているのですが、テキストベースだと情報がデジタルでいまいちピンとこないため、Metabaseで情報を可視化してみることにしました。最初Grafanaが使いたかったのですが、SQLiteに対応していないので自動的にMetabase一択になりました。

動かし方

インストールは以下の記事を参考にしました。
OSSのデータ可視化ツール「Metabase」が超使いやすい
Dockerが多分一番楽に立ち上げられる気がします。私の環境はいろいろあってDockerが動かせないので、jarをそのままOpenJDK 8で動かす方法をとりました。使用したMetabaseのバージョンは0.30.1です。デフォルトだと3000番がMetabaseのポートになります。
セットアップはほんとに楽すぎて何も困ることなかったので割愛。

可視化したいDBの設定

DBの追加画面

ここから解析対象のDBまでのパスを入力すればすぐ解析してくれます。

DBの可視化結果とか

DBの可視化結果
ポケモンの円グラフとかホエルコのグラフとか

お互いが孵したポケモンの円グラフを作ってみました。本当はグラフの横に凡例と値が出力できるのですが、GUIのバグで凡例が多すぎるとグラフが表示できなくなるため、非表示にしています。カーソルを当てると内容がわかるのですが、不便なので次バージョンに期待します。

DBのフィルタリング結果

フィルター機能で期間やタマゴの距離を絞り込むこともできます。めちゃくちゃ楽です。

使ってみた感想

私がQuestionをあまり上手に使いこなせていないので、今の所Kibanaのように息を吸って吐くレベルのグラフ作成には到達できていません。が、最悪SQL文を書いてもグラフは作れるので、可視化するには困らなさそうです。ただ動かすまでの手軽さは、ElasticSearchとFluentdのハードルが高い分、圧倒的にMetabaseのほうが勝ります。java jarコマンド打つだけだったので本当に手軽でした。アクセスログを解析するぐらいであれば、Metabaseで十分用が足りると思います。GUI周りのバグについては今後の修正に期待したいと思います。

あと、旦那さんが使っているブラウザがモダンブラウザではないので、表示がバグったり動作しないスクリプトがあったりするのが悩みどころです。他人とダッシュボードを共有するときは、モダンブラウザの使用ルール化することをおすすめします。

Metabase v0.30.1 でSQLite3のテーブルのFILTERED BYが動作しない

あらまし

Metabase v0.30.1でSQLite3のテーブルを読み込んだのですが、DB追加時にMetabaseが実施してくれるExploreが500を返し続けて永遠に終わらなかったり、FILTERED BYを使おうとしてもfieldの候補が表示されないので原因を調べました。Sample datasetだと問題ないのでインストール時の問題ではなさそうです。

FILTERED BYが選択できない

FILTERED BYが選択できない

調査

logに以下の警告が出ています。Settingsからログが見られるのはありがたいですね。

Aug 26 12:50:00 WARN metabase.driver.generic-sql :: Don't know how to map column type '' to a Field base_type, falling back to :type/*.
(中略)
Aug 26 07:50:04 ERROR metabase.sync.util :: Error running sync step: class java.lang.ClassCastException
[]

テーブル作成時にカラムのデータ型を指定しなかったので、typeが空文字で返ってきてしまって、どの型にキャストしていいのかわからずにエラーを起こしているみたいですね。DBの仕様に合わせてその辺りよろしくやってくれると嬉しいのですが。

対処

カラムの型を定義したテーブルを作り直してMetabaseに登録し直します。SQLiteは途中でカラムの定義が変えられないようなので、create tableし直したあとにinsert intoで元のテーブルの内容をそっくりそのまま挿入する方法でどうにかしました。

結果

無事Exploreが動作してFILTERED BYも選択できるようになりました。SQLiteの時刻表記の文字列が時刻として扱われるのか不安でしたが、きちんと時刻として認識されました。よかったです。

nginxでリバースプロキシしているときにupstreamからのレスポンスヘッダを書き換える。

やりたいこと

いろいろあって、nginxでリバースプロキシしているときに、upstreamから渡ってくるlocationヘッダの中身を書き換えないといけない場面に出くわしました。
普通ならproxy_redirectでどうにかするものですが、upstreamが返してくるlocationヘッダが自分の管理しているサイトとは全然別のところで、それをどうにか書き換えないといけません。ちなみにいじっている環境はモジュールが導入できないので、デフォルトで有効になっている機能でどうにかする必要があります。

やりたいことを図にするとこんな感じですね。

これを

upstream--(Location: http://example.com?hogehoge)--> nginx--> クライアント

こうしたい。

upstream--(Location: http://example.com?hogehoge)--> nginx (Location: http://example.jp?hogehoge)--> クライアント

失敗した方法

最初「if使って書き換えればいいじゃん」と思って試したのが以下。

location / {
  if ($upstream_http_location ~ example.com(.*)){
     proxy_hide_header location;
     add_header location http://example.jp$1;
  }
}

おそらくifの評価タイミングが$upstream_http_locationに値が設定される後ではなく前のため、どう頑張っても評価がfalseになってしまいました。そもそもlocation内でifを使うのは事故の元なのであんまりよくないです。
If Is Evil | NGINX

期待通りに動作した方法

じゃあmapならどうだと思って試したのが以下。

map $upstream_http_location $location{
  ~example.com(.*) http://example.jp$1;
  default $upstream_http_location;
}
location / {
  proxy_hide_header location;
  add_header location $location
}

動きました。ifは評価タイミングがクライアントからリクエストを受けた直後で、mapはレスポンス返す直前なのかな…。そこは理解できていません。
Module ngx_http_rewrite_module
Module ngx_http_map_module

twitter系のアプリが軒並み死んでいたので復旧させました。

Twitter が OAuth 認証時 Callback URL をチェックするようになったみたい – プログラミング生放送
Action REQUIRED – Sign in with Twitter users must whitelist callback URLs – Announcements – Twitter Developers

何だこの仕様変更。ほぼすべてのアプリで設定が適当(httpsがhttpになってたりURLが違ったり)だったため修正しました。最初upicoが使えないとのご連絡を頂きまして、トークン払い出しきったと思って一時対処的にtwimageのキーを設定してたのですが、結局原因が全然違ったという。
コードに修正の入る仕様変更だった場合、もう直す時間も気力もないと思ってたので、簡単に修正できてよかったです。