🐧 Linux 総合学習プラットフォーム
デバイスドライバ実装 ・ 上級

printk とログレベル

printk はカーネル空間からログを出す関数で、メッセージの先頭に KERN_INFO や KERN_ERR といったログレベルを付けて緊急度を示せる。レベルは8段階(0=EMERG が最も深刻、7=DEBUG が最も軽い)。/proc/sys/kernel/printk でコンソール表示のしきい値を確認でき、dmesg -l でレベル別に絞り込める。どのメッセージを表に出すかを重要度で仕分ける仕組みだ。

ドライバのログは dmesg で読める、と前に学んだ。だが、出したメッセージが全部そのままコンソールに流れてくると、大事な知らせが雑多な記録に埋もれてしまう。

この「にぎやかすぎる」問題を、カーネルはどう解いているのか。答えが、メッセージ一つひとつに緊急度の目印を付けておく、という仕組みだ。

💡
ポイントprintk のメッセージには緊急度(ログレベル)を付けられる。重要度で仕分けておけば、表に出す量を後から調整できる。

ドライバがログを出すのに使う printk では、メッセージの先頭にログレベルという印を添えて、そのメッセージがどれくらい深刻かを示せる。

この回では、レベルにどんな段階があり、どう指定し、そしてどのレベルまでを実際に画面へ出すかをどう調整するのかを見ていく。ログを「垂れ流し」から「使える情報」に変えるための土台になる話だ。

🌡 8段階のレベルと、数字の向き

printk のログレベルは、全部で8段階が定義されている。

深刻なものから順に並べると、システムが使用不能(EMERG)、ただちに対処が必要(ALERT)、危機的な状況(CRIT)、エラー(ERR)、警告(WARNING)、正常だが重要(NOTICE)、単なる情報(INFO)、そしてデバッグ用(DEBUG)、となる。

ここで数字の向きに気をつけたい。最も深刻な EMERG が 0 で、最も軽い DEBUG が 7 という具合に、数字が小さいほど緊急度が高い、という決まりになっている。日常の感覚とは逆に感じるかもしれないので、意識して覚えておくとよい。

🔗
たとえ番号は「順位」ではなく「危険の近さ」。0 が最前線の非常ベル、7 がのんびりしたメモ書きだ。

実務でよく使うのは、正常時の記録を残す INFO と、異常を知らせる ERR あたりだ。まずはこの2つを軸に、必要に応じて他のレベルを使い分けていけばよい。

✍ レベルを、どうやって付けるのか

では、コードの中でレベルをどう指定するのか。難しくはない。

各レベルには KERN_INFO や KERN_ERR といった名前の付いた印が用意されていて、printk に渡す文字列の先頭にそれを置くだけでよい。

printk(KERN_ERR "init failed\n"); ……エラーレベルでログを出す。KERN_INFO なら通常の情報として出る。

たとえばエラーを知らせたいときは printk(KERN_ERR ...) のように書き、通常の情報なら printk(KERN_INFO ...) と書く。印と、それに続くメッセージ本文の間にカンマは入らず、続けて書く点だけ最初は戸惑いやすい。

もし印を何も付けずに printk を書くと、あらかじめ決められた既定のレベルが使われる。とはいえ、後から読む人のためにも、メッセージの性格に合った印を意識して付けておくのが行儀のよい書き方だ。

🎚 どのレベルまで画面に出すか — しきい値

レベルを付けておくと何が嬉しいのか。ここからが本題だ。

システムには「このレベル以上に深刻なメッセージだけをコンソールに表示する」というしきい値が設定されていて、その現在値は /proc/sys/kernel/printk というファイルを読むと分かる。

このしきい値より軽い(数字が大きい)メッセージは、記録はされてもコンソールには出てこない。ふだんは重要なものだけを表示して静かにしておき、調査が必要なときだけ、デバッグ用の細かいメッセージまで表に出す、という調整ができるわけだ。

cat /proc/sys/kernel/printk で現在のしきい値を確認できる。左端の数字がコンソールに出す下限のレベルだ。

このしきい値は、必要に応じて dmesg にレベルを指定するオプションで変えられ、たとえばデバッグ中は全レベルを表示させ、落ち着いたら重要なものだけに戻す、という使い方をする。

「ログの量は、出す側だけでなく、受け取る側のしきい値でも決まる」と理解しておくと、メッセージが出たり出なかったりする現象に戸惑わずに済む。

🔍 dmesg 側でレベルを絞り込む

出力の量を、表示のときに絞る手もある。

dmesg には、指定したレベルの行だけを取り出して見せるオプションがあり、たとえばエラーだけを拾いたい、警告以上だけを見たい、といった調査ができる。

dmesg -l err でエラーレベルの行だけを、dmesg -l warn で警告レベルの行だけを抜き出せる。

コンソールに出す・出さないのしきい値とは別に、すでに溜まったログの中から必要なレベルだけを後から選り分けられる、と考えるとよい。原因を追うとき、まず err のレベルだけに絞って眺めれば、異常の手がかりを素早く見つけられる。

レベルを付けて出し、レベルで絞って読む。この両輪がそろって、はじめてカーネルログは調査に耐える道具になる。

✅ まとめ — 静かさと詳しさを両立させる

printk のログレベルは、ひとことで言えば「大事な知らせと、にぎやかなだけの記録を仕分ける仕組み」だ。

コードを書く側は、メッセージの性格に合わせて KERN_ERR や KERN_INFO を付けておく。読む側は、しきい値や dmesg のレベル指定で、そのときに必要な量だけを表に出す。

コツ平常時は静かに、調査時は詳しく。ログレベルは、その切り替えを一つの仕組みで実現するためにある。

この仕組みを使いこなせると、ドライバのログが「常に全部出て邪魔」でも「肝心なときに何も出ない」でもない、ちょうどよい観察の道具になる。次に自作ドライバへ進むとき、この仕分けの感覚がそのまま役に立つ。

この項目に出てくる用語

ログレベルろぐれべる
printk のメッセージに付ける緊急度の印。8段階ある。
KERN_INFO / KERN_ERRかーねるいんふぉかーねるえらー
printk に渡す文字列の先頭に置くログレベルの印。

関連コマンド

dmesg

▶ 学習アプリでこの続きを学ぶ・演習する