LoginSignup
1
1

More than 5 years have passed since last update.

時間軸でログをマッピングするRubyスクリプトサンプル

Last updated at Posted at 2017-01-11

Goal

いつどの程度の量あるかわからないログデータを時間軸でプロットして、単位時間内の合計や平均を出力するスクリプトを作る.

Code

request.log
datetime,elapse,request_url
2016-12-16T14:00:00Z,123,/blogs
2016-12-16T14:00:00Z,124,/login
2016-12-16T14:00:00Z,30,/blogs
2016-12-16T14:00:00Z,862,/blogs/23456
csv_datetime_mapper.rb
#!/usr/bin/env ruby

require "time"

# max_datetime_count: 無限ループや不要なループをなくすため十分大きい数を設定している
max_datetime_count = 50000
# start_datetime: 時間軸プロット開始時間
start_datetime = nil
# interval_ms: 時間軸プロット間隔ミリ秒
interval_ms = 1000

map = {}

STDIN.each_line do |line|
  # 入力形式
  datetime, elapse, request_url = line.split(',')
  unless start_datetime
    start_datetime = datetime
  end
  t = Time.parse(datetime)
  base_ms = ((t - Time.parse(start_datetime))*1000).div(interval_ms) * interval_ms
  map[base_ms] = [] unless map[base_ms]
  map[base_ms] << elapse.to_i
end

max_datetime_count.times do |i|
  delta_ms = interval_ms * i
  break if delta_ms > map.keys.max
  current_ms = (Time.parse(start_datetime).to_i * 1000) + (interval_ms * i)
  total_elapse = map[delta_ms] ? map[delta_ms].reduce(:+) : 0
  request_count = map[delta_ms] ? map[delta_ms].length : 0
  average_elapse = (request_count > 0) ? total_elapse / request_count : 0
  datetime = Time.at(current_ms / 1000)
  # 出力形式
  puts "#{datetime},#{total_elapse},#{request_count},#{average_elapse}"
end
cat request.log | ruby csv_datetime_mapper.rb

# datetime,total_elapse,request_count,average_elapse
# 2016-12-16T14:00:00Z,32301,209,154
# 2016-12-16T14:01:00Z,33961,213,159
# 2016-12-16T14:02:00Z,35448,237,149
# 2016-12-16T14:03:00Z,34818,237,146
# 2016-12-16T14:04:00Z,34270,231,148
# 2016-12-16T14:05:00Z,36255,257,141
# 2016-12-16T14:06:00Z,35169,245,143
# 2016-12-16T14:07:00Z,32747,232,141
# ...

Behavior

  • (ログ時間 - 開始時間)エポックタイム変換ミリ秒を間隔ミリ秒(interval_ms)で割り、これを基底時間とする
  • あるログ情報から基底時間を計算しこれをキーとして、ハッシュにログデータを保存する
  • 開始時間から間隔ミリ秒を加算していって、ハッシュからデータを取り出し必要な情報を出力する

スクリーンショット 2017-01-11 14.05.03.png

Merit

  • 一度基底時間をキーにハッシュ作成するので、ログが時間順でソートされている必要がない
  • ハッシュ内データに頼らずに出力をおこなうので、ログが存在しない時間帯があっても抜けがおこらない

Demerit

  • 一度ハッシュに展開するのでメモリを消費する(interval_msを大きくすることでメモリ量をおさえるなどの対応はできる)
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1