2013/12/22

nginxのhttp_geoip_moduleでアクセスログにクライアントIPの地理情報を出力する。

http_geoip_module

nginxのhttp_geoip_moduleを使うとクライアントのIPアドレスから地理情報を取得できる、と知ったので試してみた。nginxのドキュメントは、ここにあります。

http_geoip_moduleは、MaxMind社が公開するIPアドレス-地理情報マッピングデータベースを利用する、ということで、http_geoip_moduleを利用するには、同社のデータファイルやもろもろのツールなどをインストール必要があるらしい。

geoip-databaseとlibgeoip-dev

Debian系のOSでは、aptでgeoip-databaseとlibgeoip-devをインストールできる。やってみると、geoip-databaseは予めインストールされとった。(ちなみに、Ubuntuっす。)

$ sudo apt-get install geoip-database
Reading package lists... Done
Building dependency tree       
Reading state information... Done
geoip-database is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 12 not upgraded.
## もう入ってた・・
$ sudo apt-get install libgeoip-dev
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  geoip-bin
The following NEW packages will be installed:
  geoip-bin libgeoip-dev
0 upgraded, 2 newly installed, 0 to remove and 12 not upgraded.
Need to get 227 kB of archives.
After this operation, 1021 kB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://jp.archive.ubuntu.com/ubuntu/ precise/main geoip-bin amd64 1.4.8+dfsg-2 [42.4 kB]
Get:2 http://jp.archive.ubuntu.com/ubuntu/ precise/main libgeoip-dev amd64 1.4.8+dfsg-2 [185 kB]
Fetched 227 kB in 0s (641 kB/s)      
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
 LANGUAGE = "en_US:",
 LC_ALL = (unset),
 LC_CTYPE = "ja_JP.UTF-8",
 LC_COLLATE = "ja_JP.UTF-8",
 LC_MESSAGES = "ja_JP.UTF-8",
 LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
Selecting previously unselected package geoip-bin.
(Reading database ... 52114 files and directories currently installed.)
Unpacking geoip-bin (from .../geoip-bin_1.4.8+dfsg-2_amd64.deb) ...
Selecting previously unselected package libgeoip-dev.
Unpacking libgeoip-dev (from .../libgeoip-dev_1.4.8+dfsg-2_amd64.deb) ...
Processing triggers for man-db ...
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
Setting up geoip-bin (1.4.8+dfsg-2) ...
Setting up libgeoip-dev (1.4.8+dfsg-2) ...

GeoIPデータファイル

geoip-databaseが予めインストールされていたため、IPアドレス-国情報マッピングファイル(GeoIP.dat)は、/usr/share/GeoIP/にすでにファイルがあったのだけど、これだけだと都市名の情報が引けないので、GeoLiteCity.datとというファイルを別途ダウンロードする必要がある。そして、GeoIP.datと同じディレクトリに置く。

$ wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
$ gnuzip GeoLiteCity.dat.gz
$ sudo mv GeoLiteCity.dat.gz /usr/share/GeoIP/

nginx

nginxは、cofigureの時点でhttp_geoip_moduleを有効化しないといけない。なので、今回は最新の安定版のソースをダウンロードしてきて、ビルドしなおした。(↓の./configure時のオプションは、実際は他にも色々指定してます。)

$ cd /usr/local/src
$ sudo wget http://nginx.org/download/nginx-1.4.4.tar.gz
$ tar zxf nginx-1.4.4.tar.gz
$ sudo ./configure --prefix='/usr/local/nginx' --with-http_geoip_module
$ sudo make
$ sudo make install

nginx.conf

http_geoip_moduleを利用するために、nginx.confにちょっと追記した。

geoip_countryディレクティブ
GeoIP.datのパスを指定して、$geoip_country_code、$geoip_country_code3、$geoip_country_nameを有効にする。
geoip_cityディレクティブ
GeoLiteCity.datのパスを指定して、$geoip_cityや$geoip_latitude、$geoip_longitudeなどを有効にする。

この2つのディレクティブは、ファイルパスを指定するのだけど、ここの例のようにファイル名だけ指定すると、ファイルオープンエラーとなるので、絶対パスを指定した(ら、うまく動きました。) で、$geoip_xxxxxという一連の変数が利用可能になるので、これらをアクセスログフォーマットに埋めてあげると、ログに出力されるようなる。今回設定したnginxは、fluentdでmongodbに蓄積させるためにltsv形式でログを出力しているので、geoip関連もltsv形式でログフォーマットに追加した。修正したnginx.confは、↓のようになった。
:

