Skip to content

Commit

Permalink
Simplify leveldb::ChromiumLogger::Logv().
Browse files Browse the repository at this point in the history
This basically reimplemented base::StringPrintV(). Use that directly
instead.

Bug: none
Change-Id: I2e1a7de3a56d609b26899532d76cb64ca5bb7842
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4814667
Auto-Submit: Peter Kasting <pkasting@chromium.org>
Reviewed-by: Joshua Bell <jsbell@chromium.org>
Commit-Queue: Joshua Bell <jsbell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1188593}
  • Loading branch information
pkasting authored and Chromium LUCI CQ committed Aug 25, 2023
1 parent 33f1311 commit 91ff7be
Showing 1 changed file with 16 additions and 79 deletions.
95 changes: 16 additions & 79 deletions third_party/leveldatabase/chromium_logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
#ifndef THIRD_PARTY_LEVELDATABASE_CHROMIUM_LOGGER_H_
#define THIRD_PARTY_LEVELDATABASE_CHROMIUM_LOGGER_H_

#include <cstdarg>
#include <string>
#include <utility>

#include "base/containers/span.h"
#include "base/files/file.h"
#include "base/format_macros.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "third_party/leveldatabase/src/include/leveldb/env.h"

namespace leveldb {

Expand All @@ -23,87 +25,22 @@ class ChromiumLogger : public Logger {
~ChromiumLogger() override = default;

void Logv(const char* format, va_list arguments) override {
// Record the time as close to the Logv() call as possible.
base::Time::Exploded now_exploded;
base::Time::Now().LocalExplode(&now_exploded);

const base::PlatformThreadId thread_id = base::PlatformThread::CurrentId();

// We first attempt to print into a stack-allocated buffer. If this attempt
// fails, we make a second attempt with a dynamically allocated buffer.
constexpr const int kStackBufferSize = 512;
char stack_buffer[kStackBufferSize];
static_assert(sizeof(stack_buffer) == static_cast<size_t>(kStackBufferSize),
"sizeof(char) is expected to be 1 in C++");

int dynamic_buffer_size = 0; // Computed in the first iteration.
for (int iteration = 0; iteration < 2; ++iteration) {
const int buffer_size =
(iteration == 0) ? kStackBufferSize : dynamic_buffer_size;
char* const buffer =
(iteration == 0) ? stack_buffer : new char[dynamic_buffer_size];

// Print the header into the buffer.
int buffer_offset = base::snprintf(
buffer, buffer_size,
"%04d/%02d/%02d-%02d:%02d:%02d.%03d %" PRIx64 " ",
now_exploded.year,
now_exploded.month,
now_exploded.day_of_month,
now_exploded.hour,
now_exploded.minute,
now_exploded.second,
now_exploded.millisecond,
static_cast<uint64_t>(thread_id));

// The header can be at most 45 characters (10 date + 12 time + 3 spacing
// + 20 thread ID), which should fit comfortably into the static buffer.
DCHECK_LE(buffer_offset, 45);
static_assert(45 < kStackBufferSize,
"stack-allocated buffer may not fit the message header");
DCHECK_LT(buffer_offset, buffer_size);

// Print the message into the buffer.
std::va_list arguments_copy;
va_copy(arguments_copy, arguments);
buffer_offset += std::vsnprintf(buffer + buffer_offset,
buffer_size - buffer_offset, format,
arguments_copy);
va_end(arguments_copy);

// The code below may append a newline at the end of the buffer, which
// requires an extra character.
if (buffer_offset >= buffer_size - 1) {
// The message did not fit into the buffer.
if (iteration == 0) {
// Re-run the loop and use a dynamically-allocated buffer. The buffer
// will be large enough for the log message, an extra newline and a
// null terminator.
dynamic_buffer_size = buffer_offset + 2;
continue;
}

// The dynamically-allocated buffer was incorrectly sized. This should
// not happen, assuming a correct implementation of (v)snprintf. Fail
// in tests, recover by truncating the log message in production.
NOTREACHED();
buffer_offset = buffer_size - 1;
}

// Add a newline if necessary.
if (buffer[buffer_offset - 1] != '\n') {
buffer[buffer_offset] = '\n';
++buffer_offset;
}

DCHECK_LE(buffer_offset, buffer_size);
file_.WriteAtCurrentPos(buffer, buffer_offset);

if (iteration != 0) {
delete[] buffer;
}
break;
std::string str =
base::StringPrintf(
"%04d/%02d/%02d-%02d:%02d:%02d.%03d %" PRIx64 " ",
now_exploded.year, now_exploded.month, now_exploded.day_of_month,
now_exploded.hour, now_exploded.minute, now_exploded.second,
now_exploded.millisecond,
static_cast<uint64_t>(base::PlatformThread::CurrentId())) +
base::StringPrintV(format, arguments);
if (str.back() != '\n') {
str.push_back('\n');
}

file_.WriteAtCurrentPosAndCheck(base::as_bytes(base::make_span(str)));
}

private:
Expand Down

0 comments on commit 91ff7be

Please sign in to comment.