log_buffer.cc 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. #include "logging/log_buffer.h"
  6. #include "port/sys_time.h"
  7. #include "port/port.h"
  8. namespace ROCKSDB_NAMESPACE {
  9. LogBuffer::LogBuffer(const InfoLogLevel log_level,
  10. Logger*info_log)
  11. : log_level_(log_level), info_log_(info_log) {}
  12. void LogBuffer::AddLogToBuffer(size_t max_log_size, const char* format,
  13. va_list ap) {
  14. if (!info_log_ || log_level_ < info_log_->GetInfoLogLevel()) {
  15. // Skip the level because of its level.
  16. return;
  17. }
  18. char* alloc_mem = arena_.AllocateAligned(max_log_size);
  19. BufferedLog* buffered_log = new (alloc_mem) BufferedLog();
  20. char* p = buffered_log->message;
  21. char* limit = alloc_mem + max_log_size - 1;
  22. // store the time
  23. gettimeofday(&(buffered_log->now_tv), nullptr);
  24. // Print the message
  25. if (p < limit) {
  26. va_list backup_ap;
  27. va_copy(backup_ap, ap);
  28. auto n = vsnprintf(p, limit - p, format, backup_ap);
  29. #ifndef OS_WIN
  30. // MS reports -1 when the buffer is too short
  31. assert(n >= 0);
  32. #endif
  33. if (n > 0) {
  34. p += n;
  35. } else {
  36. p = limit;
  37. }
  38. va_end(backup_ap);
  39. }
  40. if (p > limit) {
  41. p = limit;
  42. }
  43. // Add '\0' to the end
  44. *p = '\0';
  45. logs_.push_back(buffered_log);
  46. }
  47. void LogBuffer::FlushBufferToLog() {
  48. for (BufferedLog* log : logs_) {
  49. const time_t seconds = log->now_tv.tv_sec;
  50. struct tm t;
  51. if (localtime_r(&seconds, &t) != nullptr) {
  52. Log(log_level_, info_log_,
  53. "(Original Log Time %04d/%02d/%02d-%02d:%02d:%02d.%06d) %s",
  54. t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min,
  55. t.tm_sec, static_cast<int>(log->now_tv.tv_usec), log->message);
  56. }
  57. }
  58. logs_.clear();
  59. }
  60. void LogToBuffer(LogBuffer* log_buffer, size_t max_log_size, const char* format,
  61. ...) {
  62. if (log_buffer != nullptr) {
  63. va_list ap;
  64. va_start(ap, format);
  65. log_buffer->AddLogToBuffer(max_log_size, format, ap);
  66. va_end(ap);
  67. }
  68. }
  69. void LogToBuffer(LogBuffer* log_buffer, const char* format, ...) {
  70. if (log_buffer != nullptr) {
  71. va_list ap;
  72. va_start(ap, format);
  73. log_buffer->AddLogToBuffer(LogBuffer::kDefaultMaxLogSize, format, ap);
  74. va_end(ap);
  75. }
  76. }
  77. } // namespace ROCKSDB_NAMESPACE