1 // Copyright (c) 2011 The LevelDB 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. See the AUTHORS file for names of contributors.
5 // Logger implementation that can be shared by all environments
6 // where enough Posix functionality is available.
8 #ifndef STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_
9 #define STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_
15 #include "leveldb/env.h"
19 class PosixLogger : public Logger {
22 uint64_t (*gettid_)(); // Return the thread id for the current thread
24 PosixLogger(FILE* f, uint64_t (*gettid)()) : file_(f), gettid_(gettid) { }
25 virtual ~PosixLogger() {
28 virtual void Logv(const char* format, va_list ap) {
29 const uint64_t thread_id = (*gettid_)();
31 // We try twice: the first time with a fixed-size stack allocated buffer,
32 // and the second time with a much larger dynamically allocated buffer.
34 for (int iter = 0; iter < 2; iter++) {
38 bufsize = sizeof(buffer);
42 base = new char[bufsize];
45 char* limit = base + bufsize;
47 struct timeval now_tv;
48 gettimeofday(&now_tv, NULL);
49 const time_t seconds = now_tv.tv_sec;
51 localtime_r(&seconds, &t);
52 p += snprintf(p, limit - p,
53 "%04d/%02d/%02d-%02d:%02d:%02d.%06d %llx ",
60 static_cast<int>(now_tv.tv_usec),
61 static_cast<long long unsigned int>(thread_id));
66 va_copy(backup_ap, ap);
67 p += vsnprintf(p, limit - p, format, backup_ap);
71 // Truncate to available space if necessary
74 continue; // Try again with larger buffer
80 // Add newline if necessary
81 if (p == base || p[-1] != '\n') {
86 fwrite(base, 1, p - base, file_);
96 } // namespace leveldb
98 #endif // STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_