LCOV - code coverage report
Current view: top level - src/leveldb/util - posix_logger.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 28 34 82.4 %
Date: 2015-10-12 22:39:14 Functions: 2 4 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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         384 :   PosixLogger(FILE* f, uint64_t (*gettid)()) : file_(f), gettid_(gettid) { }
      25         384 :   virtual ~PosixLogger() {
      26         192 :     fclose(file_);
      27         192 :   }
      28         695 :   virtual void Logv(const char* format, va_list ap) {
      29         695 :     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         695 :     for (int iter = 0; iter < 2; iter++) {
      35             :       char* base;
      36             :       int bufsize;
      37         695 :       if (iter == 0) {
      38             :         bufsize = sizeof(buffer);
      39             :         base = buffer;
      40             :       } else {
      41           0 :         bufsize = 30000;
      42           0 :         base = new char[bufsize];
      43             :       }
      44         695 :       char* p = base;
      45         695 :       char* limit = base + bufsize;
      46             : 
      47             :       struct timeval now_tv;
      48         695 :       gettimeofday(&now_tv, NULL);
      49         695 :       const time_t seconds = now_tv.tv_sec;
      50             :       struct tm t;
      51         695 :       localtime_r(&seconds, &t);
      52        1390 :       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        2085 :                     static_cast<long long unsigned int>(thread_id));
      62             : 
      63             :       // Print the message
      64         695 :       if (p < limit) {
      65             :         va_list backup_ap;
      66         695 :         va_copy(backup_ap, ap);
      67        1390 :         p += vsnprintf(p, limit - p, format, backup_ap);
      68         695 :         va_end(backup_ap);
      69             :       }
      70             : 
      71             :       // Truncate to available space if necessary
      72         695 :       if (p >= limit) {
      73           0 :         if (iter == 0) {
      74           0 :           continue;       // Try again with larger buffer
      75             :         } else {
      76           0 :           p = limit - 1;
      77             :         }
      78             :       }
      79             : 
      80             :       // Add newline if necessary
      81         695 :       if (p == base || p[-1] != '\n') {
      82         373 :         *p++ = '\n';
      83             :       }
      84             : 
      85         695 :       assert(p <= limit);
      86         695 :       fwrite(base, 1, p - base, file_);
      87         695 :       fflush(file_);
      88         695 :       if (base != buffer) {
      89           0 :         delete[] base;
      90             :       }
      91         695 :       break;
      92             :     }
      93         695 :   }
      94             : };
      95             : 
      96             : }  // namespace leveldb
      97             : 
      98             : #endif  // STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_

Generated by: LCOV version 1.11