10225501448 李度 10225101546 陈胤遒 10215501422 高宇菲
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
2.5 KiB

  1. // Copyright 2011 Google Inc. All Rights Reserved.
  2. // Author: sanjay@google.com (Sanjay Ghemawat)
  3. //
  4. // Logger implementation that can be shared by all environments
  5. // where enough posix functionality is available.
  6. #ifndef STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_
  7. #define STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_
  8. #include <algorithm>
  9. #include <stdio.h>
  10. #include <sys/time.h>
  11. #include <time.h>
  12. #include "leveldb/env.h"
  13. namespace leveldb {
  14. class PosixLogger : public Logger {
  15. private:
  16. FILE* file_;
  17. uint64_t (*gettid_)(); // Return the thread id for the current thread
  18. public:
  19. PosixLogger(FILE* f, uint64_t (*gettid)()) : file_(f), gettid_(gettid) { }
  20. virtual ~PosixLogger() {
  21. fclose(file_);
  22. }
  23. virtual void Logv(const char* format, va_list ap) {
  24. const uint64_t thread_id = (*gettid_)();
  25. // We try twice: the first time with a fixed-size stack allocated buffer,
  26. // and the second time with a much larger dynamically allocated buffer.
  27. char buffer[500];
  28. for (int iter = 0; iter < 2; iter++) {
  29. char* base;
  30. int bufsize;
  31. if (iter == 0) {
  32. bufsize = sizeof(buffer);
  33. base = buffer;
  34. } else {
  35. bufsize = 30000;
  36. base = new char[bufsize];
  37. }
  38. char* p = base;
  39. char* limit = base + bufsize;
  40. struct timeval now_tv;
  41. gettimeofday(&now_tv, NULL);
  42. const time_t seconds = now_tv.tv_sec;
  43. struct tm t;
  44. localtime_r(&seconds, &t);
  45. p += snprintf(p, limit - p,
  46. "%04d/%02d/%02d-%02d:%02d:%02d.%06d %llx ",
  47. t.tm_year + 1900,
  48. t.tm_mon + 1,
  49. t.tm_mday,
  50. t.tm_hour,
  51. t.tm_min,
  52. t.tm_sec,
  53. static_cast<int>(now_tv.tv_usec),
  54. static_cast<long long unsigned int>(thread_id));
  55. // Print the message
  56. if (p < limit) {
  57. va_list backup_ap;
  58. va_copy(backup_ap, ap);
  59. p += vsnprintf(p, limit - p, format, backup_ap);
  60. va_end(backup_ap);
  61. }
  62. // Truncate to available space if necessary
  63. if (p >= limit) {
  64. if (iter == 0) {
  65. continue; // Try again with larger buffer
  66. } else {
  67. p = limit - 1;
  68. }
  69. }
  70. // Add newline if necessary
  71. if (p == base || p[-1] != '\n') {
  72. *p++ = '\n';
  73. }
  74. assert(p <= limit);
  75. fwrite(base, 1, p - base, file_);
  76. fflush(file_);
  77. if (base != buffer) {
  78. delete[] base;
  79. }
  80. break;
  81. }
  82. }
  83. };
  84. }
  85. #endif // STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_