/Users/deen/code/yugabyte-db/src/yb/rocksdb/util/log_buffer.cc
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | // Copyright (c) YugaByte, Inc. | 
| 2 |  | // | 
| 3 |  | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | 
| 4 |  | // in compliance with the License.  You may obtain a copy of the License at | 
| 5 |  | // | 
| 6 |  | // http://www.apache.org/licenses/LICENSE-2.0 | 
| 7 |  | // | 
| 8 |  | // Unless required by applicable law or agreed to in writing, software distributed under the License | 
| 9 |  | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | 
| 10 |  | // or implied.  See the License for the specific language governing permissions and limitations | 
| 11 |  | // under the License. | 
| 12 |  | // | 
| 13 |  | // | 
| 14 |  | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. | 
| 15 |  | // This source code is licensed under the BSD-style license found in the | 
| 16 |  | // LICENSE file in the root directory of this source tree. An additional grant | 
| 17 |  | // of patent rights can be found in the PATENTS file in the same directory. | 
| 18 |  |  | 
| 19 |  | #include "yb/rocksdb/util/log_buffer.h" | 
| 20 |  |  | 
| 21 |  | #include <stdarg.h> | 
| 22 |  |  | 
| 23 |  | #include <glog/logging.h> | 
| 24 |  |  | 
| 25 |  | #include "yb/rocksdb/port/port.h" | 
| 26 |  | #include "yb/rocksdb/port/sys_time.h" | 
| 27 |  |  | 
| 28 |  | using std::string; | 
| 29 |  |  | 
| 30 |  | namespace rocksdb { | 
| 31 |  |  | 
| 32 |  | LogBuffer::LogBuffer(const InfoLogLevel log_level, | 
| 33 |  |                      Logger*info_log) | 
| 34 | 201k |     : log_level_(log_level), info_log_(info_log) {} | 
| 35 |  |  | 
| 36 | 201k | LogBuffer::~LogBuffer() { | 
| 37 | 201k |   LOG_IF(DFATAL, !IsEmpty()) | 
| 38 | 0 |       << "LogBuffer should be explicitly flushed in order to not lost accumulated log entries."; | 
| 39 | 201k | } | 
| 40 |  |  | 
| 41 |  | void LogBuffer::AddLogToBuffer( | 
| 42 |  |     const char* file, | 
| 43 |  |     const int line, | 
| 44 |  |     size_t max_log_size, | 
| 45 |  |     const char* format, | 
| 46 | 287k |     va_list ap) { | 
| 47 | 287k |   if (!info_log_ || log_level_ < info_log_->GetInfoLogLevel()287k) { | 
| 48 |  |     // Skip the level because of its level. | 
| 49 | 40 |     return; | 
| 50 | 40 |   } | 
| 51 |  |  | 
| 52 | 287k |   char* alloc_mem = arena_.AllocateAligned(max_log_size); | 
| 53 | 287k |   BufferedLog* buffered_log = new (alloc_mem) BufferedLog(); | 
| 54 | 287k |   char* p = buffered_log->message; | 
| 55 | 287k |   buffered_log->file_ = file; | 
| 56 | 287k |   buffered_log->line_ = line; | 
| 57 | 287k |   char* limit = alloc_mem + max_log_size - 1; | 
| 58 |  |  | 
| 59 |  |   // store the time | 
| 60 | 287k |   gettimeofday(&(buffered_log->now_tv), nullptr); | 
| 61 |  |  | 
| 62 |  |   // Print the message | 
| 63 | 287k |   if (p < limit287k) { | 
| 64 | 287k |     va_list backup_ap; | 
| 65 | 287k |     va_copy(backup_ap, ap); | 
| 66 | 287k |     auto n = vsnprintf(p, limit - p + 1, format, backup_ap); | 
| 67 | 287k | #ifndef OS_WIN | 
| 68 |  |     // MS reports -1 when the buffer is too short | 
| 69 | 287k |     assert(n >= 0); | 
| 70 | 0 | #endif | 
| 71 | 287k |     if (n > 0287k) { | 
| 72 | 287k |       p += n; | 
| 73 | 18.4E |     } else { | 
| 74 | 18.4E |       p = limit; | 
| 75 | 18.4E |     } | 
| 76 | 287k |     va_end(backup_ap); | 
| 77 | 287k |   } | 
| 78 |  |  | 
| 79 | 287k |   if (p > limit) { | 
| 80 | 7 |     p = limit; | 
| 81 | 7 |   } | 
| 82 |  |  | 
| 83 |  |   // Add '\0' to the end | 
| 84 | 287k |   *p = '\0'; | 
| 85 |  |  | 
| 86 | 287k |   logs_.push_back(buffered_log); | 
| 87 | 287k | } | 
| 88 |  |  | 
| 89 | 241k | void LogBuffer::FlushBufferToLog() { | 
| 90 | 287k |   for (BufferedLog* log : logs_) { | 
| 91 | 287k |     LogWithContext(log->file_, log->line_, log_level_, info_log_, "%s", log->message); | 
| 92 | 287k |   } | 
| 93 | 241k |   logs_.clear(); | 
| 94 | 241k | } | 
| 95 |  |  | 
| 96 |  | void LogToBufferWithContext( | 
| 97 |  |     const char* file, | 
| 98 |  |     const int line, | 
| 99 |  |     LogBuffer* log_buffer, | 
| 100 |  |     size_t max_log_size, | 
| 101 |  |     const char* format, | 
| 102 | 2 |     ...) { | 
| 103 | 2 |   if (log_buffer != nullptr) { | 
| 104 | 2 |     va_list ap; | 
| 105 | 2 |     va_start(ap, format); | 
| 106 | 2 |     log_buffer->AddLogToBuffer(file, line, max_log_size, format, ap); | 
| 107 | 2 |     va_end(ap); | 
| 108 | 2 |   } | 
| 109 | 2 | } | 
| 110 |  |  | 
| 111 |  | void LogToBufferWithContext( | 
| 112 |  |     const char* file, | 
| 113 |  |     const int line, | 
| 114 |  |     LogBuffer* log_buffer, | 
| 115 |  |     const char* format, | 
| 116 | 287k |     ...) { | 
| 117 | 287k |   const size_t kDefaultMaxLogSize = 512; | 
| 118 | 287k |   if (log_buffer != nullptr) { | 
| 119 | 287k |     va_list ap; | 
| 120 | 287k |     va_start(ap, format); | 
| 121 | 287k |     log_buffer->AddLogToBuffer(file, line, kDefaultMaxLogSize, format, ap); | 
| 122 | 287k |     va_end(ap); | 
| 123 | 287k |   } | 
| 124 | 287k | } | 
| 125 |  |  | 
| 126 |  | }  // namespace rocksdb |