Feathercoin  0.5.0
P2P Digital Currency
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
posix_logger.h
Go to the documentation of this file.
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.
4 //
5 // Logger implementation that can be shared by all environments
6 // where enough Posix functionality is available.
7 
8 #ifndef STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_
9 #define STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_
10 
11 #include <algorithm>
12 #include <stdio.h>
13 #include <sys/time.h>
14 #include <time.h>
15 #include "leveldb/env.h"
16 
17 namespace leveldb {
18 
19 class PosixLogger : public Logger {
20  private:
21  FILE* file_;
22  uint64_t (*gettid_)(); // Return the thread id for the current thread
23  public:
24  PosixLogger(FILE* f, uint64_t (*gettid)()) : file_(f), gettid_(gettid) { }
25  virtual ~PosixLogger() {
26  fclose(file_);
27  }
28  virtual void Logv(const char* format, va_list ap) {
29  const uint64_t thread_id = (*gettid_)();
30 
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.
33  char buffer[500];
34  for (int iter = 0; iter < 2; iter++) {
35  char* base;
36  int bufsize;
37  if (iter == 0) {
38  bufsize = sizeof(buffer);
39  base = buffer;
40  } else {
41  bufsize = 30000;
42  base = new char[bufsize];
43  }
44  char* p = base;
45  char* limit = base + bufsize;
46 
47  struct timeval now_tv;
48  gettimeofday(&now_tv, NULL);
49  const time_t seconds = now_tv.tv_sec;
50  struct tm t;
51  localtime_r(&seconds, &t);
52  p += snprintf(p, limit - p,
53  "%04d/%02d/%02d-%02d:%02d:%02d.%06d %llx ",
54  t.tm_year + 1900,
55  t.tm_mon + 1,
56  t.tm_mday,
57  t.tm_hour,
58  t.tm_min,
59  t.tm_sec,
60  static_cast<int>(now_tv.tv_usec),
61  static_cast<long long unsigned int>(thread_id));
62 
63  // Print the message
64  if (p < limit) {
65  va_list backup_ap;
66  va_copy(backup_ap, ap);
67  p += vsnprintf(p, limit - p, format, backup_ap);
68  va_end(backup_ap);
69  }
70 
71  // Truncate to available space if necessary
72  if (p >= limit) {
73  if (iter == 0) {
74  continue; // Try again with larger buffer
75  } else {
76  p = limit - 1;
77  }
78  }
79 
80  // Add newline if necessary
81  if (p == base || p[-1] != '\n') {
82  *p++ = '\n';
83  }
84 
85  assert(p <= limit);
86  fwrite(base, 1, p - base, file_);
87  fflush(file_);
88  if (base != buffer) {
89  delete[] base;
90  }
91  break;
92  }
93  }
94 };
95 
96 } // namespace leveldb
97 
98 #endif // STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_
virtual void Logv(const char *format, va_list ap)
Definition: posix_logger.h:28
PosixLogger(FILE *f, uint64_t(*gettid)())
Definition: posix_logger.h:24
unsigned long long uint64_t
Definition: stdint.h:22
const char * base
Definition: testharness.cc:17
uint64_t(* gettid_)()
Definition: posix_logger.h:22
virtual ~PosixLogger()
Definition: posix_logger.h:25