プロジェクト

全般

プロフィール

SystemLogger.h

kawasaki, 2017/11/30 16:55

 
1
// -*- C++ -*-
2
/*!
3
 * @file SystemLogger.h
4
 * @brief RT component logger class
5
 * @date $Date: 2007-07-20 16:10:32 $
6
 * @author Noriaki Ando <n-ando@aist.go.jp>
7
 *
8
 * Copyright (C) 2003-2008
9
 *     Task-intelligence Research Group,
10
 *     Intelligent Systems Research Institute,
11
 *     National Institute of
12
 *         Advanced Industrial Science and Technology (AIST), Japan
13
 *     All rights reserved.
14
 *
15
 * $Id: SystemLogger.h 2311 2012-02-07 02:48:25Z n-ando $
16
 *
17
 */
18

    
19
#ifndef RTC_SYSTEMLOGGER_H
20
#define RTC_SYSTEMLOGGER_H
21

    
22
#include <rtm/config_rtc.h>
23

    
24
// COIL
25
#include <coil/Time.h>
26
#include <coil/ClockManager.h>
27
#include <coil/Logger.h>
28
#include <coil/Mutex.h>
29
#include <coil/Guard.h>
30
#include <coil/stringutil.h>
31

    
32
namespace RTC
33
{
34
  typedef ::coil::LogStreamBuffer LogStreamBuf;
35
  typedef ::coil::LogStream LogStream;
36

    
37
  /*!
38
   * @if jp
39
   * @class Logger
40
   * @brief Logger クラス
41
   *
42
   * - ログ出力をシリアライズしかつ分配するバッファクラス
43
   * - ログをフォーマットするフォーマットクラス
44
   * で構成されるロガークラス
45
   * 
46
   * - バッファクラス
47
   *  - マルチスレッド書き込みに対してシリアライズしてバッファリングする
48
   *  - 複数の出力先にログを出力できる
49
   *  - 出力先の例としては、ファイル、標準出力、リモートのログサーバ等
50
   *  - バッファに対してaddStreamで出力先を追加できる
51
   * - フォーマットクラス
52
   *  - ログレベルを指定して出力できる
53
   *  - 書式は、[時間] [ログレベル] [サフィックス] [メッセージ]
54
   *  - [時間] [ログレベル] [サフィックス]は自動付加
55
   *  - [サフィックス] を指定できる関数を用意
56
   *  - ログレベルは以下のとおり
57
   *   - RTL_SILENT
58
   *   - RTL_FATAL
59
   *   - RTL_ERROR
60
   *   - RTL_WARN
61
   *   - RTL_INFO
62
   *   - RTL_DEBUG
63
   *   - RTL_TRACE
64
   *   - RTL_VERBOSE
65
   *   - RTL_PARANOID
66
   *  - このフォーマットオブジェクトに対するロック・アンロック機能
67
   *
68
   * @else
69
   * @class Logger
70
   * @brief Logger class
71
   *
72
   * This class is composed of the buffer class and the format class. 
73
   * - The buffer class
74
   *  - The buffer class serializes to the MultiThreading writing and 
75
   *    does buffering.
76
   *  - The buffer class can output the log at two or more output destination.
77
   *    As the example of the output destination, filing, the standard, 
78
   *    the log server etc. 
79
   *  - The output destination can be added to the buffer with addStream. 
80
   * - The format class
81
   *  - The format class can output it by specifying the log level. 
82
   *  - The format is [Time] [Loglevel] [Ssuffix] [Message].
83
   *  - [Time] [Loglevel] [Suffix] are added by the automatic operation. 
84
   *  - [Suffix] can be specified. 
85
   *  - Loglevel
86
   *   - RTL_SILENT
87
   *   - RTL_FATAL
88
   *   - RTL_ERROR
89
   *   - RTL_WARN
90
   *   - RTL_INFO
91
   *   - RTL_DEBUG
92
   *   - RTL_TRACE
93
   *   - RTL_VERBOSE
94
   *   - RTL_PARANOID
95
   *  - The format class can be locked/unlocked to this format object. 
96
   *
97
   * @endif
98
   */
99
  class Logger
100
    : public coil::LogStream
101
  {
102
  public:
103
    enum
104
      {              // No: Write out messages include the following.
105
        RTL_SILENT,  // 0: ()
106
        RTL_FATAL,   // 1: (FATAL)
107
        RTL_ERROR,   // 2: (FATAL, ERROR)
108
        RTL_WARN,    // 3: (FATAL, ERROR, WARN)
109
        RTL_INFO,    // 4: (FATAL, ERROR, WARN, INFO)
110
        RTL_DEBUG,   // 5: (FATAL, ERROR, WARN, INFO, DEBUG)
111
        RTL_TRACE,   // 6: (FATAL, ERROR, WARN, INFO, DEBUG, TRACE)
112
        RTL_VERBOSE, // 7: (FATAL, ERROR, WARN, INFO, DEBUG, TRACE, VERBOSE)
113
        RTL_PARANOID // 8: (FATAL, ERROR, WARN, INFO, DEBUG, TRACE, VERBOSE, PARA)
114
      };
115
 
116
    /*!
117
     * @if jp
118
     * @brief コンストラクタ
119
     *
120
     * コンストラクタ
121
     *
122
     * @param name ヘッダの日時の後に付加する文字列
123
     *
124
     * @else
125
     *
126
     * @brief Constructor
127
     *
128
     * Constructor
129
     *
130
     * @param name suffix of date/time string of header.
131
     *
132
     * @endif
133
     */
134
    Logger(const char* name = "");
135
    /*!
136
     * @if jp
137
     * @brief コンストラクタ
138
     *
139
     * コンストラクタ
140
     *
141
     * @param streambuf LogStream オブジェクト 
142
     *
143
     * @else
144
     *
145
     * @brief Constructor
146
     *
147
     * Constructor
148
     *
149
     * @param streambuf LogStream object
150
     *
151
     * @endif
152
     */
153
    Logger(LogStreamBuf* streambuf);
154
    /*!
155
     * @if jp
156
     *
157
     * @brief 仮想デストラクタ
158
     * 
159
     * @else
160
     * 
161
     * @brief Virtual destructor
162
     * 
163
     * @endif
164
     */
165
    virtual ~Logger(void);
166

    
167
    /*!
168
     * @if jp
169
     *
170
     * @brief ログレベルを文字列で設定する
171
     *
172
     * @param level ログレベル
173
     *
174
     * @else
175
     *
176
     * @brief Set log level by string
177
     *
178
     * @param level log level
179
     *
180
     * @endif
181
     */
182
    bool setLevel(const char* level);
183

    
184
    /*!
185
     * @if jp
186
     *
187
     * @brief ヘッダに付加する日時フォーマットを指定する。
188
     *
189
     * フォーマット指定文字列は以下のとおり。
190
     * <pre>
191
     * @%a abbreviated weekday name 
192
     * @%A full weekday name 
193
     * @%b abbreviated month name 
194
     * @%B full month name 
195
     * @%c the standard date and time string 
196
     * @%d day of the month, as a number (1-31) 
197
     * @%H hour, 24 hour format (0-23) 
198
     * @%I hour, 12 hour format (1-12) 
199
     * @%j day of the year, as a number (1-366) 
200
     * @%m month as a number (1-12).
201
     *    Note: some versions of Microsoft Visual C++ may use values that range
202
     *    from 0-11. 
203
     * @%M minute as a number (0-59) 
204
     * @%p locale's equivalent of AM or PM 
205
     * @%Q millisecond as a number (0-999) from ver 1.1
206
     * @%q microsecond as a number (0-999) from ver 1.1
207
     * @%S second as a number (0-59) 
208
     * @%U week of the year, sunday as the first day 
209
     * @%w weekday as a decimal (0-6, sunday=0) 
210
     * @%W week of the year, monday as the first day 
211
     * @%x standard date string 
212
     * @%X standard time string 
213
     * @%y year in decimal, without the century (0-99) 
214
     * @%Y year in decimal, with the century 
215
     * @%Z time zone name 
216
     * %% a percent sign 
217
     * </pre>
218
     *
219
     * @param fmt 日時フォーマット
220
     *
221
     * @else
222
     *
223
     * @brief Set date/time format for adding the header
224
     *
225
     * The format specification string is as follows:
226
     * <pre>
227
     * @%a abbreviated weekday name 
228
     * @%A full weekday name 
229
     * @%b abbreviated month name 
230
     * @%B full month name 
231
     * @%c the standard date and time string 
232
     * @%d day of the month, as a number (1-31) 
233
     * @%H hour, 24 hour format (0-23) 
234
     * @%I hour, 12 hour format (1-12) 
235
     * @%j day of the year, as a number (1-366) 
236
     * @%m month as a number (1-12).
237
     *    Note: some versions of Microsoft Visual C++ may use values that range
238
     *    from 0-11. 
239
     * @%M minute as a number (0-59) 
240
     * @%p locale's equivalent of AM or PM 
241
     * @%Q millisecond as a number (0-999) from ver 1.1
242
     * @%q microsecond as a number (0-999) from ver 1.1
243
     * @%S second as a number (0-59) 
244
     * @%U week of the year, sunday as the first day 
245
     * @%w weekday as a decimal (0-6, sunday=0) 
246
     * @%W week of the year, monday as the first day 
247
     * @%x standard date string 
248
     * @%X standard time string 
249
     * @%y year in decimal, without the century (0-99) 
250
     * @%Y year in decimal, with the century 
251
     * @%Z time zone name 
252
     * %% a percent sign 
253
     * </pre>
254
     *
255
     * @param fmt Datetime format
256
     *
257
     * @endif
258
     */
259
    void setDateFormat(const char* format);
260

    
261
    /*!
262
     * @if jp
263
     *
264
     * @brief ログ記録時に使用するクロックを指定する
265
     *
266
     * ログ記録時に時刻を取得するためのクロックの種類を指定することができる。
267
     * - system: システムクロック。デフォルト
268
     * - logical: 論理時間クロック。
269
     * - adjusted: 調整済みクロック。
270
     *
271
     * 論理時間クロックについては
272
     * <pre>
273
     * coil::ClockManager::instance().getClock("logical").settime()
274
     * </pre>
275
     * で時刻を設定する必要がある。
276
     *
277
     * @param clocktype 上述のクロックタイプ
278
     *
279
     * @else
280
     *
281
     * @brief Specifying clock type to be used for logging
282
     *
283
     * This function sets a clock type getting time when it is used
284
     * for logging. Available clock types are,
285
     * - system: System clock. Default option.
286
     * - logical: Logical time clock.
287
     * - adjusted: Adjusted clock.
288
     *
289
     * To use logical time clock, call and set time by the following
290
     * function in somewhere.
291
     * <pre>
292
     * coil::ClockManager::instance().getClock("logical").settime()
293
     * </pre>
294
     *
295
     * @param clocktype A clock type above mentioned
296
     *
297
     * @endif
298
     */
299
    void setClockType(std::string clocktype);
300

    
301
    /*!
302
     * @if jp
303
     *
304
     * @brief ヘッダの日時の後に付加する文字列を設定する。
305
     *
306
     * ヘッダの日時の後に付加する接頭語文字列を設定する。
307
     *
308
     * @param suffix 接頭語文字列
309
     *
310
     * @else
311
     *
312
     * @brief Set suffix of date/time string of header.
313
     *
314
     * Set the suffix string added after the datatime of the header.
315
     *
316
     * @param suffix Suffix string
317
     *
318
     * @endif
319
     */
320
    void setName(const char* name);
321

    
322
    /*!
323
     * @if jp
324
     *
325
     * @brief カラーモード設定
326
     *
327
     * @else
328
     *
329
     * @brief Enable the color mode
330
     *
331
     * Enable the color mode.
332
     *
333
     * @endif
334
     */
335
    void enableColor();
336

    
337
    /*!
338
     * @if jp
339
     *
340
     * @brief カラーモード解除
341
     *
342
     * @else
343
     *
344
     * @brief Disable the color mode
345
     *
346
     * Disable the color mode.
347
     *
348
     * @endif
349
     */
350
    void disableColor();
351

    
352
  protected:
353
    /*!
354
     * @if jp
355
     *
356
     * @brief メッセージのプリフィックス追加関数
357
     *
358
     * サブクラスにおいてこの関数をオーバーライドし、
359
     * ログメッセージに適当なプリフィックスるを追加する。
360
     *
361
     * @else
362
     *
363
     * @brief Message prefix appender function
364
     *
365
     * Subclasses of this class should override this operation, and
366
     * this function should be defined to append some prefix to the
367
     * log messages.
368
     *
369
     * @endif
370
     */
371
    virtual void header(int level);
372

    
373
    /*!
374
     * @if jp
375
     * @brief フォーマットされた現在日時文字列を取得する。
376
     * 指定された書式で記述した現在日時を取得する。
377
     *
378
     * @return 書式指定現在日時
379
     *
380
     * @else
381
     * @brief Get the current formatted date/time string
382
     * Get the current datetime described by specified format.
383
     *
384
     * @return Format specification current datetime
385
     *
386
     * @endif
387
     */
388
    std::string getDate(void);
389

    
390
    /*!
391
     * @if jp
392
     * @brief ログレベル設定
393
     * 与えられた文字列に対応したログレベルを設定する。
394
     *
395
     * @param lv ログレベル文字列
396
     * @return 設定したログレベル
397
     *
398
     * @else
399
     * @brief Set the log level
400
     * Set the log level corresponding to the given string.
401
     *
402
     * @param lv Log level string
403
     * @return The set log level
404
     *
405
     * @endif
406
     */
407
    int strToLevel(const char* level);
408

    
409
  private:
410
    std::string m_name;
411
    std::string m_dateFormat;
412
    coil::IClock* m_clock;
413
    static const char* m_levelString[];
414
    int m_msEnable;
415
    int m_usEnable;
416

    
417
    /*!
418
     * @if jp
419
     * @brief カラー有効モード
420
     * @else
421
     * @brief Color enable mode
422
     * @endif
423
     */
424
    bool m_colorEnable;
425
  };    
426

    
427

    
428
#ifndef NO_LOGGING
429
/*!
430
 * @if jp
431
 *
432
 * @brief 汎用ログ出力マクロ
433
 *
434
 * ログレベルおよび出力フォーマット文字列を引数としてとる。
435
 *
436
 * @else
437
 *
438
 * @brief General-purpose log output macro
439
 *
440
 * Lock log level and output format string as arguments.
441
 *
442
 * @endif
443
 */
444
#define RTC_LOG(LV, fmt)                                    \
445
  if (rtclog.isValid(LV))                                   \
446
    {                                                       \
447
      std::string str = ::coil::sprintf fmt;                \
448
      rtclog.lock();                                        \
449
      rtclog.level(LV) << str << std::endl; \
450
      rtclog.unlock();                                      \
451
    }
452

    
453
#define RTC_LOG_STR(LV, str)                                    \
454
  if (rtclog.isValid(LV))                                   \
455
    {                                                       \
456
      rtclog.lock();                                        \
457
      rtclog.level(LV) << str << std::endl;  \
458
      rtclog.unlock();                                      \
459
    }
460

    
461
   /*!
462
   * @if jp
463
   *
464
   * @brief エラーログ出力マクロ。
465
   *
466
   * エラーレベルのログ出力マクロ。<BR>ログレベルが
467
   * ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID
468
   * の場合にログ出力される。
469
   *
470
   * @else
471
   *
472
   * @brief Error log output macro
473
   *
474
   * This is a log output macro of the error level.
475
   * If log levels are ERROR, WARN, INFO, NORMAL, DEBUG, TRACE,
476
   * VERBOSE or PARANOID, message will be output to log.
477
   *
478
   * @endif
479
   */
480
#define RTC_FATAL(fmt) RTC_LOG(::RTC::Logger::RTL_FATAL, fmt)
481
#define RTC_FATAL_STR(str) RTC_LOG_STR(::RTC::Logger::RTL_FATAL, str)
482
 
483
  /*!
484
   * @if jp
485
   *
486
   * @brief エラーログ出力マクロ。
487
   *
488
   * エラーレベルのログ出力マクロ。<BR>ログレベルが
489
   * ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID
490
   * の場合にログ出力される。
491
   *
492
   * @else
493
   *
494
   * @brief Error log output macro
495
   *
496
   * This is a log output macro of the error level.
497
   * If log levels are ERROR, WARN, INFO, NORMAL, DEBUG, TRACE,
498
   * VERBOSE or PARANOID, message will be output to log.
499
   *
500
   * @endif
501
   */
502
#define RTC_ERROR(fmt) RTC_LOG(::RTC::Logger::RTL_ERROR, fmt)
503
#define RTC_ERROR_STR(str) RTC_LOG_STR(::RTC::Logger::RTL_ERROR, str)
504
  
505
  /*!
506
   * @if jp
507
   *
508
   * @brief ワーニングログ出力マクロ。
509
   *
510
   * ワーニングレベルのログ出力マクロ。<BR>ログレベルが
511
   * ( WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID )
512
   * の場合にログ出力される。
513
   *
514
   * @else
515
   *
516
   * @brief Warning log output macro
517
   *
518
   * If log levels are
519
   * ( WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID ),
520
   * message will be output to log.
521
   *
522
   * @endif
523
   */
524
#define RTC_WARN(fmt) RTC_LOG(::RTC::Logger::RTL_WARN, fmt)
525
#define RTC_WARN_STR(str) RTC_LOG_STR(::RTC::Logger::RTL_WARN, str)
526
  
527
  /*!
528
   * @if jp
529
   *
530
   * @brief インフォログ出力マクロ。
531
   *
532
   * インフォレベルのログ出力マクロ。<BR>ログレベルが
533
   * ( INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID )
534
   * の場合にログ出力される。
535
   *
536
   * @else
537
   *
538
   * @brief Information level log output macro
539
   *
540
   *  If log levels are
541
   * ( INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID ),
542
   * message will be output to log.
543
   *
544
   * @endif
545
   */
546
#define RTC_INFO(fmt) RTC_LOG(::RTC::Logger::RTL_INFO, fmt)
547
#define RTC_INFO_STR(str) RTC_LOG_STR(::RTC::Logger::RTL_INFO, str)
548

    
549
  /*!
550
   * @if jp
551
   *
552
   * @brief デバッグログ出力マクロ。
553
   *
554
   * デバッグレベルのログ出力マクロ。<BR>ログレベルが
555
   * ( DEBUG, TRACE, VERBOSE, PARANOID )
556
   * の場合にログ出力される。
557
   *
558
   * @else
559
   *
560
   * @brief Debug level log output macro.
561
   *
562
   * If log levels are
563
   * ( DEBUG, TRACE, VERBOSE, PARANOID ),
564
   * message will be output to log.
565
   *
566
   * @endif
567
   */
568
#define RTC_DEBUG(fmt) RTC_LOG(::RTC::Logger::RTL_DEBUG, fmt)
569
#define RTC_DEBUG_STR(str) RTC_LOG_STR(::RTC::Logger::RTL_DEBUG, str)
570
  
571
  /*!
572
   * @if jp
573
   *
574
   * @brief トレースログ出力マクロ。
575
   *
576
   * トレースレベルのログ出力マクロ。<BR>ログレベルが
577
   * ( TRACE, VERBOSE, PARANOID )
578
   * の場合にログ出力される。
579
   *
580
   * @else
581
   *
582
   * @brief Trace level log output macro.
583
   *
584
   * If log levels are
585
   * ( TRACE, VERBOSE, PARANOID ),
586
   * message will be output to log.
587
   *
588
   * @endif
589
   */
590
#define RTC_TRACE(fmt) RTC_LOG(::RTC::Logger::RTL_TRACE, fmt)
591
#define RTC_TRACE_STR(str) RTC_LOG_STR(::RTC::Logger::RTL_TRACE, str)
592

    
593

    
594
  /*!
595
   * @if jp
596
   *
597
   * @brief ベルボーズログ出力マクロ。
598
   *
599
   * ベルボーズレベルのログ出力マクロ。<BR>ログレベルが
600
   * ( VERBOSE, PARANOID )
601
   * の場合にログ出力される。
602
   *
603
   * @else
604
   *
605
   * @brief Verbose level log output macro.
606
   *
607
   * If log levels are
608
   * ( VERBOSE, PARANOID ),
609
   * message will be output to log.
610
   *
611
   * @endif
612
   */
613
#define RTC_VERBOSE(fmt) RTC_LOG(::RTC::Logger::RTL_VERBOSE, fmt)
614
#define RTC_VERBOSE_STR(str) RTC_LOG_STR(::RTC::Logger::RTL_VERBOSE, str)
615
  
616
  /*!
617
   * @if jp
618
   *
619
   * @brief パラノイドログ出力マクロ。
620
   *
621
   * パラノイドレベルのログ出力マクロ。<BR>ログレベルが
622
   * ( PARANOID )
623
   * の場合にログ出力される。
624
   *
625
   * @else
626
   *
627
   * @brief Paranoid level log output macro.
628
   *
629
   * If log levels are
630
   * ( PARANOID ),
631
   * message will be output to log.
632
   *
633
   * @endif
634
   */
635
#define RTC_PARANOID(fmt) RTC_LOG(::RTC::Logger::RTL_PARANOID, fmt)
636
#define RTC_PARANOID_STR(str) RTC_LOG_STR(::RTC::Logger::RTL_PARANOID, str)
637
  
638
#else
639
#define RTC_ERROR(fmt)
640
#define RTC_ERROR_STR(str)
641
#define RTC_WARN(fmt)
642
#define RTC_WARN_STR(str)
643
#define RTC_NORMAL(fmt)
644
#define RTC_NORMAL_STR(str)
645
#define RTC_INFO(fmt)
646
#define RTC_INFO_STR(str)
647
#define RTC_DEBUG(fmt)
648
#define RTC_DEBUG_STR(str)
649
#define RTC_TRACE(fmt)
650
#define RTC_TRACE_STR(str)
651
#define RTC_VERBOSE(fmt)
652
#define RTC_VERBOSE_STR(str)
653
#define RTC_PARANOID(fmt)
654
#define RTC_PARANOID_STR(str)
655
#endif
656
  
657
}; // namespace RTC
658

    
659
#endif  // RTC_SYSTEMLOGGER_H