Skip to content

Commit

Permalink
Merge pull request google#554 from santigl/santigl/custom-prefixer
Browse files Browse the repository at this point in the history
Add support for customizing the prefix format
  • Loading branch information
sergiud authored Apr 9, 2021
2 parents 663bb26 + 0cbc235 commit 7d4eeb1
Show file tree
Hide file tree
Showing 6 changed files with 1,844 additions and 15 deletions.
16 changes: 16 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ set (CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
option (BUILD_SHARED_LIBS "Build shared libraries" ON)
option (PRINT_UNSYMBOLIZED_STACK_TRACES
"Print file offsets in traces instead of symbolizing" OFF)
option (WITH_CUSTOM_PREFIX "Enable support for user-generated message prefixes" OFF)
option (WITH_GFLAGS "Use gflags" ON)
option (WITH_GTEST "Use googletest" ON)
option (WITH_PKGCONFIG "Enable pkg-config support" ON)
Expand Down Expand Up @@ -599,6 +600,10 @@ if (WIN32)
target_compile_definitions (glog PUBLIC GLOG_NO_ABBREVIATED_SEVERITIES)
endif (WIN32)

if (WITH_CUSTOM_PREFIX)
target_compile_definitions(glog PUBLIC GLOG_CUSTOM_PREFIX_SUPPORT)
endif (WITH_CUSTOM_PREFIX)

set_target_properties (glog PROPERTIES PUBLIC_HEADER "${GLOG_PUBLIC_H}")

target_include_directories (glog BEFORE PUBLIC
Expand Down Expand Up @@ -635,6 +640,17 @@ if (BUILD_TESTING)

target_link_libraries (logging_unittest PRIVATE ${_GLOG_TEST_LIBS})

if (WITH_CUSTOM_PREFIX)
add_executable (logging_custom_prefix_unittest
src/logging_custom_prefix_unittest.cc
)

target_link_libraries (logging_custom_prefix_unittest PRIVATE ${_GLOG_TEST_LIBS})

add_test (NAME logging_custom_prefix
COMMAND logging_custom_prefix_unittest)
endif (WITH_CUSTOM_PREFIX)

add_executable (stl_logging_unittest
src/stl_logging_unittest.cc
)
Expand Down
47 changes: 46 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ glog defines a series of macros that simplify many common logging tasks.
You can log messages by severity level, control logging behavior from
the command line, log based on conditionals, abort the program when
expected conditions are not met, introduce your own verbose logging
levels, and more.
levels, customize the prefix attached to log messages, and more.

Following sections describe the functionality supported by glog. Please note
this description may not be complete but limited to the most useful ones. If you
Expand Down Expand Up @@ -516,6 +516,51 @@ severity level.
" than 1024, when you run the program with --v=1 or more. ";
"Present occurence is " << google::COUNTER;
Custom log prefix format
~~~~~~~~~~~~~~~~~~~~~~~~

glog supports changing the format of the prefix attached to log messages by
receiving a user-provided callback to be used to generate such strings. That
feature must be enabled at compile time by the ``WITH_CUSTOM_PREFIX`` flag.

For each log entry, the callback will be invoked with a ``LogMessageInfo``
struct containing the severity, filename, line number, thread ID, and time of
the event. It will also be given a reference to the output stream, whose
contents will be prepended to the actual message in the final log line.

For example:

.. code:: cpp
/* This function writes a prefix that matches glog's default format.
* (The third parameter can be used to receive user-supplied data, and is
* NULL by default.)
*/
void CustomPrefix(std::ostream &s, const LogMessageInfo &l, void*) {
s << l.severity[0]
<< setw(4) << 1900 + l.time.year()
<< setw(2) << 1 + l.time.month()
<< setw(2) << l.time.day()
<< ' '
<< setw(2) << l.time.hour() << ':'
<< setw(2) << l.time.min() << ':'
<< setw(2) << l.time.sec() << "."
<< setw(6) << l.time.usec()
<< ' '
<< setfill(' ') << setw(5)
<< l.thread_id << setfill('0')
<< ' '
<< l.filename << ':' << l.line_number << "]";
}
To enable the use of ``CustomPrefix()``, simply give glog a pointer to it
during initialization: ``InitGoogleLogging(argv[0], &CustomPrefix);``.

Optionally, ``InitGoogleLogging()`` takes a third argument of type ``void*``
to pass on to the callback function.

Failure Signal Handler
~~~~~~~~~~~~~~~~~~~~~~

Expand Down
50 changes: 50 additions & 0 deletions src/glog/logging.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,50 @@ typedef unsigned __int64 uint64;

@ac_google_end_namespace@

#ifdef GLOG_CUSTOM_PREFIX_SUPPORT
struct LogMessageTime {
explicit LogMessageTime (const struct::tm& time_struct_,
const time_t& timestamp_, const int32_t& usecs_):
time_struct(time_struct_), ts(timestamp_), usecs(usecs_) {}

const time_t& timestamp() const { return ts; }
const int& sec() const { return time_struct.tm_sec; }
const int32_t& usec() const { return usecs; }
const int& min() const { return time_struct.tm_min; }
const int& hour() const { return time_struct.tm_hour; }
const int& day() const { return time_struct.tm_mday; }
const int& month() const { return time_struct.tm_mon; }
const int& year() const { return time_struct.tm_year; }
const int& dayOfWeek() const { return time_struct.tm_wday; }
const int& dayInYear() const { return time_struct.tm_yday; }
const int& dst() const { return time_struct.tm_isdst; }

private:
const struct::tm& time_struct;
const time_t& ts;
const int32_t& usecs;
};

struct LogMessageInfo {
explicit LogMessageInfo(const char* const severity_,
const char* const filename_,
const int& line_number_,
const int& thread_id_,
const LogMessageTime& time_):
severity(severity_), filename(filename_), line_number(line_number_),
thread_id(thread_id_), time(time_)
{}

const char* const severity;
const char* const filename;
const int &line_number;
const int &thread_id;
const LogMessageTime& time;
};

typedef void(*CustomPrefixCallback)(std::ostream& s, const LogMessageInfo& l, void* data);
#endif

// The global value of GOOGLE_STRIP_LOG. All the messages logged to
// LOG(XXX) with severity less than GOOGLE_STRIP_LOG will not be displayed.
// If it can be determined at compile time that the message will not be
Expand Down Expand Up @@ -535,6 +579,12 @@ DECLARE_bool(log_utc_time);
// specified by argv0 in log outputs.
GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0);

#ifdef GLOG_CUSTOM_PREFIX_SUPPORT
GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0,
CustomPrefixCallback prefix_callback,
void* prefix_callback_data = NULL);
#endif

