ログフォーマット仕様

22487 ワード

1概要
プログラムにログを書くことは非常に重要ですが、開発者に無視されやすい場所です.プログラムのログを書くことで、後期のメンテナンスのストレスを大幅に軽減できます.実際の仕事の中で、開発者は往々にして大きな時間の圧力に迫られ、ログを書くのは非常に煩わしいことであり、十分な重視を引き起こさないことが多い.開発者は、最初から良いログ作成習慣を身につけ、実際の開発作業でログを書くのに十分な時間を残しておく必要があります.
1.1ログの役割
一般的なプログラムログは以下のいくつかの方面の需要から出ています:1.ユーザーの操作を記録する監査ログは、監督管理部門の要求である場合もあります.2.問題の原因を素早く特定する3.プログラムが実行するプロセスを追跡します.4.トレースデータの変化5.データ統計と性能分析6.実行環境データを収集するのは一般的にプログラムがオンラインになった後、異常が発生すると、最初のことはその時何が起こったのかを明らかにすることです.ユーザが当時どのような操作をしていたのか,環境に影響があったのか,データがどのように変化しているのか,繰り返し発生しているのかなど,さらにどのような問題があるのかを特定する.プログラムの問題であることを確定した後、開発者に再現、研究、解決策を提出する.このとき、ログは私たちに最初の資料を提供してくれました.
1.2ログ作成の要件
日記を書くことが必要であり、将来的に仕事の効率を高めるのに役立つことである以上、長期的には非常に有利なことです.そのため、私たちは自分が開発したプログラムで規範に合った作成ログを作成し、ログを書く際に以下の問題に注意しなければならない.
1.2.1ログの読み取り可能性
ログを読むときに読まれるのは、自分に理解させるだけでなく、私たちのソースコードに触れていない他のプログラマーにも一目瞭然にさせることです.同僚の中には、「+++++++++++++」、「=============================================================================これは悪いプログラミング習慣です.また、ログの分類を異なるファイルに出力することも、干渉を排除し、必要な情報を迅速に見つけるのに役立ちます.また、ログを印刷するときに英語を出力し、中国語がサポートされていないために文字化けしが印刷されないようにすることが望ましい.
1.2.2ログのパフォーマンス
ログをファイルに書いてもデータベースに書いても、IOリソースを消費する必要があります.適切な制御ログの出力も、プログラムのパフォーマンスを向上させるのに役立ちます.たとえば、大きなサイクルで意味のないログコンテンツを印刷しないようにします.ログを出力する前にログのレベルを判断することが望ましい(例えば.debugの前にisDebugEnabled()を呼び出して判断する).
1.2.3ディスク容量の使用
通常、ディスク上のログファイルにログを書き込みます.スクロールログを適切に使用し、古いファイルを定期的に消去することはメリットがあります.このような例を見たことがありますが、プログラムが何回か実行されると走れなくなり、前の何回も正常でした.プログラムに何の問題があるのかどうしても分からず、ログファイルがディスク領域を埋め尽くしていることに気づいた.実際のアプリケーションではGのログファイルが登場することも珍しくない.このような規模のログ・ファイルで、問題解決に役立つ情報を見つけることも大きな課題です.
1.2.4ログの有効性
時々私たちはタイムリーに問題を発見することができません.遡及前のログが必要です.トレーサビリティを容易にするには、しばらくの間ログを保持する必要があります.1.2.5ログ・レベルは通常、製品環境においてログのレベルがINFO以上であるため、このような状況下でプログラムが判断に十分な情報を出力できることを保証しなければならない.たとえば、一般的なシステムには、次のようなログ・レベルがあります.
//   FATAL     
#define DRV_LOG_FATAL(fmt, ...)           hlog_format(HLOG_LEVEL_FATAL, "PluginDriver",   "[%s(%d)] "fmt, __FUNCTION__,   __LINE__, ##__VA_ARGS__)

//   ERROR     
#define DRV_LOG_ERROR(fmt, ...)           hlog_format(HLOG_LEVEL_ERROR, "PluginDriver",   "[%s(%d)] "fmt, __FUNCTION__,   __LINE__, ##__VA_ARGS__)

//   WARN     
#define DRV_LOG_WARN(fmt, ...)          hlog_format(HLOG_LEVEL_WARN, "PluginDriver",   "[%s(%d)] "fmt, __FUNCTION__,   __LINE__, ##__VA_ARGS__)  

