• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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