Home | History | Annotate | Download | only in leveldatabase
      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:
     19   ChromiumLogger(FILE* f) : file_(f) { }
     20   virtual ~ChromiumLogger() {
     21     fclose(file_);
     22   }
     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