//   INFO     
#define DRV_LOG_INFO(fmt, ...)          hlog_format(HLOG_LEVEL_INFO, "PluginDriver",   "[%s(%d)] "fmt, __FUNCTION__,   __LINE__, ##__VA_ARGS__)  

//   DEBUG     
#define DRV_LOG_DEBUG(fmt, ...)           hlog_format(HLOG_LEVEL_DEBUG, "PluginDriver",   "[%s(%d)] "fmt, __FUNCTION__,   __LINE__, ##__VA_ARGS__)   
//   TRACE     
#define DRV_LOG_TRACE(fmt,   ...)         hlog_format(HLOG_LEVEL_TRACE, "PluginDriver",   "[%s(%d)] "fmt, __FUNCTION__,   __LINE__, ##__VA_ARGS__)  

上記のログファイルには6種類のログレベルが定義されており、異なるレベルの意味は以下で詳しく説明するが、1つのプログラム開発の過程でFATAL、ERROR、EARN、INFO、DEBUG、TRACEを維持する必要があることを理解する必要がある.
1.2.6ログの内容
ログを書くときは、適切な内容を出力することに注意する必要があります.まず、ビジネス関連の説明をできるだけ使用します.私たちのプログラムはあるビジネスを実現しているので、この時にビジネスプロセスのどのステップに達したかを説明したほうがいいです.次に、ユーザー名やパスワードなどの機密情報をログに出力しないでください.および、符号化の一貫性を保つ.保証できない場合は、できるだけ中国語ではなく英語を使います.これにより、ログを手に入れた後、文字化けして何が起こっているのか分からないことはありません.
1.2.7ログ形式
一般的なログ・フォーマットでは、各ログに含まれる情報には、日付、時間、ログ・レベル、コードの場所、ログの内容、エラーコードなどの情報が含まれます.次に、作業中のログ・ファイルの一部を示します.
2018-05-22 15:35:53.850 TRACE TDWZLog [0x00001b10] <36> <TDWZProtocol::Init>,TDWZProtocol::Init
2018-05-22 15:35:53.850 TRACE TDWZLog [0x00001b10] <89> <TDWZProtocol::Init>,End in processing TDWZProtocol::Init
2018-05-22 15:35:53.853 TRACE TDWZLog [0x00001b10] <142>    <TDWZProtocol::Connect>,Connect Execute finish
2018-05-22 15:35:53.853 TRACE TDWZLog [0x00002f10] <149>    <GetAlarmEventPro>,Enter GetAlarmEventPro func
2018-05-22 15:39:36.382 WARN TrackLog [0x000029fc] - [ internal WARN htrace_server_convert_msgstring_to_contextintls(493) ] detect input id error, trace_id span_id,this chain may not be tracked.
2018-05-22 15:39:36.383 WARN TrackLog [0x000029fc] - [ internal WARN htrace_server_receive(195) ] can not detect trace_id in context, this chain may not be tracked.
2018-05-22 15:39:36.383 TRACE TDWZLog [0x000029fc] <231>    <TDWZProtocol::DisConnect>,TDWZProtocol::DisConnect
2018-05-22 15:39:37.502 TRACE TDWZLog [0x00002f10] <225>    <GetAlarmEventPro>,End Get AlarmEventPro Func
2018-05-22 15:39:37.503 TRACE TDWZLog [0x000029fc] <241>    <TDWZProtocol::DisConnect>,close socket
2018-05-22 15:39:37.503 TRACE TDWZLog [0x000029fc] <242>    <TDWZProtocol::DisConnect>,Execute DisConnect function succeed.

