1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef THIRD_PARTY_LEVELDATABASE_CHROMIUM_LOGGER_H_ 6 #define THIRD_PARTY_LEVELDATABASE_CHROMIUM_LOGGER_H_ 7 8 #include <algorithm> 9 #include <stdio.h> 10 #include "base/format_macros.h" 11 #include "base/strings/string_util.h" 12 #include "base/time/time.h" 13 #include "leveldb/env.h" 14 15 namespace leveldb { 16 17 class ChromiumLogger : public Logger { 18 public: ChromiumLogger(FILE * f)19 ChromiumLogger(FILE* f) : file_(f) { } ~ChromiumLogger()20 virtual ~ChromiumLogger() { 21 fclose(file_); 22 } Logv(const char * format,va_list ap)23 virtual void Logv(const char* format, va_list ap) { 24 const long long unsigned int thread_id = 25 ::base::PlatformThread::CurrentId(); 26 27 // We try twice: the first time with a fixed-size stack allocated buffer, 28 // and the second time with a much larger dynamically allocated buffer. 29 char buffer[500]; 30 for (int iter = 0; iter < 2; iter++) { 31 char* base; 32 int bufsize; 33 if (iter == 0) { 34 bufsize = sizeof(buffer); 35 base = buffer; 36 } else { 37 bufsize = 30000; 38 base = new char[bufsize]; 39 } 40 char* p = base; 41 char* limit = base + bufsize; 42 43 ::base::Time::Exploded t; 44 ::base::Time::Now().LocalExplode(&t); 45 46 p += ::base::snprintf(p, limit - p, 47 "%04d/%02d/%02d-%02d:%02d:%02d.%03d %" PRIu64 " ", 48 t.year, 49 t.month, 50 t.day_of_month, 51 t.hour, 52 t.minute, 53 t.second, 54 t.millisecond, 55 thread_id); 56 57 // Print the message 58 if (p < limit) { 59 va_list backup_ap; 60 GG_VA_COPY(backup_ap, ap); 61 p += vsnprintf(p, limit - p, format, backup_ap); 62 va_end(backup_ap); 63 } 64 65 // Truncate to available space if necessary 66 if (p >= limit) { 67 if (iter == 0) { 68 continue; // Try again with larger buffer 69 } else { 70 p = limit - 1; 71 } 72 } 73 74 // Add newline if necessary 75 if (p == base || p[-1] != '\n') { 76 *p++ = '\n'; 77 } 78 79 assert(p <= limit); 80 fwrite(base, 1, p - base, file_); 81 fflush(file_); 82 if (base != buffer) { 83 delete[] base; 84 } 85 break; 86 } 87 } 88 private: 89 FILE* file_; 90 }; 91 92 } // namespace leveldb 93 94 #endif // THIRD_PARTY_LEVELDATABASE_CHROMIUM_LOGGER_H_ 95