Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

json log format #115

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/triton/common/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace triton { namespace common {
//
class Error {
public:
enum class Code {
enum class Code : uint8_t {
SUCCESS,
UNKNOWN,
INTERNAL,
Expand Down
221 changes: 175 additions & 46 deletions include/triton/common/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,46 +33,50 @@
#include <string>
#include <vector>

namespace triton { namespace common {

// A log message.
class LogMessage {
public:
// Log levels.
enum Level { kERROR = 0, kWARNING = 1, kINFO = 2 };

LogMessage(const char* file, int line, uint32_t level);
~LogMessage();
#include "table_printer.h"
#ifdef _WIN32
// suppress the min and max definitions in Windef.h.
#define NOMINMAX
#include <Windows.h>
#else
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#endif

std::stringstream& stream() { return stream_; }

private:
static const std::vector<char> level_name_;
std::stringstream stream_;
};
namespace triton { namespace common {

// Global logger for messages. Controls how log messages are reported.
class Logger {
public:
// Log Formats.
enum class Format { kDEFAULT, kISO8601 };

// Log levels.
enum Level { kERROR = 0, kWARNING = 1, kINFO = 2, kEND };

Logger();

// Is a log level enabled.
bool IsEnabled(LogMessage::Level level) const { return enables_[level]; }
bool IsEnabled(Level level) const { return enables_[level]; }

// Set enable for a log Level.
void SetEnabled(LogMessage::Level level, bool enable)
{
enables_[level] = enable;
}
void SetEnabled(Level level, bool enable) { enables_[level] = enable; }

// Get the current verbose logging level.
uint32_t VerboseLevel() const { return vlevel_; }

// Set the current verbose logging level.
void SetVerboseLevel(uint32_t vlevel) { vlevel_ = vlevel; }

// Whether to escape log messages
// using JSON string escaping rules.
// Default is true but can be disabled via an environment variable
// TRITONSERVER_ESCAPE_LOG_MESSAGES
bool EscapeLogMessages() const { return escape_log_messages_; };

// Get the logging format.
Format LogFormat() { return format_; }

Expand Down Expand Up @@ -125,7 +129,10 @@ class Logger {
// Flush the log.
void Flush();

static const std::array<const char*, Level::kINFO + 1> LEVEL_NAMES;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should have defined Level:kEND then use it instead of Level::kINFO + 1, easy to miss if someone adds new log level and doesn't change there.


private:
bool escape_log_messages_;
std::vector<bool> enables_;
uint32_t vlevel_;
Format format_;
Expand All @@ -136,15 +143,64 @@ class Logger {

extern Logger gLogger_;

#define LOG_ENABLE_INFO(E) \
triton::common::gLogger_.SetEnabled( \
triton::common::LogMessage::Level::kINFO, (E))
// A log message.
class LogMessage {
public:
LogMessage(const char* file, int line, uint32_t level)
: path_(file), line_(line),
level_(std::min(level, (uint32_t)Logger::Level::kINFO)),
pid_(GetProcessId()), escape_log_messages_(gLogger_.EscapeLogMessages())
{
SetTimestamp();
size_t path_start = path_.rfind('/');
if (path_start != std::string::npos) {
path_ = path_.substr(path_start + 1, std::string::npos);
}
}

LogMessage(
const char* file, int line, uint32_t level, bool escape_log_messages)
: LogMessage(file, line, level)
{
escape_log_messages_ = escape_log_messages;
}

~LogMessage();

std::stringstream& stream() { return message_; }

private:
std::string path_;
const int line_;
const uint32_t level_;
const uint32_t pid_;
void LogPreamble(std::stringstream& stream);
void LogTimestamp(std::stringstream& stream);

#ifdef _WIN32
SYSTEMTIME timestamp_;
void SetTimestamp() { GetSystemTime(&timestamp_); }
static uint32_t GetProcessId()
{
return static_cast<uint32_t>(GetCurrentProcessId());
};
#else
struct timeval timestamp_;
void SetTimestamp() { gettimeofday(&timestamp_, NULL); }
static uint32_t GetProcessId() { return static_cast<uint32_t>(getpid()); };
#endif
std::stringstream message_;
bool escape_log_messages_;
};

#define LOG_ENABLE_INFO(E) \
triton::common::gLogger_.SetEnabled(triton::common::Logger::Level::kINFO, (E))
#define LOG_ENABLE_WARNING(E) \
triton::common::gLogger_.SetEnabled( \
triton::common::LogMessage::Level::kWARNING, (E))
triton::common::Logger::Level::kWARNING, (E))
#define LOG_ENABLE_ERROR(E) \
triton::common::gLogger_.SetEnabled( \
triton::common::LogMessage::Level::kERROR, (E))
triton::common::Logger::Level::kERROR, (E))
#define LOG_SET_VERBOSE(L) \
triton::common::gLogger_.SetVerboseLevel( \
static_cast<uint32_t>(std::max(0, (L))))
Expand All @@ -159,12 +215,11 @@ extern Logger gLogger_;
#ifdef TRITON_ENABLE_LOGGING

#define LOG_INFO_IS_ON \
triton::common::gLogger_.IsEnabled(triton::common::LogMessage::Level::kINFO)
#define LOG_WARNING_IS_ON \
triton::common::gLogger_.IsEnabled( \
triton::common::LogMessage::Level::kWARNING)
triton::common::gLogger_.IsEnabled(triton::common::Logger::Level::kINFO)
#define LOG_WARNING_IS_ON \
triton::common::gLogger_.IsEnabled(triton::common::Logger::Level::kWARNING)
#define LOG_ERROR_IS_ON \
triton::common::gLogger_.IsEnabled(triton::common::LogMessage::Level::kERROR)
triton::common::gLogger_.IsEnabled(triton::common::Logger::Level::kERROR)
#define LOG_VERBOSE_IS_ON(L) (triton::common::gLogger_.VerboseLevel() >= (L))

#else
Expand All @@ -178,33 +233,107 @@ extern Logger gLogger_;
#endif // TRITON_ENABLE_LOGGING

// Macros that use explicitly given filename and line number.
#define LOG_INFO_FL(FN, LN) \
if (LOG_INFO_IS_ON) \
triton::common::LogMessage( \
(char*)(FN), LN, triton::common::LogMessage::Level::kINFO) \
#define LOG_INFO_FL(FN, LN) \
if (LOG_INFO_IS_ON) \
triton::common::LogMessage( \
(char*)(FN), LN, triton::common::Logger::Level::kINFO) \
.stream()
#define LOG_WARNING_FL(FN, LN) \
if (LOG_WARNING_IS_ON) \
triton::common::LogMessage( \
(char*)(FN), LN, triton::common::LogMessage::Level::kWARNING) \
#define LOG_WARNING_FL(FN, LN) \
if (LOG_WARNING_IS_ON) \
triton::common::LogMessage( \
(char*)(FN), LN, triton::common::Logger::Level::kWARNING) \
.stream()
#define LOG_ERROR_FL(FN, LN) \
if (LOG_ERROR_IS_ON) \
triton::common::LogMessage( \
(char*)(FN), LN, triton::common::LogMessage::Level::kERROR) \
#define LOG_ERROR_FL(FN, LN) \
if (LOG_ERROR_IS_ON) \
triton::common::LogMessage( \
(char*)(FN), LN, triton::common::Logger::Level::kERROR) \
.stream()
#define LOG_VERBOSE_FL(L, FN, LN) \
if (LOG_VERBOSE_IS_ON(L)) \
triton::common::LogMessage( \
(char*)(FN), LN, triton::common::LogMessage::Level::kINFO) \
#define LOG_VERBOSE_FL(L, FN, LN) \
if (LOG_VERBOSE_IS_ON(L)) \
triton::common::LogMessage( \
(char*)(FN), LN, triton::common::Logger::Level::kINFO) \
.stream()

#define LOG_JSON_INFO_FL(FN, LN, PREAMBLE, JSON_CHAR_PTR, SIZE) \
\
do { \
if (LOG_INFO_IS_ON) \
triton::common::LogMessage( \
(char*)(FN), LN, triton::common::Logger::Level::kINFO, false) \
.stream() \
<< PREAMBLE << '\n' \
<< std::string({JSON_CHAR_PTR, SIZE}); \
} while (false)

#define LOG_JSON_WARNING_FL(FN, LN, PREAMBLE, JSON_CHAR_PTR, SIZE) \
\
do { \
if (LOG_WARNING_IS_ON) \
triton::common::LogMessage( \
(char*)(FN), LN, triton::common::Logger::Level::kWARNING, false) \
.stream() \
<< PREAMBLE << '\n' \
<< std::string({JSON_CHAR_PTR, SIZE}); \
} while (false)

#define LOG_JSON_ERROR_FL(FN, LN, PREAMBLE, JSON_CHAR_PTR, SIZE) \
\
do { \
if (LOG_ERROR_IS_ON) \
triton::common::LogMessage( \
(char*)(FN), LN, triton::common::Logger::Level::kERROR, false) \
.stream() \
<< PREAMBLE << '\n' \
<< std::string({JSON_CHAR_PTR, SIZE}); \
} while (false)

#define LOG_JSON_VERBOSE_FL(L, FN, LN, PREAMBLE, JSON_CHAR_PTR, SIZE) \
\
do { \
if (LOG_VERBOSE_IS_ON(L)) \
triton::common::LogMessage( \
(char*)(FN), LN, triton::common::Logger::Level::kINFO, false) \
.stream() \
<< PREAMBLE << '\n' \
<< std::string({JSON_CHAR_PTR, SIZE}); \
} while (false)


// Macros that use current filename and line number.
#define LOG_INFO LOG_INFO_FL(__FILE__, __LINE__)
#define LOG_WARNING LOG_WARNING_FL(__FILE__, __LINE__)
#define LOG_ERROR LOG_ERROR_FL(__FILE__, __LINE__)
#define LOG_VERBOSE(L) LOG_VERBOSE_FL(L, __FILE__, __LINE__)

#define LOG_TABLE_VERBOSE(L, TABLE) \
\
do { \
if (LOG_VERBOSE_IS_ON(L)) \
triton::common::LogMessage( \
__FILE__, __LINE__, triton::common::Logger::Level::kINFO, false) \
.stream() \
<< TABLE.PrintTable(); \
} while (false)

#define LOG_PROTOBUF_VERBOSE(L, PREAMBLE, PB_MESSAGE) \
\
do { \
if (LOG_VERBOSE_IS_ON(L)) \
triton::common::LogMessage( \
__FILE__, __LINE__, triton::common::Logger::Level::kINFO, false) \
.stream() \
<< PREAMBLE << '\n' \
<< PB_MESSAGE.DebugString(); \
} while (false)

#define LOG_TABLE_INFO(TABLE) \
do { \
if (LOG_INFO_IS_ON) \
triton::common::LogMessage( \
__FILE__, __LINE__, triton::common::Logger::Level::kINFO, false) \
.stream() \
<< TABLE.PrintTable(); \
} while (false)

#define LOG_STATUS_ERROR(X, MSG) \
do { \
Expand Down
21 changes: 21 additions & 0 deletions include/triton/common/triton_json.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once


#ifdef _WIN32
// Remove GetObject definition from windows.h, which prevents calls to
// RapidJSON's GetObject.
Expand Down Expand Up @@ -109,6 +110,26 @@ class TritonJson {
std::string buffer_;
};

//
// Utility to return an escaped version of the
// input string
//

static std::string EscapeString(const std::string& input)
{
WriteBuffer writebuffer;
const unsigned int writeFlags = rapidjson::kWriteNanAndInfFlag;
// Provide default template arguments to pass writeFlags
rapidjson::Writer<
WriteBuffer, rapidjson::UTF8<>, rapidjson::UTF8<>,
rapidjson::CrtAllocator, writeFlags>
writer(writebuffer);
if (RAPIDJSON_UNLIKELY(!writer.String(input.c_str()))) {
return "Error Escaping String";
}
return writebuffer.Contents();
}

//
// Value representing the entire document or an element within a
// document.
Expand Down
Loading
Loading