15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef THIRD_PARTY_LEVELDATABASE_CHROMIUM_LOGGER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define THIRD_PARTY_LEVELDATABASE_CHROMIUM_LOGGER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <algorithm>
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/format_macros.h"
135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "third_party/leveldatabase/src/include/leveldb/env.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace leveldb {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChromiumLogger : public Logger {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  explicit ChromiumLogger(FILE* f) : file_(f) {}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ChromiumLogger() {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fclose(file_);
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Logv(const char* format, va_list ap) {
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::PlatformThreadId thread_id =
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ::base::PlatformThread::CurrentId();
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We try twice: the first time with a fixed-size stack allocated buffer,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and the second time with a much larger dynamically allocated buffer.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char buffer[500];
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int iter = 0; iter < 2; iter++) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      char* base;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int bufsize;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (iter == 0) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bufsize = sizeof(buffer);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base = buffer;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bufsize = 30000;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base = new char[bufsize];
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      char* p = base;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      char* limit = base + bufsize;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::base::Time::Exploded t;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::base::Time::Now().LocalExplode(&t);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      p += ::base::snprintf(p, limit - p,
49bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                    "%04d/%02d/%02d-%02d:%02d:%02d.%03d %" PRIu64 " ",
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    t.year,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    t.month,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    t.day_of_month,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    t.hour,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    t.minute,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    t.second,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    t.millisecond,
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    static_cast<uint64>(thread_id));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Print the message
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (p < limit) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        va_list backup_ap;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GG_VA_COPY(backup_ap, ap);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        p += vsnprintf(p, limit - p, format, backup_ap);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        va_end(backup_ap);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Truncate to available space if necessary
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (p >= limit) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (iter == 0) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          continue;       // Try again with larger buffer
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          p = limit - 1;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add newline if necessary
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (p == base || p[-1] != '\n') {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *p++ = '\n';
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(p <= limit);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fwrite(base, 1, p - base, file_);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fflush(file_);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (base != buffer) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delete[] base;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FILE* file_;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace leveldb
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // THIRD_PARTY_LEVELDATABASE_CHROMIUM_LOGGER_H_
98