http {
    :
  geoip_country /usr/share/GeoIP/GeoIP.dat;
  geoip_city    /usr/share/GeoIP/GeoLiteCity.dat;
    :

  log_format ltsv "time:$time_local"
                  "\thost:$remote_addr"
                  "\tforwardedfor:$http_x_forwarded_for"
                  "\tuser:$remote_user"
                  "\treq:$request"
                  "\tmethod:$request_method"
                  "\turi:$request_uri"
                  "\tstatus:$status"
                  "\tsize:$body_bytes_sent"
                  "\treferer:$http_referer"
                  "\tua:$http_user_agent"
                  "\treqtime:$request_time"
                  "\tcache:$upstream_http_x_cache"
                  "\truntime:$upstream_http_x_runtime"
                  "\tapptime:$upstream_response_time"
                  "\tvhost:$host"
                  "\tgeoip_country_name:$geoip_city_country_name"    # <= 国名
                  "\tgeoip_country_code3:$geoip_city_country_code3"  # <= JPNとかUSAとか
                  "\tgeoip_city:$geoip_city"                         # <= 都市名
                  "\tgeoip_latitude:$geoip_latitude"                 # <= 緯度
                  "\tgeoip_longitude:$geoip_longitude";              # <= 経度
    :
}
:
nginx再起動して、何やらアクセスすると、ログとfluendが出力してくれるmongodbのドキュメントにも、地理情報が出力された。

2013/12/19

three.jsでカレンダーを3Dにしてみた。

Javascriptの3Dライブラリであるthree.jsのexampleに、元素周期表を3Dで表示するっていうカッコイイのがあります。

これを参考に何か作れないかな、と思ってカレンダーを作ってみよう、となり、出来たのがこちらのページです。

これらは、次のような特徴があります。

  • THREE.CSS3DObjectというオブジェクトを利用している。
  • tween.jsを利用している。

THREE.CSS3DObject

three.jsのドキュメントには無いので、githubのソースを読もうと思ってます。

tween.js

Javascriptのアニメーションライブラリです。カレンダーでは、全然使いこなせていませんが、かなり凝ったアニメーションが簡単に作れるスグレモノみたいです。

three.jsのCSS3DObjectとtween.jsを組み合わせるだけで、相当カッコイイものが作れそうなんで、調べつつ試しつつしていこうと思っています。

2013/11/30

Rails4+kaminari+bootstrap3なページング

Railsにおけるページングライブラリといったらkaminariでいいですね。Rails4でも使えました。で、twitter-bootstrap3のページングUIと合わせて使えるのかやってみました。

kaminariの導入

Railsアプリこさえて、Gemfileに

  gem 'kaminari'
を追加して、
$ bundle
しますね。2013年11月28日現在では、kaminari (0.15.0) が入りました。ちなみに、Railsは4.0です。

bootstrap3の導入

同じく、Gemfileに
gem 'anjlab-bootstrap-rails',
:require => 'bootstrap-rails',
:github  => 'anjlab/bootstrap-rails'
を追加して、
$ bundle
します。

bootstrapのページング

bootstrapのページング(ページネーション)は、Components · Bootstrapに説明があります。kaminariのページングに、このUIを適用したい、っていうのがこの記事の根幹です。

rails generate kaminari:views bootstrap

kaminariにはthemeっていう概念があって、アプリにテーマを適用するには、

$ rails generate kaminari:views [theme]
を実行すると、[theme]が適用されたerbセットを作ってくれるんですね。で、[theme]に何指定したらいいの?ってことで、
$ rails g kaminari:views --help
をやったら、出てきました。
Usage:
  rails g kaminari:views THEME [options]

    Copies all paginator partial templates to your application.
    You can choose a template THEME by specifying one from the list below:

        - default
            The default one.
            This one is used internally while you don't override the partials.
        - bootstrap
            Pagination for Twitter Bootstrap 2.0.
            http://twitter.github.com/bootstrap/
        - github
            A very simple one with only "Older" and "Newer" links.
        - google
            A googlish one.
            Try with this option  :window => 10, :outer_window => -1

Options:
      [--skip-namespace]                   # Skip namespace (affects only isolated applications)
  -e, [--template-engine=TEMPLATE_ENGINE]  # Template engine for the views. Available options are "erb", "haml", and "slim".
                                           # Default: erb

Runtime options:
  -f, [--force]    # Overwrite files that already exist
  -p, [--pretend]  # Run but do not make any changes
  -q, [--quiet]    # Suppress status output
  -s, [--skip]     # Skip files that already exist
なんだ、bootstrapサポートされてるじゃない、ってことでTHEMEにbootstrapを指定して、
$ rails g kaminari:views bootstrap
を実行して、次のファイルたちを得たわけです。
  • app/views/kaminari/_first_page.html.erb
  • app/views/kaminari/_gape.html.erb
  • app/views/kaminari/_last_page.html.erb
  • app/views/kaminari/_next_page.html.erb
  • app/views/kaminari/_page.html.erb
  • app/views/kaminari/_paginator.html.erb
  • app/views/kaminari/_prev_page.html.erb

