Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

アクセス元の地域をKibanaで可視化する

More than 1 year has passed since last update.

ちょっとした内容をアクセスログから見たいなと思った時に
試した事があったので、それについて書こうと思います

検証したきっかけ

リリース直後や機能のアップデート後、はたまたアクセスが急増した時などに
アクセスログを見ることがよくあると思います。
ただ、上記要件以外でもカジュアルに
あれ、この地域からのアクセスが意外に多い等、
コーヒー飲みながら、サービス展開に思いを馳せたりしたいな、と思ったのがきっかけです。

今回はKibanaのvisualizeを使ってログを見ていきたいと思います。

やる事

  • Kibanaでどのあたりの地域からアクセスがあるのかを見たい
  • Elasticsearchを使う
  • ログファイルだけあれば解析できるように、embulkでElasticsearchで投入する
  • どこでも気軽に試せるようにdockerコンテナで処理する
  • 今回のエントリー用にログデータはダミーデータを利用する
  • Elasticsearchに入れるデータはIPと位置情報のみ

今回の構成

- access_kibana
  - docker
    - elasticsearch
      - config
        schema.json
      Dockerfile 
    - embulk
      - config
        embulk_config.yml 
      Dockerfile 
    - kibana
      Dockerfile 
    docker-compose.yml
  - log
  Gemfile
  sample_log.rb     

dockerコンテナで環境を用意する

Dockerfileの準備

  • elasticsearch
FROM elasticsearch:5.6.5

# x-pack
RUN elasticsearch-plugin  install --batch x-pack

# kuromoji
RUN elasticsearch-plugin  install analysis-kuromoji
  • kibana
FROM kibana:5.6.5

# x-pack
RUN kibana-plugin install x-pack
  • embulk 

こちらはDockerhubに上がっているものを利用します。
embulk Dockerfile

docker-compose

docker-composeを準備してまとめて管理します

version: '2'
services:
  elasticsearch:
    build: elasticsearch
    volumes:
        - es-data:/usr/share/elasticsearch/data
        - ./elasticsearch/config:/usr/share/elasticsearch/config
    ports:
        - 9200:9200
    expose:
        - 9300
    ulimits:
        nofile:
            soft: 65536
            hard: 65536
    network_mode: "bridge"
  kibana:
    build: kibana
    links:
        - elasticsearch:elasticsearch
    ports:
        - 5601:5601
    network_mode: "bridge"
  embulk:
    build: embulk
    links:
        - elasticsearch:elasticsearch
    volumes:
        - ./embulk/config:/opt/config
        - ../log:/opt/log
    network_mode: "bridge"
volumes:
    es-data:
        driver: local
networks:
  default:
    external:
      name: bridge

dockerコンテナを起動

cd docker
docker-compose up -d

アクセスログを作る apache-loggen

今回は apache-loggen を使ってダミーのアクセスログを作ります

gem install apache-loggen --no-ri --no-rdoc -V
apache-loggen --rate=10 --limit=10 > opt/log

ログに位置情報を追加する

IPから位置情報を推測するようにします

  • gem
# Gemfileに追加
gem 'maxminddb'
  • gem install
bundle install --path vdendor/bundle
  • 位置情報の取得
    位置情報にはMaxMindのオープンソースデータを利用します
    GeoLite2-City をダウンロードする

  • ruby
    IPと位置情報を紐付けデータを再出力します

require 'MaxMindDB'

db = MaxMindDB.new('GeoLite2-City.mmdb')
readFile = "log/orig.log"
outFile  = "log/geoip.log"
outIp = []
begin
  File.open(readFile){|file|
    file.each_line{|access|
      access.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/){|md|
        ip  = md[0]
        ret = db.lookup(ip)
        str = "#{ip},¥"#{ret.location.latitude},#{ret.location.longitude}¥""
        outIp << str
      }
    }
  }
# 例外は小さい単位で捕捉する
rescue SystemCallError => e
  puts %Q(class=[#{e.class}] message=[#{e.message}])
rescue IOError => e
  puts %Q(class=[#{e.class}] message=[#{e.message}])
end

f = File.open(outFile, "w")
outIp.each { |s| f.puts(s) }

Elasticsearchの初期化

何もtemplateを指定しないと、geo_pointを認識してくれないので
明示的に型を定義します。
今回は、ipと位置情報のみを登録するようにします。

docker-composeのvolumeで指定した [./elasticsearch/config]配下に
設定ファイルを準備する

/* schema.json */
{
  "mappings": {
      "geo_ips": {
        "properties": {
          "ip": {
            "type": "string",
            "index" : "not_analyzed"
          },
          "location": {
            "type": "geo_point"
          }
        }
      }
    }
  }
}
  • 作ったtemplateを元に indexの作成
curl -XPUT localhost:9200/geo_ips --data-binary @schema.json

embulk_configの作成

CSV情報をElasticsearchに取り込むように設定ファイルを作成します。

  • embulk_config.yml
in:
  type: file
  path_prefix: /opt/log/geoip
  parser:
    charset: UTF-8
    newline: CRLF
    type: csv
    delimiter: ','
    quote: '"'
    escape: ''
    header_line: true
    columns:
    - {name: "ip", type: string}
    - {name: "location", type: string}
out:
  type: elasticsearch
  mode: insert
  nodes:
    - {host: elasticsearch, port: 9200}
  index: geo_ips
  index_type: geo_ips

Elasticsearch実行

dockerコンテナ上で実行します

embulk run embulk_config.yml 

Kibanaで確認

localhost:5601/

スクリーンショット 2017-12-14 2.45.25.png
登録したデータが地図にプロットされました。

まとめ

fuluentdやLogstashを導入する場合はindexのtemplateだけしっかりしておけば、
そのまま表示できると思います。
ただサーバーになかなか入れらなかったり、アクセスログだけからの調査や確認をする場合は
割と便利だなと思いました。
もう少しtemplateを実用化してレガシーシステムのログも集約していければと思います。

feat2kj
readyfor
想いをつなぎ、叶える未来を、つくる READYFORのOrganizationです
https://tech.readyfor.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away