log_buffer.cc 2.4 KB

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