Skip to content

Commit

Permalink
feat(logging): Make it possible to print logs to stderr when using sc…
Browse files Browse the repository at this point in the history
…reen_logger (#2079)

If using `screen_logger`, the logs are only printed to stdout.

This patch introduces a new config
`[tools.screen_logger]stderr_start_level_on_stdout`
to define the lowest level of log messages to be copied to
stderr in addition to stdout. This is useful for testing.

A test using `ASSERT_DEATH` is added to check the logs are printed
to stderr indeed.
  • Loading branch information
acelyc111 authored Jul 22, 2024
1 parent c05e3f6 commit 013e2e1
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 11 deletions.
3 changes: 3 additions & 0 deletions src/utils/logging_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ class logging_provider

static logging_provider *create_default_instance();

logging_provider(log_level_t stderr_start_level) : _stderr_start_level(stderr_start_level) {}

std::vector<std::unique_ptr<command_deregister>> _cmds;
const log_level_t _stderr_start_level;
};

void set_log_prefixed_message_func(std::function<std::string()> func);
Expand Down
27 changes: 21 additions & 6 deletions src/utils/simple_logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ DSN_DEFINE_uint64(
DSN_DEFINE_validator(max_number_of_log_files_on_disk,
[](int32_t value) -> bool { return value > 0; });

DSN_DEFINE_string(tools.screen_logger,
stderr_start_level_on_stdout,
"LOG_LEVEL_WARNING",
"The lowest level of log messages to be copied to stderr in addition to stdout");
DSN_DEFINE_validator(stderr_start_level_on_stdout, [](const char *value) -> bool {
const auto level = enum_from_string(value, LOG_LEVEL_INVALID);
return LOG_LEVEL_DEBUG <= level && level <= LOG_LEVEL_FATAL;
});

DSN_DEFINE_string(
tools.simple_logger,
stderr_start_level,
Expand Down Expand Up @@ -169,9 +178,15 @@ inline void process_fatal_log(log_level_t log_level)

} // anonymous namespace

screen_logger::screen_logger(const char *, const char *)
: logging_provider(enum_from_string(FLAGS_stderr_start_level_on_stdout, LOG_LEVEL_INVALID)),
_short_header(true)
{
}

void screen_logger::print_header(log_level_t log_level)
{
::dsn::tools::print_header(stdout, LOG_LEVEL_COUNT, log_level);
::dsn::tools::print_header(stdout, _stderr_start_level, log_level);
}

void screen_logger::print_long_header(const char *file,
Expand All @@ -180,12 +195,12 @@ void screen_logger::print_long_header(const char *file,
log_level_t log_level)
{
::dsn::tools::print_long_header(
stdout, file, function, line, _short_header, LOG_LEVEL_COUNT, log_level);
stdout, file, function, line, _short_header, _stderr_start_level, log_level);
}

void screen_logger::print_body(const char *body, log_level_t log_level)
{
::dsn::tools::print_body(stdout, body, LOG_LEVEL_COUNT, log_level);
::dsn::tools::print_body(stdout, body, _stderr_start_level, log_level);
}

void screen_logger::log(
Expand All @@ -206,10 +221,10 @@ void screen_logger::log(
void screen_logger::flush() { ::fflush(stdout); }

simple_logger::simple_logger(const char *log_dir, const char *role_name)
: _log_dir(std::string(log_dir)),
: logging_provider(enum_from_string(FLAGS_stderr_start_level, LOG_LEVEL_INVALID)),
_log_dir(std::string(log_dir)),
_log(nullptr),
_file_bytes(0),
_stderr_start_level(enum_from_string(FLAGS_stderr_start_level, LOG_LEVEL_INVALID))
_file_bytes(0)
{
// Use 'role_name' if it is specified, otherwise use 'base_name'.
const std::string symlink_name(
Expand Down
7 changes: 3 additions & 4 deletions src/utils/simple_logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace tools {
class screen_logger : public logging_provider
{
public:
explicit screen_logger(const char *, const char *) : _short_header(true) {}
explicit screen_logger(const char *, const char *);
~screen_logger() override = default;

void log(const char *file,
Expand All @@ -56,12 +56,12 @@ class screen_logger : public logging_provider
virtual void flush();

private:
static void print_header(log_level_t log_level);
void print_header(log_level_t log_level);
void print_long_header(const char *file,
const char *function,
const int line,
log_level_t log_level);
static void print_body(const char *body, log_level_t log_level);
void print_body(const char *body, log_level_t log_level);

::dsn::utils::ex_lock_nr _lock;
const bool _short_header;
Expand Down Expand Up @@ -119,7 +119,6 @@ class simple_logger : public logging_provider
FILE *_log;
// The byte size of the current log file.
uint64_t _file_bytes;
const log_level_t _stderr_start_level;
};
} // namespace tools
} // namespace dsn
4 changes: 3 additions & 1 deletion src/utils/test/fmt_logging_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@
#include <fmt/core.h>
#include <memory>

#include "absl/strings/string_view.h"
#include "common/gpid.h"
#include "common/replication.codes.h"
#include "gtest/gtest.h"
#include "runtime/task/task_code.h"
#include "utils/error_code.h"
#include "utils/errors.h"
#include "absl/strings/string_view.h"
#include "utils/fmt_logging.h"

namespace dsn {
namespace replication {
Expand All @@ -47,6 +48,7 @@ TEST(fmt_logging, basic)
ASSERT_EQ(fmt::format("{}", LPC_REPLICATION_LOW), "LPC_REPLICATION_LOW");
ASSERT_EQ(absl::string_view("yes"), "yes");
ASSERT_EQ(fmt::format("{}", absl::string_view("yes\0yes")), "yes\0yes");
ASSERT_DEATH(CHECK(false, "CHECK false in test"), "CHECK false in test");
}

} // namespace replication
Expand Down

0 comments on commit 013e2e1

Please sign in to comment.