// Shutdown google's logging library.
GOOGLE_GLOG_DLL_DECL void ShutdownGoogleLogging();

Expand Down
64 changes: 50 additions & 14 deletions src/logging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,15 @@ static bool SendEmailInternal(const char*dest, const char *subject,
base::Logger::~Logger() {
}

#ifdef GLOG_CUSTOM_PREFIX_SUPPORT
namespace {
// Optional user-configured callback to print custom prefixes.
CustomPrefixCallback custom_prefix_callback = NULL;
// User-provided data to pass to the callback:
void* custom_prefix_callback_data = NULL;
}
#endif

namespace {

// Encapsulates all file-system related state
Expand Down Expand Up @@ -1593,20 +1602,37 @@ void LogMessage::Init(const char* file,
// (log level, GMT year, month, date, time, thread_id, file basename, line)
// We exclude the thread_id for the default thread.
if (FLAGS_log_prefix && (line != kNoLogPrefix)) {
stream() << LogSeverityNames[severity][0]
<< setw(4) << 1900+data_->tm_time_.tm_year
<< setw(2) << 1+data_->tm_time_.tm_mon
<< setw(2) << data_->tm_time_.tm_mday
<< ' '
<< setw(2) << data_->tm_time_.tm_hour << ':'
<< setw(2) << data_->tm_time_.tm_min << ':'
<< setw(2) << data_->tm_time_.tm_sec << "."
<< setw(6) << data_->usecs_
<< ' '
<< setfill(' ') << setw(5)
<< static_cast<unsigned int>(GetTID()) << setfill('0')
<< ' '
<< data_->basename_ << ':' << data_->line_ << "] ";
#ifdef GLOG_CUSTOM_PREFIX_SUPPORT
if (custom_prefix_callback == NULL) {
#endif
stream() << LogSeverityNames[severity][0]
<< setw(4) << 1900+data_->tm_time_.tm_year
<< setw(2) << 1+data_->tm_time_.tm_mon
<< setw(2) << data_->tm_time_.tm_mday
<< ' '
<< setw(2) << data_->tm_time_.tm_hour << ':'
<< setw(2) << data_->tm_time_.tm_min << ':'
<< setw(2) << data_->tm_time_.tm_sec << "."
<< setw(6) << data_->usecs_
<< ' '
<< setfill(' ') << setw(5)
<< static_cast<unsigned int>(GetTID()) << setfill('0')
<< ' '
<< data_->basename_ << ':' << data_->line_ << "] ";
#ifdef GLOG_CUSTOM_PREFIX_SUPPORT
} else {
custom_prefix_callback(
stream(),
LogMessageInfo(LogSeverityNames[severity],
data_->basename_, data_->line_, GetTID(),
LogMessageTime(data_->tm_time_,
data_->timestamp_,
data_->usecs_)),
custom_prefix_callback_data
);
stream() << " ";
}
#endif
}
data_->num_prefix_chars_ = data_->stream_.pcount();

Expand Down Expand Up @@ -2510,6 +2536,16 @@ void InitGoogleLogging(const char* argv0) {
glog_internal_namespace_::InitGoogleLoggingUtilities(argv0);
}

#ifdef GLOG_CUSTOM_PREFIX_SUPPORT
void InitGoogleLogging(const char* argv0,
CustomPrefixCallback prefix_callback,
void* prefix_callback_data) {
custom_prefix_callback = prefix_callback;
custom_prefix_callback_data = prefix_callback_data;
InitGoogleLogging(argv0);
}
#endif

void ShutdownGoogleLogging() {
glog_internal_namespace_::ShutdownGoogleLoggingUtilities();
LogDestination::DeleteLogDestinations();
Expand Down
Loading

0 comments on commit 7d4eeb1

Please sign in to comment.