systemd: gemのsystemd-journalでrubyからjournalログを読んでみる

この記事はLinux Advent Calendar 2014の11日目です。

systemdはAPIが公開されていてプログラムからジャーナルを読んだりできるのですが、公式サイトを見ていたらrubyのgem(systemd-journal)があったので遊んでみます。

requireするのはsystemd/journalです。

require 'systemd/journal'

journalのオブジェクトの初期化はこうです。

j = Systemd::Journal.new

こちらは見たままですね。journalの最後に移動して何かしらのログが書かれたら表示するというものです。

j.seek(:tail)

j.watch do |entry|
  puts entry.message
end

この場合は先頭に移動し、そこから20行目の場所に移動して、その行を表示。次は現在位置から-1行目に移動してその行を表示です。

j.seek(:head)
j.move(20)
puts j.current_entry.message
j.move(-1)
puts j.current_entry.message

これは4行目に移動してそこから1行ずつ、計10行の表示です。move_nextは次の行、move_previousは前の行に移動できます。

j.move(4)
10.times {
  s j.current_entry.message
  j.move_next
}

これはsyslogのprioriyが1,6でsshdに関するものでフィルターして表示。

j.filter(priority: [1,6], _exe: '/usr/bin/sshd')
j.each do |entry|
  puts entry.message
end

ちなみに、j.current_entryがどのようなデータ構造か見てみますと、

require 'pp'
j.move(1)
pp j.current_entry

このような構造になってます。

#<Systemd::JournalEntry:0x0000000000c29f20 priority: '6', _transport: 'driver', message: 'Runtime journal is using 8.0M (max allowed 399.4M, trying to leave 599.2M free of 3.8G available → current limit 399.4M).', message_id: 'ec387f577b844b8fa948f33cad9a75e6', _pid: '113', _uid: '0', _gid: '0', _comm: 'systemd-journal', _exe: '/usr/lib/systemd/systemd-journald', _cmdline: '/usr/lib/systemd/systemd-journald', _cap_effective: '5402800cf', _systemd_cgroup: '/system.slice/systemd-journald.service', _systemd_unit: 'systemd-journald.service', _systemd_slice: 'system.slice', _boot_id: '0896d72f609b442281cf42863c691fb8', _machine_id: 'e45278de30b0468fbc1d54aa9bf3615a', _hostname: 'systemd-test'>

とまあ、軽くsystemd-journalを試してみました。journalのログを見たい場合に使える場面があるかもですね。