LoginSignup
4
5

More than 5 years have passed since last update.

Linuxでpythonからdmesg(/dev/kmsg)の更新監視

Posted at

dmesg で確認できるログを tail -F のように末尾更新の監視をするサンプル実装。
dmesg で出力されるリングバッファは /dev/kmsg または /proc/kmsg でファイルとしてオープンできる。
最終行の read でブロックしてしまうため、読み飛ばしの処理の時のみ O_NONBLOCK を指定している。

実装

dmesg(/dev/kmsg)の更新監視
#!/usr/bin/env python2
# cofing: UTF-8

import os
import fcntl
import time

def readLines(path):
    with open(path, "r") as fp:
        stat = os.stat(path)
        fp.seek(stat[6])

        where = None

        # =================
        # seek to last line
        # =================
        fd   = fp.fileno()
        flag = fcntl.fcntl(fd, fcntl.F_GETFL)
        fcntl.fcntl(fd, fcntl.F_SETFL, flag | os.O_NONBLOCK)

        try:
            # FIXME
            for last in fp:
                pass
        except IOError as e:
            if e.errno != 11:
                raise

        fcntl.fcntl(fd, fcntl.F_SETFL, flag)

        # =================
        # tailf impl
        # =================
        try:
            while True:
                where = fp.tell()
                line  = fp.readline()
                yield line
        except KeyboardInterrupt:
            pass

if __name__ == "__main__":
    import sys
    for line in readLines("/dev/kmsg"):
        if str(line).find("stop tailf") >= 0:
            print "### stop watch tailf ###"
            break
        else:
            print line,

※通常のファイルの更新監視の場合は、最終行到達時に fp.readline() で止まらないため修正が必要

実行とその結果は以下のようになる。

実行結果と終了(監視側)
$ ./tailf.py
12,642,9584294872,-;aaa
12,643,9588998703,-;bbb
12,644,9593362017,-;ccc
### stop watch tailf ###

/dev/kmsg にリダイレクトすることで、擬似的にドライバのログの出力を確認している

実行結果と終了(更新側サンプル)
$ sudo sh -c "echo aaa > /dev/kmsg"
$ sudo sh -c "echo bbb > /dev/kmsg"
$ sudo sh -c "echo ccc > /dev/kmsg"
$ sudo sh -c "echo stop tailf > /dev/kmsg"

TODO

pythonでファイルの最終行にseekする良い方法がいまいち分からなかったため、最終行まですべて読みだす方法で実装してしまっている。
巨大なファイルの場合、読み飛ばしだけで地味に時間がかかる可能性がある。(リングバッファのサイズを変更している場合等)

# FIXME
for last in fp:
    pass

参考

Emerge Technology: Pythonでtailもどき
テキストファイルから指定した文字列を含む行を出力する - Qiita
python - What is the most efficient way to get first and last line of a text file? - Stack Overflow
Get last n lines of a file with Python, similar to tail - Stack Overflow
python Non-block read file - Stack Overflow

4
5
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
4
5