Skip to content

Commit c4f730f

Browse files
authored
Update default log formats to escape messages using JSON encoding rules
1 parent 00b3a71 commit c4f730f

File tree

5 files changed

+255
-116
lines changed

5 files changed

+255
-116
lines changed

include/triton/common/error.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ namespace triton { namespace common {
3636
//
3737
class Error {
3838
public:
39-
enum class Code {
39+
enum class Code : uint8_t {
4040
SUCCESS,
4141
UNKNOWN,
4242
INTERNAL,

include/triton/common/logging.h

Lines changed: 152 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -33,38 +33,46 @@
3333
#include <string>
3434
#include <vector>
3535

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
4347

44-
LogMessage(const char* file, int line, uint32_t level);
45-
~LogMessage();
4648

47-
std::stringstream& stream() { return stream_; }
49+
namespace triton { namespace common {
4850

49-
private:
50-
static const std::vector<char> level_name_;
51-
std::stringstream stream_;
52-
};
5351

5452
// Global logger for messages. Controls how log messages are reported.
5553
class Logger {
5654
public:
55+
// Log Formats.
5756
enum class Format { kDEFAULT, kISO8601 };
5857

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+
5964
Logger();
6065

6166
// 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+
}
6371

6472
// Set enable for a log Level.
65-
void SetEnabled(LogMessage::Level level, bool enable)
73+
void SetEnabled(Level level, bool enable)
6674
{
67-
enables_[level] = enable;
75+
enables_[static_cast<uint8_t>(level)] = enable;
6876
}
6977

7078
// Get the current verbose logging level.
@@ -73,6 +81,16 @@ class Logger {
7381
// Set the current verbose logging level.
7482
void SetVerboseLevel(uint32_t vlevel) { vlevel_ = vlevel; }
7583

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+
7694
// Get the logging format.
7795
Format LogFormat() { return format_; }
7896

@@ -126,7 +144,10 @@ class Logger {
126144
void Flush();
127145

128146
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_;
130151
uint32_t vlevel_;
131152
Format format_;
132153
std::mutex mutex_;
@@ -136,15 +157,60 @@ class Logger {
136157

137158
extern Logger gLogger_;
138159

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(&timestamp_); }
192+
static uint32_t GetProcessId()
193+
{
194+
return static_cast<uint32_t>(GetCurrentProcessId());
195+
};
196+
#else
197+
struct timeval timestamp_;
198+
void SetTimestamp() { gettimeofday(&timestamp_, 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))
142208
#define LOG_ENABLE_WARNING(E) \
143209
triton::common::gLogger_.SetEnabled( \
144-
triton::common::LogMessage::Level::kWARNING, (E))
210+
triton::common::Logger::Level::kWARNING, (E))
145211
#define LOG_ENABLE_ERROR(E) \
146212
triton::common::gLogger_.SetEnabled( \
147-
triton::common::LogMessage::Level::kERROR, (E))
213+
triton::common::Logger::Level::kERROR, (E))
148214
#define LOG_SET_VERBOSE(L) \
149215
triton::common::gLogger_.SetVerboseLevel( \
150216
static_cast<uint32_t>(std::max(0, (L))))
@@ -159,12 +225,11 @@ extern Logger gLogger_;
159225
#ifdef TRITON_ENABLE_LOGGING
160226

161227
#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)
166231
#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)
168233
#define LOG_VERBOSE_IS_ON(L) (triton::common::gLogger_.VerboseLevel() >= (L))
169234

170235
#else
@@ -178,25 +243,25 @@ extern Logger gLogger_;
178243
#endif // TRITON_ENABLE_LOGGING
179244

180245
// 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) \
185250
.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) \
190255
.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) \
195260
.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) \
200265
.stream()
201266

202267
// Macros that use current filename and line number.
@@ -205,7 +270,50 @@ extern Logger gLogger_;
205270
#define LOG_ERROR LOG_ERROR_FL(__FILE__, __LINE__)
206271
#define LOG_VERBOSE(L) LOG_VERBOSE_FL(L, __FILE__, __LINE__)
207272

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)
208315

316+
// Macros for logging errors
209317
#define LOG_STATUS_ERROR(X, MSG) \
210318
do { \
211319
const Status& status__ = (X); \

include/triton/common/triton_json.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,25 @@ class TritonJson {
109109
std::string buffer_;
110110
};
111111

112+
//
113+
// Utility to serialize input string
114+
// as a JSON string value
115+
116+
static std::string SerializeString(const std::string& input)
117+
{
118+
WriteBuffer writebuffer;
119+
const unsigned int writeFlags = rapidjson::kWriteNanAndInfFlag;
120+
// Provide default template arguments to pass writeFlags
121+
rapidjson::Writer<
122+
WriteBuffer, rapidjson::UTF8<>, rapidjson::UTF8<>,
123+
rapidjson::CrtAllocator, writeFlags>
124+
writer(writebuffer);
125+
if (RAPIDJSON_UNLIKELY(!writer.String(input.c_str()))) {
126+
return "Error Serializing String";
127+
}
128+
return writebuffer.Contents();
129+
}
130+
112131
//
113132
// Value representing the entire document or an element within a
114133
// document.

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ target_include_directories(
6666
$<INSTALL_INTERFACE:include>
6767
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
6868
PRIVATE
69+
${RAPIDJSON_INCLUDE_DIRS}
6970
${CMAKE_CURRENT_SOURCE_DIR}
7071
)
7172

0 commit comments

Comments
 (0)