2ログ・レベルと意味
Log 4 jはApacheのオープンソースプロジェクトであり、Log 4 jを使用することで、ログ情報の出力先がコンソール、ファイル、GUIコンポーネント、さらにはソケットサーバであることを制御することができます.各ログの出力フォーマットを制御することもできます.各ログ情報のレベルを定義することで、ログの生成プロセスをより細かく制御できます.最も興味深いのは、アプリケーションのコードを変更することなく、1つのプロファイルで柔軟に構成できることです.
2.1 Log 4 jの構成
Log 4 jは、ログレコーダ(Loggers)、出力端子(Appenders)、ログフォーマット(Layout)の3つの重要な構成で構成されている.
2.1.1 Logger
どのログ・ログ・ステートメントを有効または無効にし、ログ情報をレベル制限するかを制御します.
2.1.2 Appenders
ログがコンソールに印刷されるかファイルに印刷されるかを指定します.
2.1.3 Layout
ログ情報の表示形式を制御します.
2.2ログ・レベル
Log 4 jでは、出力するログ情報をTRACE、DEBUG、INFO、WARN、ERROR、FATALの6つのレベルで定義しています.出力する場合は、構成で規定されているレベルよりもレベルの高い情報だけが本格的に出力されます.これにより、コードを変更することなく、異なる場合に出力する内容を容易に構成でき、非常に便利で迅速です.
2.2.1 TRACE
TRACE designates finer-grained informational events than the DEBUG.Since:1.2.12、非常に低いログレベルで、一般的には使用されません.TRACEは一般に関数の呼び出しを追跡し、TRACEは変数パラメータを含むべきではなく、関数の呼び出し関係のみを提示することができる.
2.2.2 DEBUG
一般に細粒度レベルで使用され、主に開発中に実行情報を印刷するために使用されるデバッグアプリケーションに役立ちます.
2.2.3 INFO
INFOメッセージは、太さレベルでアプリケーションの実行プロセスを強調します.興味のある情報や重要な情報を印刷します.これは、本番環境でプログラムが実行する重要な情報を出力するために使用できますが、乱用したり、ログを印刷したりすることはできません.
2.2.4 WARN
WARNは、潜在的なエラーが発生する場合を示します.一部の情報はエラー情報ではありませんが、プログラマーにもヒントを与えます.このレベルは、プログラムが正常な状態に自動的に調整されることを示します.このようなパラメータは入力されず、デフォルトのパラメータが使用されており、プログラマの予想に合致しています.
2.2.5 ERROR
ERRORは、エラーイベントが発生してもシステムの継続に影響しないことを示しています.エラーと例外情報を印刷し、あまりログを出力したくない場合は、このレベルを使用します.一般的にWARN以降のレベルでは、エラーを印刷するときに、エラーコードを同時に印刷する必要があります.
2.2.6 FATAL
FATALは、重大なエラーイベントごとにアプリケーションが終了することを指摘しています.このレベルは比較的高く、重大なエラー、プログラムが回復できないため、プログラムを再起動することで解決する必要があります.
2.3ログ・レベルのサイズ関係
ログ・レベルは、スイッチのように、どのログ・メソッドが呼び出されるか、呼び出されないかを決定します.log 4 jでは、ログレベルの関係を以下に示す.
ALL

対応するレベルを設定すると、ログ・フレームワークはこのレベル以上のメソッドのみを呼び出します.Log 4 jは以下の4つの境界のみを使用することを推奨する
DEBUG

3ログ仕様の例
真似、書き写すのは比較的に良い学習方式で、前人の日記を書く良い風格を参考にして自分の風格を形成するのは悪くない方式です.次はいいログです.
3.1 TRACEログ記録例
DRV_LOG_TRACE("Connect Execute start");
DRV_LOG_TRACE("Connect Execute finish");
DRV_LOG_TRACE("DisConnect func");
DRV_LOG_TRACE("Execute DisConnect function succeed.");
DRV_LOG_TRACE("Enter UploadEvent Func");
DRV_LOG_TRACE("extInfo = %s", Extension);
DRV_LOG_TRACE("Send a Msg ");
DRV_LOG_TRACE("- Connect Execute start");
DRV_LOG_TRACE("- Connect Execute finish");
DRV_LOG_TRACE("- Enter GetAlarmEventPro func");
DRV_LOG_TRACE("- Receive an info");
DRV_LOG_TRACE("- End Get AlarmEventPro Func");
DRV_LOG_TRACE("- DisConnect func");
DRV_LOG_TRACE("- Execute DisConnect function succeed.");
DRV_LOG_TRACE("- Enter UploadEvent Func");
DRV_LOG_TRACE("- Leave UploadEvent Func");
DRV_LOG_TRACE("- ============      ");
DRV_LOG_TRACE("- ============         ");
DRV_LOG_TRACE("- ============               ");

3.2 INFOログ記録例
DRV_LOG_INFO("- UpdataEvent  nchal= %d,EventID = %d.",iChannelNo,nEventType);
DRV_LOG_INFO("- do not support doControl");
DRV_LOG_INFO("- channelId = %s, nStatusType = %d", channelId.c_str(), nStatusType);

