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