LoginSignup
2
0

More than 3 years have passed since last update.

nanolog, C++11 で python "{}" 記法をサポートした小さいロギングライブラリ

Last updated at Posted at 2020-03-09

背景

  • 主にグラフィックス系 C++11 アプリでロギングほしい
    • 演算メインのときではあまり print しないが, データロードとかセーブのときとかにログを出したい
    • デバッグ用にベクトルの値とかをプリントしたい
    • ログ処理速度はそんなに高速である必要はない. しかしコンパイルは早くしたい
    • すごい機能がいっぱい欲しいわけでなく, python の "{}" のような表記が使えれば OK

既存ライブラリ

  • spdlog https://github.com/gabime/spdlog : "{}" 記法が使える. 今まで 3, 4 年ほどメインで使っているが, テンプレートいっぱい使っているのでコンパイル遅い(実際には spdlog が利用している fmtlib が主にコンパイル遅い. non-header only にするとコンパイル早くなると記述があるが, やっぱりそれでも遅い).
    • あと, なぜか Android NDK r20+ clang で C++14 モードだとコンパイルに失敗する
  • glog : ビルドシステムとコードが古臭い. ストリーム記法しかない. 他のサードパーティライブラリが glog 使っていると, メインのアプリと干渉したり, またマクロ名が衝突したりすることがあり面倒になる

=> 本当に欲しい機能というはそんなにあるわけでないので, 自作しました.

nanolog

#include "nanolog.hh"

// logging method
NANOLOG_TRACE("The answer is {}", 42);
NANOLOG_DEBUG("The answer is {}", 42);
NANOLOG_INFO("The answer is {}", 42);

こんな感じで使えます.

デフォルトでは自前処理ですが({}operator<< で得た文字列で置き換えるだけ. コンパイル時引数型チェックなどはしない), backend として pprintpp と fmtlib を使えます.

pprintpp

python の "{}" 表記を実現するのに,

Typesafe Python Style Printf Formatting for C++
https://github.com/tfc/pprintpp

をバックエンドに使っています.
(fmtlib backend もあります. コンパイルは pprintpp のほうが fmtlib に比べて 4~5 倍は早いです)

printpp も template で "{}" をパースしたりしてコンパイル型チェックしてくれます.
実装がテンプレートバリバリでよくわからない :cry: ので, みなさん是非解析してみてください.

実装的には, AUTOFORMAT マクロで, ("{}", 1) が与えたれたときに, フォーマット文字列を "%d" にコンパイル時に置き換えるというのをしています.

ただ, pprintpp ではいくつか制約があります. TODO にあるように文字列型がうまく扱えません. また対応していない型だと seg fault したりします. うまくいかなければ fmtlib を使うようにしましょう.

NANOLOG_XXX

__LINE__, __func__ あたりはマクロを使わないと実現できないので, ログ関数のエントリはマクロになっています.

nanolog の内部実装的には, printf するところだけ mutex で lock_guard 入れて multi-thread safe にしているという単純なものです.

TODO

  • pprintpp で const char * を print すると, 文字列ではなくアドレスが表示されるのを直す
  • 精度はあまり求めないので, 高速な unix epoch time -> 時刻文字列生成を行う(既存のライブラリで, locale を考慮するといろいろ遅くなるみたいな噂を聞いた)
  • ログが多量に生成されるのを防ぐために, __FILE__, __LINE__ の値を見て, 前回から log 出したあと N 秒内のメッセージは suppress するとか, M 回表示したらそれ以降は suppress するとかの機能を実装する
    • グラフィックスアプリで, pixel ごとに log を出す場合にエラーメッセージが大量に出力されてしまうのを防ぐときなどに役立つ.
2
0
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
2
0