From 4354967ec526308ac52af447a3074db196b5aa26 Mon Sep 17 00:00:00 2001 From: divyagayathri-hcl <159437886+divyagayathri-hcl@users.noreply.github.com> Date: Thu, 22 Aug 2024 11:50:02 -0700 Subject: [PATCH] [Comb] Add syslog sink to be used with GLOG. (#482) Co-authored-by: rhalstea Co-authored-by: kishanps --- gutil/BUILD.bazel | 7 +++++ gutil/syslog_sink.cc | 62 ++++++++++++++++++++++++++++++++++++++++++++ gutil/syslog_sink.h | 34 ++++++++++++++++++++++++ p4rt_app/BUILD.bazel | 1 + p4rt_app/p4rt.cc | 2 ++ 5 files changed, 106 insertions(+) create mode 100644 gutil/syslog_sink.cc create mode 100644 gutil/syslog_sink.h diff --git a/gutil/BUILD.bazel b/gutil/BUILD.bazel index 208c1438..e7a0dcd4 100644 --- a/gutil/BUILD.bazel +++ b/gutil/BUILD.bazel @@ -316,3 +316,10 @@ cc_test( "@com_google_absl//absl/strings", ], ) + +cc_library( + name = "syslog_sink", + srcs = ["syslog_sink.cc"], + hdrs = ["syslog_sink.h"], + deps = ["@com_github_google_glog//:glog"], +) diff --git a/gutil/syslog_sink.cc b/gutil/syslog_sink.cc new file mode 100644 index 00000000..e8ffb6e7 --- /dev/null +++ b/gutil/syslog_sink.cc @@ -0,0 +1,62 @@ +#include "gutil/syslog_sink.h" + +#include +#include +#include + +#include + +#include "glog/logging.h" + +namespace gutil { +namespace { + +// GLOG severity uses integers in the range [0-3]: +// https://github.com/google/glog/blob/master/src/glog/log_severity.h +constexpr std::array kGlogSeverityToSyslog = { + LOG_INFO, + LOG_WARNING, + LOG_ERR, + LOG_EMERG, +}; +constexpr std::array kGlogSeverityLetter = { + 'I', + 'W', + 'E', + 'F', +}; + +} // namespace + +SyslogSink::SyslogSink(const char* process_name) { + openlog(process_name, LOG_NDELAY, LOG_USER); + google::AddLogSink(this); +} + +SyslogSink::~SyslogSink() { + google::RemoveLogSink(this); + closelog(); +} + +void SyslogSink::send(google::LogSeverity severity, const char* full_filename, + const char* base_filename, int line, + const google::LogMessageTime& logmsgtime, + const char* message, size_t message_len) { + // Create a timestamp with micosecond resolution. + struct timeval tv; + struct timezone tz; + struct tm time; + gettimeofday(&tv, &tz); + localtime_r(&tv.tv_sec, &time); + + // Output format: + // I0104 23:00:59.123456 71 filename.cc:100] Your Message Here! + syslog(kGlogSeverityToSyslog[severity], + "%c%02d%02d %02d:%02d:%02d.%06ld %5ld %s:%d] %.*s", + kGlogSeverityLetter[severity], 1 + time.tm_mon, time.tm_mday, + time.tm_hour, time.tm_min, time.tm_sec, static_cast(tv.tv_usec), + syscall(SYS_gettid), base_filename, line, + static_cast(message_len), message); +} + +} // namespace gutil diff --git a/gutil/syslog_sink.h b/gutil/syslog_sink.h new file mode 100644 index 00000000..eff71912 --- /dev/null +++ b/gutil/syslog_sink.h @@ -0,0 +1,34 @@ +#ifndef PINS_GUTIL_SYSLOG_SINK_H_ +#define PINS_GUTIL_SYSLOG_SINK_H_ + +#include + +#include "glog/logging.h" + +namespace gutil { + +// When constructed SyslogSink will automatically register with GLOG and begin +// forwarding all LOG() messages to syslog. In the dtor we unregister with GLOG +// so the SyslogSink should outlive the program. These messages are treated as +// user-level (i.e. a LOG_USER facility), and serverities are mapped as follows: +// LOG(INFO) -> LOG_INFO +// LOG(WARNING) -> LOG_WARNING +// LOG(ERROR) -> LOG_ERR +// LOG(FATAL) -> LOG_EMERG +// +// The syslog message will be formatted similar to a GLOG message with a +// microsecond timestamp. +class SyslogSink : google::LogSink { + public: + SyslogSink(const char* process_name); + ~SyslogSink(); + + void send(google::LogSeverity severity, const char* full_filename, + const char* base_filename, int line, + const google::LogMessageTime& logmsgtime, const char* message, + size_t message_len) override; +}; + +} // namespace gutil + +#endif // PINS_GUTIL_SYSLOG_SINK_H_ diff --git a/p4rt_app/BUILD.bazel b/p4rt_app/BUILD.bazel index 21192654..8bf0b830 100644 --- a/p4rt_app/BUILD.bazel +++ b/p4rt_app/BUILD.bazel @@ -40,6 +40,7 @@ cc_binary( "@com_google_absl//absl/time", "@com_github_grpc_grpc//:grpc++_public_hdrs", "//gutil:status", + "//gutil:syslog_sink", "//p4rt_app/event_monitoring:app_state_db_port_table_event", "//p4rt_app/event_monitoring:app_state_db_send_to_ingress_port_table_event", "//p4rt_app/event_monitoring:config_db_cpu_queue_table_event", diff --git a/p4rt_app/p4rt.cc b/p4rt_app/p4rt.cc index e7808657..ece56ccd 100644 --- a/p4rt_app/p4rt.cc +++ b/p4rt_app/p4rt.cc @@ -40,6 +40,7 @@ #include "grpcpp/server.h" #include "grpcpp/server_builder.h" #include "gutil/status.h" +#include "gutil/syslog_sink.h" #include "p4rt_app/event_monitoring/app_state_db_port_table_event.h" #include "p4rt_app/event_monitoring/app_state_db_send_to_ingress_port_table_event.h" #include "p4rt_app/event_monitoring/config_db_cpu_queue_table_event.h" @@ -364,6 +365,7 @@ void ConfigDbEventLoop(P4RuntimeImpl* p4runtime_server, } // namespace p4rt_app int main(int argc, char** argv) { + gutil::SyslogSink syslog_sink("p4rt"); google::InitGoogleLogging(argv[0]); gflags::ParseCommandLineFlags(&argc, &argv, true);