/src/rocksdb/logging/log_buffer.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | | // This source code is licensed under both the GPLv2 (found in the |
3 | | // COPYING file in the root directory) and Apache 2.0 License |
4 | | // (found in the LICENSE.Apache file in the root directory). |
5 | | |
6 | | #include "logging/log_buffer.h" |
7 | | |
8 | | #include "port/port.h" |
9 | | #include "port/sys_time.h" |
10 | | |
11 | | namespace ROCKSDB_NAMESPACE { |
12 | | |
13 | | LogBuffer::LogBuffer(const InfoLogLevel log_level, Logger* info_log) |
14 | 0 | : log_level_(log_level), info_log_(info_log) {} |
15 | | |
16 | | void LogBuffer::AddLogToBuffer(size_t max_log_size, const char* format, |
17 | 0 | va_list ap) { |
18 | 0 | if (!info_log_ || log_level_ < info_log_->GetInfoLogLevel()) { |
19 | | // Skip the level because of its level. |
20 | 0 | return; |
21 | 0 | } |
22 | | |
23 | 0 | char* alloc_mem = arena_.AllocateAligned(max_log_size); |
24 | 0 | BufferedLog* buffered_log = new (alloc_mem) BufferedLog(); |
25 | 0 | char* p = buffered_log->message; |
26 | 0 | char* limit = alloc_mem + max_log_size - 1; |
27 | | |
28 | | // store the time |
29 | 0 | port::GetTimeOfDay(&(buffered_log->now_tv), nullptr); |
30 | | |
31 | | // Print the message |
32 | 0 | if (p < limit) { |
33 | 0 | va_list backup_ap; |
34 | 0 | va_copy(backup_ap, ap); |
35 | 0 | auto n = vsnprintf(p, limit - p, format, backup_ap); |
36 | 0 | #ifndef OS_WIN |
37 | | // MS reports -1 when the buffer is too short |
38 | 0 | assert(n >= 0); |
39 | 0 | #endif |
40 | 0 | if (n > 0) { |
41 | 0 | p += n; |
42 | 0 | } else { |
43 | 0 | p = limit; |
44 | 0 | } |
45 | 0 | va_end(backup_ap); |
46 | 0 | } |
47 | |
|
48 | 0 | if (p > limit) { |
49 | 0 | p = limit; |
50 | 0 | } |
51 | | |
52 | | // Add '\0' to the end |
53 | 0 | *p = '\0'; |
54 | |
|
55 | 0 | logs_.push_back(buffered_log); |
56 | 0 | } |
57 | | |
58 | 0 | void LogBuffer::FlushBufferToLog() { |
59 | 0 | for (BufferedLog* log : logs_) { |
60 | 0 | const time_t seconds = log->now_tv.tv_sec; |
61 | 0 | struct tm t; |
62 | 0 | if (port::LocalTimeR(&seconds, &t) != nullptr) { |
63 | 0 | Log(log_level_, info_log_, |
64 | 0 | "(Original Log Time %04d/%02d/%02d-%02d:%02d:%02d.%06d) %s", |
65 | 0 | t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, |
66 | 0 | t.tm_sec, static_cast<int>(log->now_tv.tv_usec), log->message); |
67 | 0 | } |
68 | 0 | } |
69 | 0 | logs_.clear(); |
70 | 0 | } |
71 | | |
72 | | void LogToBuffer(LogBuffer* log_buffer, size_t max_log_size, const char* format, |
73 | 0 | ...) { |
74 | 0 | if (log_buffer != nullptr) { |
75 | 0 | va_list ap; |
76 | 0 | va_start(ap, format); |
77 | 0 | log_buffer->AddLogToBuffer(max_log_size, format, ap); |
78 | 0 | va_end(ap); |
79 | 0 | } |
80 | 0 | } |
81 | | |
82 | 0 | void LogToBuffer(LogBuffer* log_buffer, const char* format, ...) { |
83 | 0 | if (log_buffer != nullptr) { |
84 | 0 | va_list ap; |
85 | 0 | va_start(ap, format); |
86 | 0 | log_buffer->AddLogToBuffer(LogBuffer::kDefaultMaxLogSize, format, ap); |
87 | 0 | va_end(ap); |
88 | 0 | } |
89 | 0 | } |
90 | | |
91 | | } // namespace ROCKSDB_NAMESPACE |