mirror of
https://github.com/facebook/rocksdb.git
synced 2024-12-02 20:52:55 +00:00
3fdc7243f3
Summary: This PR fixes a bug in the StderrLogger that truncated the last character in the logline. The problem was that we provided an incorrect max size parameter into the vsnprintf function. The size didn't take into account the null byte that the function automatically adds. Before fix ``` ** File Read Latency Histogram By Level [default] ** 2024/05/04-18:50:24.209304 4788 [/db_impl/db_impl.cc:498] Shutdown: canceling all background wor 2024/05/04-18:50:24.209598 4788 [/db_impl/db_impl.cc:692] Shutdown complet ``` After fix ``` ** File Read Latency Histogram By Level [default] ** 2024/05/04-18:51:19.814584 4d4d [/db_impl/db_impl.cc:498] Shutdown: canceling all background work 2024/05/04-18:51:19.815528 4d4d [/db_impl/db_impl.cc:692] Shutdown complete ``` Pull Request resolved: https://github.com/facebook/rocksdb/pull/12620 Test Plan: tested on examples/simple_example.cc with StderrLogger Fixes: https://github.com/facebook/rocksdb/issues/12576 Reviewed By: jaykorean Differential Revision: D56972332 Pulled By: ajkr fbshipit-source-id: 70405e8231ae6e90d24fe0b351bc8e749176bd15
63 lines
2.2 KiB
C++
63 lines
2.2 KiB
C++
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
//
|
|
// This source code is licensed under both the GPLv2 (found in the
|
|
// COPYING file in the root directory) and Apache 2.0 License
|
|
// (found in the LICENSE.Apache file in the root directory).
|
|
|
|
#include "util/stderr_logger.h"
|
|
|
|
#include "port/malloc.h"
|
|
#include "port/sys_time.h"
|
|
|
|
namespace ROCKSDB_NAMESPACE {
|
|
StderrLogger::~StderrLogger() {
|
|
if (log_prefix != nullptr) {
|
|
free((void*)log_prefix);
|
|
}
|
|
}
|
|
|
|
void StderrLogger::Logv(const char* format, va_list ap) {
|
|
const uint64_t thread_id = Env::Default()->GetThreadID();
|
|
|
|
port::TimeVal now_tv;
|
|
port::GetTimeOfDay(&now_tv, nullptr);
|
|
const time_t seconds = now_tv.tv_sec;
|
|
struct tm t;
|
|
port::LocalTimeR(&seconds, &t);
|
|
|
|
// The string we eventually log has three parts: the context (time, thread),
|
|
// optional user-supplied prefix, and the actual log message (the "suffix").
|
|
//
|
|
// We compute their lengths so that we can allocate a buffer big enough to
|
|
// print it. The context string (with the date and thread id) is really only
|
|
// 44 bytes, but we allocate 50 to be safe.
|
|
//
|
|
// ctx_len = 44 = ( 4+ 1+ 2+1+2+ 1+2+ 1+2+ 1+ 2+1+6+ 1+16+1)
|
|
const char* ctx_prefix_fmt = "%04d/%02d/%02d-%02d:%02d:%02d.%06d %llx %s";
|
|
size_t ctx_len = 50;
|
|
|
|
va_list ap_copy;
|
|
va_copy(ap_copy, ap);
|
|
const size_t log_suffix_len = vsnprintf(nullptr, 0, format, ap_copy) + 1;
|
|
va_end(ap_copy);
|
|
|
|
// Allocate space for the context, log_prefix, and log itself
|
|
// Extra byte for null termination
|
|
size_t buf_len = ctx_len + log_prefix_len + log_suffix_len;
|
|
std::unique_ptr<char[]> buf(new char[buf_len]);
|
|
|
|
// If the logger was created without a prefix, the prefix is a nullptr
|
|
const char* prefix = log_prefix == nullptr ? "" : log_prefix;
|
|
|
|
// Write out the context and prefix string
|
|
int written =
|
|
snprintf(buf.get(), ctx_len + log_prefix_len, ctx_prefix_fmt,
|
|
t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min,
|
|
t.tm_sec, static_cast<int>(now_tv.tv_usec),
|
|
static_cast<long long unsigned int>(thread_id), prefix);
|
|
vsnprintf(buf.get() + written, log_suffix_len, format, ap);
|
|
|
|
fprintf(stderr, "%s%c", buf.get(), '\n');
|
|
}
|
|
} // namespace ROCKSDB_NAMESPACE
|