Trivial logger for VC++

ログ出力をどうしようかと google-glog を触ってみたのですが何か上手くいかず,結局,自作で逃げてしまいました.そんな訳で簡易リファレンス代わり.ログ出力関連は Boost.Log が採択されているようなので,正式に Boost 入りしたらまた考えようと思います.

Examples

使い方としては,Logger::Configuration() で初期設定をした後,各種マクロでログを出力していく形.

#include <windows.h>
#include <tchar.h>
#include <psdotnet/logger.h>
#include <psdotnet/appender.h>

int _tmain(int argc, TCHAR* argv[]) {
#ifndef PSDOTNET_INVALIDATE_LOG_MACRO
    PsdotNet::FileAppender fapp(_T("foo/bar/bas.log"));
    PsdotNet::Logger::Configuration(fapp, PsdotNet::LogLevel::Warn);
#endif
    
    LOG_TRACE(_T("trace macro"));
    LOG_DEBUG(_T("debug macro"));
    LOG_INFO(_T("info macro"));
    LOG_WARN(_T("warn macro"));
    LOG_ERROR(_T("error macro"));
    LOG_FATAL(_T("fatal macro"));
    
    return 0;
}

LogLevel

定義している LogLevel は,Quiet, Trace, Debug, Info, Warn, Error, Fatal の 7 種類.Quiet はまったくログを出力したくない時に指定する定数で,他の値はまぁよく見かけるものを定義しています.Configuration() 時に Info を指定すると LOG_TRACE, LOG_DEBUG のマクロで記述した部分は出力されないとか,そんな感じ.

IAppender

PsdotNet::Logger では IAppender がほとんど仕事をする事になっていて,ここはユーザ定義に任せています.IAppender は,Log4J の Appender と Layout を併せたような役割となります.既に定義してあるのは,指定されたファイルに出力していく FileAppender と,全く何もしない(渡されたログ情報を全て捨てていく) NullAppender の 2 種類になります.

class LogInfo;
class IAppender {
public:
    typedef std::size_t size_type;
    typedef TCHAR char_type;
    typedef std::basic_string<TCHAR> string_type;

    IAppender() {}
    virtual ~IAppender() {}

    virtual void Set(const LogInfo& info) = 0;
    virtual void operator()(const char_type* format, ...) = 0;
    virtual bool Reset() { return true; }
    virtual bool Finish() { return true; }
};

FileAppender のコンストラクタでの第 2 引数に指定できるオプションは現状では以下の通り.オプションは,"|" (OR) で複数指定する事ができます.

  • AppendMode ..... 末尾に追加モードでファイルを開く.
  • FlushOnWrite ..... 書き込む度にフラッシュする.
  • CloseOnWrite ..... 書き込む度にファイルを閉じる.
  • WriteDateTime ..... 日時を出力する.
  • WriteLevel ..... ログレベルを出力する.
  • WriteFileAndLine ..... ファイル名,行番号を出力する.
  • WriteAll ..... 日時,ログレベル,ファイル名,行番号を出力する (WriteDateTime | WriteLevel | WriteFileAndLine と同等).

ログ出力を無効にする方法

ログを出力させないようにする方法は,以下の 3 通りがあります.

  • PsdotNet::Logger::Configuration() を実行しない.
  • PsdotNet::Logger::Configuration() で PsdotNet::LogLevel::Quiet を指定する.
  • psdotnet/logger.h をインクルードする前に PSDOTNET_INVALIDATE_LOG_MACRO を定義する.

このうち上 2 種類に関しては,LOG_XXX() マクロで渡された文字列を NullAppender に渡して捨てる事でログを出力しないようにしています.すなわち,ログ出力はされませんが関数の実行自体は行われています.これに対して,PSDOTNET_INVALIDATE_LOG_MACRO を定義した場合は LOG_XXX() マクロが全てプリプロセス時点で消去されます.このため,関数の実行自体も行われません.