3.3 DEBUGログ記録例
DRV_LOG_DEBUG("-       :    :%d,    :%d,    :%s.",datas.data1.chn,datas.data1.alarm_num,datas.data1.alarms);
DRV_LOG_DEBUG("-       :    :%d,    :%d,    :%s.",datas.data2.chn,datas.data2.alarm_num,datas.data2.alarms);
DRV_LOG_DEBUG("-       :    :%d,    :%d,    :%s.",datas.data3.chn,datas.data3.alarm_num,datas.data3.alarms);
DRV_LOG_DEBUG("-       :    :%d,    :%d,    :%s.",datas.data4.chn,datas.data4.alarm_num,datas.data4.alarms);
DRV_LOG_DEBUG("- ============datas.data1.huab = %d",datas.data1.huab);
DRV_LOG_DEBUG("- ============datas.data1.hiab = %d",datas.data1.hiab);
DRV_LOG_DEBUG("- ============datas.data2.huab = %d",datas.data2.huab);
DRV_LOG_DEBUG("- ============datas.data2.hiab = %d",datas.data2.hiab);
DRV_LOG_DEBUG("- ============datas.data3.huab = %d",datas.data3.huab);
DRV_LOG_DEBUG("- ============datas.data3.hiab = %d",datas.data3.hiab);
DRV_LOG_DEBUG("- ============datas.data4.huab = %d",datas.data4.huab);
DRV_LOG_DEBUG("- ============datas.data4.hiab = %d",datas.data4.hiab);
DRV_LOG_DEBUG("- Alarm is : %s",szEvent.c_str());
DRV_LOG_DEBUG("- GetChannelExtInfo channelId=%s", channelId.c_str());
DRV_LOG_DEBUG("- nChan = %d, szInfo = %s", nChan, szInfo);

3.4 WARNログ記録例
DRV_LOG_WARN("[0x%08x] - invaild event msg,discard it", DRV_INVALID_ARG);
DRV_LOG_WARN("[0x%08x] - Can't find channel by channelId");
DRV_LOG_WARN("[0x%08x] - [DWSdk.errorcode=0x%08x]Connect device failed", DRV_CONNECT_FAILED, sdkErrCode);
DRV_LOG_WARN("[0x%08x] - [DWSdk.errorcode=0x%08x]dw_start_receive failed", DRV_ERROR, sdkErrCode);
DRV_LOG_WARN("[0x%08x] - [DWSdk.errorcode=0x%08x]Communicate failed, socket recv error", DRV_ERROR, DW_SOCKET_RECV_ERROR);
DRV_LOG_WARN("[0x%08x] - [DWSdk.errorcode=0x%08x>other error", DRV_ERROR, iGetResult);
DRV_LOG_WARN("[0x%08x] - [DWSdk.errorcode=0x%08x>other error", DRV_ERROR, iGetResult);
DRV_LOG_WARN("[0x%08x] - SetEventCallBack should be called first", DRV_ERROR);

3.5 ERRORログ記録例
DRV_LOG_ERROR("Init DwSDK filded;", initRet); 
DRV_LOG_ERROR("Connect device failed");
DRV_LOG_ERROR("Create thread failed");
DRV_LOG_ERROR("dw_start_receive failed");
DRV_LOG_ERROR("Communicate failed, socket recv error");
DRV_LOG_ERROR("other error", iGetResult);
DRV_LOG_ERROR("SetEventCallBack should be called first");

DRV_LOG_ERROR("[0x%08x] - [DWSdk.errorcode=0x%08x]Init DwSDK filded", DRV_INIT_FAILED, initRet);
DRV_LOG_ERROR("- [HPR.errorcode=0x%08x]Create thread failed", HPR_GetLastError());

上記のコードの[0 x%08 x]には、出力をフォーマットするときのフォーマット文字列にこの文が表示される役割があります.形式は
"0x%08x"

このうち、0 xは普通文字で、出力するとそのまま0 xに出力されます.%08 xは整数型で16進数で出力されるフォーマット文字列で、後続の対応パラメータの整数値を16進数で出力します.08の意味は、出力の16進数値が8ビットを占め、不足分は左側が0を補う.そして、実行すると
printf("0x%08x", 0x1234);

0 x 0000 1234が出力されます.
https://www.cnblogs.com/sentakee/p/5630466.html