_paginator.html.erbの修正

上のヘルプの内容を見ると、bootstrap2.0用のテーマなんですね。じゃあ、bootstrap3用にするには、どうするかってことなんですが、試したところ、_paginator.html.erbを、↓のように修正することで対応出来ました。

diff --git a/app/views/kaminari/_paginator.html.erb b/app/views/kaminari/_paginator.html.erb
index 03d508e..01e7195 100644
--- a/app/views/kaminari/_paginator.html.erb
+++ b/app/views/kaminari/_paginator.html.erb
@@ -1,17 +1,19 @@
 <%= paginator.render do -%>
-  <div class="pagination">
-    <ul>
-      <%= first_page_tag unless current_page.first? %>
-      <%= prev_page_tag unless current_page.first? %>
-      <% each_page do |page| -%>
-        <% if page.left_outer? || page.right_outer? || page.inside_window? -%>
-          <%= page_tag page %>
-        <% elsif !page.was_truncated? -%>
-          <%= gap_tag %>
+  <div class="row">
+    <div class="col-md-12 text-center">
+      <ul class="pagination">
+        <%= first_page_tag unless current_page.first? %>
+        <%= prev_page_tag unless current_page.first? %>
+        <% each_page do |page| -%>
+          <% if page.left_outer? || page.right_outer? || page.inside_window? -%>
+            <%= page_tag page %>
+          <% elsif !page.was_truncated? -%>
+            <%= gap_tag %>
+          <% end -%>
         <% end -%>
-      <% end -%>
-      <%= next_page_tag unless current_page.last? %>
-      <%= last_page_tag unless current_page.last? %>
-    </ul>
+        <%= next_page_tag unless current_page.last? %>
+        <%= last_page_tag unless current_page.last? %>
+      </ul>
+    </div>
   </div>
 <% end -%>

2013/11/26

Javascriptのグラフ描画ライブラリJSChartsを試してみた。

Webページ上にチャートを描画するJavascriptライブラリに JSCharts というのがある。シンプルなAPIかつ、綺麗なチャートが描画できそうだったので試してみた。

JSCharts

JSChartsは、http://www.jumpeyecomponents.com/というサイトで公開されているソフトウェアライブラリの1つ。このサイトは、有償ソフトウェアを販売しているっぽくて、JSChartsも有償。ただ、同サイトにユーザ登録をし、JSChartsで描画するチャートにウォータマークを表示する、という条件で無料で利用できる。今回試したのは無料版。

価格

ちなみに、JSChartsの価格は2013年11月末現在、http://www.jscharts.com/free-downloadにあるように、1ドメインでの非商用利用で$39、商用利用で$79というお値段。

チャート

JSチャートがサポートするチャートは、

  • Line Chart
  • Bar Chart
  • Pie Chart
の3種類。チャートの種類は少ないけど、色が設定やツールチップや凡例の表示が細かくできる点が強いところに見える。チャートの例や具体的なAPIは本家のサイトに詳しく書いてあるのでここには書かないけど、実際にチャートを描画したイメージを張っておく。

画像、もしくは実際のサイト上の描画(http://simalabs.com/labs/jscharts)をよく見るとわかるんだけど、各チャートの左上に「JSCharts」っていう画像が表示されていて、これがそのウォータマークってやつ。これを表示させないためには、お金払ってね、ということ。けど、実際にWebページ上に敢えてチャート出す時って、軸や値の数値も見れた方が嬉しい、という人のほうが多いと思うし、4,000円乃至8,000円は払っても損はないかなと思います。以前試したChart.jsよりは個人的にはJSChartsの方が使いたいと思ってる。(Javascriptのグラフ描画ライブラリChart.jsを試してみた。参照)

2013/11/24

Javascriptのストリーミングデータ用チャートライブラリSmoothie Chartsを試してみた。

Javascriptのチャートライブラリを調べていて、ちょっと変わったライブラリをみつけたので試してみた。
今回試したのは、Smoothie Chartsというもので、ストリーミングデータを時系列なラインチャートとして表示するもの。MITラインセンスのオープンソースで、githubにホスティングされてる。

リアルタイムな時系列チャートを描く

このライブラリを使うと、簡単にリアルタイムな時系列チャートが描画できる。使い方は、チュートリアルがあり、本当に簡単すぎる・・・

ポイントとしては、

  • canvasタグを利用する。
  • setInterval関数を使ってリアルタイムにチャートを更新する。
というところか。

実際にページ上で使ってみた例が、このキャプチャになります。

ここに動くページを作ってみたよ。