プロジェクト

全般

プロフィール

SystemLogger.cpp

kawasaki, 2017/11/30 16:55

 
1
// -*- C++ -*-
2
/*!
3
 * @file SystemLogger.cpp
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.cpp 845 2008-09-25 11:10:40Z n-ando $
16
 *
17
 */
18

    
19
#include <rtm/SystemLogger.h>
20
#include <rtm/Manager.h>
21

    
22
#if defined(_MSC_VER)
23
#define snprintf _snprintf
24
#endif
25

    
26
namespace RTC
27
{
28
  const char* Logger::m_levelString[] =
29
    {
30
      " SILENT: ",
31
      " FATAL: ",
32
      " ERROR: ",
33
      " WARNING: ",
34
      " INFO: ",
35
      " DEBUG: ",
36
      " TRACE: ",
37
      " VERBOSE: ",
38
      " PARANOID: "
39
    };
40

    
41
  Logger::Logger(const char* name)
42
    : ::coil::LogStream(&(Manager::instance().getLogStreamBuf()),
43
                        RTL_SILENT, RTL_PARANOID, RTL_SILENT),
44
      m_name(name),
45
      m_dateFormat("%b %d %H:%M:%S.%Q"),
46
      m_clock(&coil::ClockManager::instance().getClock("system")),
47
      m_msEnable(0), m_usEnable(0), m_colorEnable(false)
48
  {
49
    setLevel(Manager::instance().getLogLevel().c_str());
50
    coil::Properties& prop(Manager::instance().getConfig());
51
    if (prop.findNode("logger.date_format") != NULL)
52
      {
53
        setDateFormat(prop["logger.date_format"].c_str());
54
      }
55
    if (prop.findNode("logger.clock_type") != NULL)
56
      {
57
        setClockType(prop["logger.clock_type"]);
58
      }
59
  }
60

    
61
  Logger::Logger(LogStreamBuf* streambuf)
62
    : ::coil::LogStream(streambuf,
63
                        RTL_SILENT, RTL_PARANOID,  RTL_SILENT),
64
      m_name("unknown"),
65
      m_dateFormat("%b %d %H:%M:%S.%Q"),
66
      m_clock(&coil::ClockManager::instance().getClock("system")),
67
      m_msEnable(0), m_usEnable(0), m_colorEnable(false)
68
  {
69
    setDateFormat(m_dateFormat.c_str());
70
  }
71

    
72
  Logger::~Logger(void)
73
  {
74
  }
75

    
76
  /*!
77
   * @if jp
78
   * @brief ログレベルを文字列で設定する
79
   * @else
80
   * @brief Set log level by string
81
   * @endif
82
   */
83
  bool Logger::setLevel(const char* level)
84
  {
85
    return coil::LogStream::setLevel(strToLevel(level));
86
  }
87

    
88
  /*!
89
   * @if jp
90
   * @brief ヘッダに付加する日時フォーマットを指定する。
91
   * @else
92
   * @brief Set date/time format for adding the header
93
   * @endif
94
   */
95
  void Logger::setDateFormat(const char* format)
96
  {
97
    m_dateFormat = std::string(format);
98
    m_msEnable = coil::replaceString(m_dateFormat, "%Q", "#m#");
99
    m_usEnable = coil::replaceString(m_dateFormat, "%q", "#u#");
100
  }
101

    
102
  void Logger::setClockType(std::string clocktype)
103
  {
104
    m_clock = &coil::ClockManager::instance().getClock(clocktype);
105
  }
106
  /*!
107
   * @if jp
108
   * @brief ヘッダの日時の後に付加する文字列を設定する。
109
   * @else
110
   * @brief Set suffix of date/time string of header.
111
   * @endif
112
   */
113
  void Logger::setName(const char* name)
114
  {
115
    m_name = name;
116
  }
117

    
118
  /*!
119
   * @if jp
120
   * @brief カラーモード設定
121
   * カラーモードを有効にする。
122
   * @else
123
   * @brief Enable the color mode
124
   * Enable the color mode.
125
   * @endif
126
   */
127
  void Logger::enableColor()
128
  {
129
    m_colorEnable = true;
130
  }
131

    
132
  /*!
133
   * @if jp
134
   * @brief カラーモード解除
135
   * カラーモードを無効にする。
136
   * @else
137
   * @brief Disable the color mode
138
   * Disable the color mode.
139
   * @endif
140
  */
141
  void Logger::disableColor()
142
  {
143
    m_colorEnable = false;
144
  }
145

    
146
  /*!
147
   * @if jp
148
   * @brief メッセージのプリフィックス追加関数
149
   * @else
150
   * @brief Message prefix appender function
151
   * @endif
152
   */
153
  void Logger::header(int level)
154
  {
155
    const char* color[] =
156
      {
157
        "\x1b[0m",         // SLILENT  (none)
158
        "\x1b[0m\x1b[31m", // FATAL    (red)
159
        "\x1b[0m\x1b[35m", // ERROR    (magenta)
160
        "\x1b[0m\x1b[33m", // WARN     (yellow)
161
        "\x1b[0m\x1b[34m", // INFO     (blue)
162
        "\x1b[0m\x1b[32m", // DEBUG    (green)
163
        "\x1b[0m\x1b[36m", // TRACE    (cyan)
164
        "\x1b[0m\x1b[39m", // VERBOSE  (default)
165
        "\x1b[0m\x1b[37m"  // PARANOID (white)
166
      };
167
    if (m_colorEnable)
168
      {
169
        *this << color[level];
170
      }
171
    *this << getDate() + m_levelString[level] + m_name + ": ";
172
    *this << "\x1b[0m";
173
  }
174

    
175
  /*!
176
   * @if jp
177
   * @brief フォーマットされた現在日時文字列を取得する。
178
   * @else
179
   * @brief Get the current formatted date/time string
180
   * @endif
181
   */
182
  std::string Logger::getDate(void)
183
  {
184
    const int maxsize = 256;
185
    char buf[maxsize];
186
    coil::TimeValue tm(m_clock->gettime());
187

    
188
    time_t timer;
189
    struct tm* date;
190

    
191
    timer = tm.sec();
192
    date = gmtime(&timer);
193
      
194
    strftime(buf, sizeof(buf), m_dateFormat.c_str(), date);
195
    std::string fmt(buf);
196

    
197
    if (m_msEnable > 0)
198
      {
199
        char msec[4];
200
#ifdef WIN32
201
        _snprintf(msec, 4, "%03d", (int)(tm.usec() / 1000));
202
#else
203
        snprintf(msec, 4, "%03d", (int)(tm.usec() / 1000));
204
#endif
205
        coil::replaceString(fmt, "#m#", msec);
206
      }
207
    if (m_usEnable > 0)
208
      {
209
        char usec[4];
210
#ifdef WIN32
211
        _snprintf(usec, 4, "%03d",
212
                 (int)(tm.usec() - ((tm.usec() / 1000) * 1000)));
213
#else
214
        snprintf(usec, 4, "%03d",
215
                 (int)(tm.usec() - ((tm.usec() / 1000) * 1000)));
216
#endif
217
        coil::replaceString(fmt, "#u#", usec);
218
      }
219

    
220
    return fmt;
221
  }
222

    
223
  /*!
224
   * @if jp
225
   * @brief ログレベル設定
226
   * @else
227
   * @brief Set the log level
228
   * @endif
229
   */
230
  int Logger::strToLevel(const char* level)
231
  {
232
    std::string lv(level);
233
    if      (lv == "SILENT")
234
      return RTL_SILENT;
235
    else if (lv == "FATAL")
236
      return RTL_FATAL;
237
    else if (lv == "ERROR")
238
      return RTL_ERROR;
239
    else if (lv == "WARN")
240
      return RTL_WARN;
241
    else if (lv == "INFO")
242
      return RTL_INFO;
243
    else if (lv == "DEBUG")
244
      return RTL_DEBUG;
245
    else if (lv == "TRACE")
246
      return RTL_TRACE;
247
    else if (lv == "VERBOSE")
248
      return RTL_VERBOSE;
249
    else if (lv == "PARANOID")
250
      return RTL_PARANOID;
251
    else
252
      return RTL_SILENT;
253
  }
254

    
255
}; // namespace RTC