33
33
#include < string>
34
34
#include < vector>
35
35
36
- namespace triton { namespace common {
37
-
38
- // A log message.
39
- class LogMessage {
40
- public:
41
- // Log levels.
42
- enum Level { kERROR = 0 , kWARNING = 1 , kINFO = 2 };
36
+ #include " table_printer.h"
37
+ #ifdef _WIN32
38
+ // suppress the min and max definitions in Windef.h.
39
+ #define NOMINMAX
40
+ #include < Windows.h>
41
+ #else
42
+ #include < sys/time.h>
43
+ #include < sys/types.h>
44
+ #include < time.h>
45
+ #include < unistd.h>
46
+ #endif
43
47
44
- LogMessage (const char * file, int line, uint32_t level);
45
- ~LogMessage ();
46
48
47
- std::stringstream& stream () { return stream_; }
49
+ namespace triton { namespace common {
48
50
49
- private:
50
- static const std::vector<char > level_name_;
51
- std::stringstream stream_;
52
- };
53
51
54
52
// Global logger for messages. Controls how log messages are reported.
55
53
class Logger {
56
54
public:
55
+ // Log Formats.
57
56
enum class Format { kDEFAULT , kISO8601 };
58
57
58
+ // Log levels.
59
+ enum class Level : uint8_t { kERROR = 0 , kWARNING = 1 , kINFO = 2 , kEND };
60
+
61
+ inline static const std::array<const char *, static_cast <uint8_t >(Level::kEND )>
62
+ LEVEL_NAMES{" E" , " W" , " I" };
63
+
59
64
Logger ();
60
65
61
66
// Is a log level enabled.
62
- bool IsEnabled (LogMessage::Level level) const { return enables_[level]; }
67
+ bool IsEnabled (Level level) const
68
+ {
69
+ return enables_[static_cast <uint8_t >(level)];
70
+ }
63
71
64
72
// Set enable for a log Level.
65
- void SetEnabled (LogMessage:: Level level, bool enable)
73
+ void SetEnabled (Level level, bool enable)
66
74
{
67
- enables_[level] = enable;
75
+ enables_[static_cast < uint8_t >( level) ] = enable;
68
76
}
69
77
70
78
// Get the current verbose logging level.
@@ -73,6 +81,16 @@ class Logger {
73
81
// Set the current verbose logging level.
74
82
void SetVerboseLevel (uint32_t vlevel) { vlevel_ = vlevel; }
75
83
84
+ // Whether to escape log messages
85
+ // using JSON string escaping rules.
86
+ // Default is true but can be disabled by setting
87
+ // the following environment variable to '0'.
88
+ // If the variable is unset or set to any value !='0'
89
+ // log messages will be escaped
90
+ //
91
+ // TRITON_SERVER_ESCAPE_LOG_MESSAGES=0
92
+ bool EscapeLogMessages () const { return escape_log_messages_; };
93
+
76
94
// Get the logging format.
77
95
Format LogFormat () { return format_; }
78
96
@@ -126,7 +144,10 @@ class Logger {
126
144
void Flush ();
127
145
128
146
private:
129
- std::vector<bool > enables_;
147
+ inline static const char * ESCAPE_ENVIRONMENT_VARIABLE =
148
+ " TRITON_SERVER_ESCAPE_LOG_MESSAGES" ;
149
+ bool escape_log_messages_;
150
+ std::array<bool , static_cast <uint8_t >(Level::kEND )> enables_;
130
151
uint32_t vlevel_;
131
152
Format format_;
132
153
std::mutex mutex_;
@@ -136,15 +157,60 @@ class Logger {
136
157
137
158
extern Logger gLogger_ ;
138
159
139
- #define LOG_ENABLE_INFO (E ) \
140
- triton::common::gLogger_ .SetEnabled( \
141
- triton::common::LogMessage::Level::kINFO , (E))
160
+ // A log message.
161
+ class LogMessage {
162
+ public:
163
+ LogMessage (
164
+ const char * file, int line, Logger::Level level,
165
+ const char * heading = nullptr ,
166
+ bool escape_log_messages = gLogger_ .EscapeLogMessages())
167
+ : path_(file), line_(line), level_(level), pid_(GetProcessId()),
168
+ heading_ (heading), escape_log_messages_(escape_log_messages)
169
+ {
170
+ SetTimestamp ();
171
+ size_t path_start = path_.rfind (' /' );
172
+ if (path_start != std::string::npos) {
173
+ path_ = path_.substr (path_start + 1 , std::string::npos);
174
+ }
175
+ }
176
+
177
+ ~LogMessage ();
178
+
179
+ std::stringstream& stream () { return message_; }
180
+
181
+ private:
182
+ std::string path_;
183
+ const int line_;
184
+ const Logger::Level level_;
185
+ const uint32_t pid_;
186
+ void LogPreamble (std::stringstream& stream);
187
+ void LogTimestamp (std::stringstream& stream);
188
+
189
+ #ifdef _WIN32
190
+ SYSTEMTIME timestamp_;
191
+ void SetTimestamp () { GetSystemTime (×tamp_); }
192
+ static uint32_t GetProcessId ()
193
+ {
194
+ return static_cast <uint32_t >(GetCurrentProcessId ());
195
+ };
196
+ #else
197
+ struct timeval timestamp_;
198
+ void SetTimestamp () { gettimeofday (×tamp_, NULL ); }
199
+ static uint32_t GetProcessId () { return static_cast <uint32_t >(getpid ()); };
200
+ #endif
201
+ std::stringstream message_;
202
+ const char * heading_;
203
+ bool escape_log_messages_;
204
+ };
205
+
206
+ #define LOG_ENABLE_INFO (E ) \
207
+ triton::common::gLogger_ .SetEnabled(triton::common::Logger::Level::kINFO , (E))
142
208
#define LOG_ENABLE_WARNING (E ) \
143
209
triton::common::gLogger_ .SetEnabled( \
144
- triton::common::LogMessage ::Level::kWARNING , (E))
210
+ triton::common::Logger ::Level::kWARNING , (E))
145
211
#define LOG_ENABLE_ERROR (E ) \
146
212
triton::common::gLogger_ .SetEnabled( \
147
- triton::common::LogMessage ::Level::kERROR , (E))
213
+ triton::common::Logger ::Level::kERROR , (E))
148
214
#define LOG_SET_VERBOSE (L ) \
149
215
triton::common::gLogger_ .SetVerboseLevel( \
150
216
static_cast <uint32_t >(std::max(0 , (L))))
@@ -159,12 +225,11 @@ extern Logger gLogger_;
159
225
#ifdef TRITON_ENABLE_LOGGING
160
226
161
227
#define LOG_INFO_IS_ON \
162
- triton::common::gLogger_ .IsEnabled(triton::common::LogMessage::Level::kINFO )
163
- #define LOG_WARNING_IS_ON \
164
- triton::common::gLogger_ .IsEnabled( \
165
- triton::common::LogMessage::Level::kWARNING )
228
+ triton::common::gLogger_ .IsEnabled(triton::common::Logger::Level::kINFO )
229
+ #define LOG_WARNING_IS_ON \
230
+ triton::common::gLogger_ .IsEnabled(triton::common::Logger::Level::kWARNING )
166
231
#define LOG_ERROR_IS_ON \
167
- triton::common::gLogger_ .IsEnabled(triton::common::LogMessage ::Level::kERROR )
232
+ triton::common::gLogger_ .IsEnabled(triton::common::Logger ::Level::kERROR )
168
233
#define LOG_VERBOSE_IS_ON (L ) (triton::common::gLogger_ .VerboseLevel() >= (L))
169
234
170
235
#else
@@ -178,25 +243,25 @@ extern Logger gLogger_;
178
243
#endif // TRITON_ENABLE_LOGGING
179
244
180
245
// Macros that use explicitly given filename and line number.
181
- #define LOG_INFO_FL (FN, LN ) \
182
- if (LOG_INFO_IS_ON) \
183
- triton::common::LogMessage ( \
184
- (char *)(FN), LN, triton::common::LogMessage ::Level::kINFO) \
246
+ #define LOG_INFO_FL (FN, LN ) \
247
+ if (LOG_INFO_IS_ON) \
248
+ triton::common::LogMessage ( \
249
+ (char *)(FN), LN, triton::common::Logger ::Level::kINFO) \
185
250
.stream()
186
- #define LOG_WARNING_FL (FN, LN ) \
187
- if (LOG_WARNING_IS_ON) \
188
- triton::common::LogMessage ( \
189
- (char *)(FN), LN, triton::common::LogMessage ::Level::kWARNING) \
251
+ #define LOG_WARNING_FL (FN, LN ) \
252
+ if (LOG_WARNING_IS_ON) \
253
+ triton::common::LogMessage ( \
254
+ (char *)(FN), LN, triton::common::Logger ::Level::kWARNING) \
190
255
.stream()
191
- #define LOG_ERROR_FL (FN, LN ) \
192
- if (LOG_ERROR_IS_ON) \
193
- triton::common::LogMessage ( \
194
- (char *)(FN), LN, triton::common::LogMessage ::Level::kERROR) \
256
+ #define LOG_ERROR_FL (FN, LN ) \
257
+ if (LOG_ERROR_IS_ON) \
258
+ triton::common::LogMessage ( \
259
+ (char *)(FN), LN, triton::common::Logger ::Level::kERROR) \
195
260
.stream()
196
- #define LOG_VERBOSE_FL (L, FN, LN ) \
197
- if (LOG_VERBOSE_IS_ON(L)) \
198
- triton::common::LogMessage ( \
199
- (char *)(FN), LN, triton::common::LogMessage ::Level::kINFO) \
261
+ #define LOG_VERBOSE_FL (L, FN, LN ) \
262
+ if (LOG_VERBOSE_IS_ON(L)) \
263
+ triton::common::LogMessage ( \
264
+ (char *)(FN), LN, triton::common::Logger ::Level::kINFO) \
200
265
.stream()
201
266
202
267
// Macros that use current filename and line number.
@@ -205,7 +270,50 @@ extern Logger gLogger_;
205
270
#define LOG_ERROR LOG_ERROR_FL (__FILE__, __LINE__)
206
271
#define LOG_VERBOSE (L ) LOG_VERBOSE_FL(L, __FILE__, __LINE__)
207
272
273
+ // Macros for use with triton::common::table_printer objects
274
+ //
275
+ // Data is assumed to be server / backend generated
276
+ // and not for use with client input.
277
+ //
278
+ // Tables are printed without escaping
279
+ #define LOG_TABLE_VERBOSE (L, TABLE ) \
280
+ \
281
+ do { \
282
+ if (LOG_VERBOSE_IS_ON (L)) \
283
+ triton::common::LogMessage ( \
284
+ __FILE__, __LINE__, triton::common::Logger::Level::kINFO , nullptr , \
285
+ false ) \
286
+ .stream () \
287
+ << TABLE.PrintTable (); \
288
+ } while (false )
289
+
290
+ #define LOG_TABLE_INFO (TABLE ) \
291
+ do { \
292
+ if (LOG_INFO_IS_ON) \
293
+ triton::common::LogMessage ( \
294
+ __FILE__, __LINE__, triton::common::Logger::Level::kINFO , nullptr , \
295
+ false ) \
296
+ .stream () \
297
+ << TABLE.PrintTable (); \
298
+ } while (false )
299
+
300
+
301
+ // Macros for use with protobuf messages
302
+ //
303
+ // Data is serialized via DebugString()
304
+ //
305
+ // Data is printed without further escaping
306
+ #define LOG_PROTOBUF_VERBOSE (L, HEADING, PB_MESSAGE ) \
307
+ do { \
308
+ if (LOG_VERBOSE_IS_ON (L)) \
309
+ triton::common::LogMessage ( \
310
+ __FILE__, __LINE__, triton::common::Logger::Level::kINFO , HEADING, \
311
+ false ) \
312
+ .stream () \
313
+ << PB_MESSAGE.DebugString (); \
314
+ } while (false )
208
315
316
+ // Macros for logging errors
209
317
#define LOG_STATUS_ERROR (X, MSG ) \
210
318
do { \
211
319
const Status& status__ = (X); \
0 commit comments