浏览代码

Begin merging cfmtlogger code

Sam Jaffe 6 年之前
父节点
当前提交
b70f1d70f0

+ 94 - 0
include/logger/c_logger.h

@@ -0,0 +1,94 @@
+//
+//  c_logger.hpp
+//  logging
+//
+//  Created by Sam Jaffe on 4/1/19.
+//
+
+#pragma once
+
+#include <cstdarg>
+#include <cstdlib>
+#include <cstring>
+#include <memory>
+#include <string>
+
+#include "logger_fwd.h"
+
+#define VA_LOGN(level, size)          \
+  do {                                \
+    va_list vargs;                    \
+    va_start( vargs, fmt );           \
+    vlognf( level, size, fmt, vargs );\
+    va_end( vargs );                  \
+  } while(0)
+
+#define VA_LOG(level) VA_LOGN(level, c_logger::LOGF_MAX_SIZE)
+
+namespace logging {
+  class logger_impl;
+  std::string timestamp();
+  
+  class c_logger {
+  public:
+    static const size_t LOGF_MAX_SIZE = 2048;
+  public:
+    inline void tracef(char const* fmt, ...) { VA_LOG(LTRACE); }
+    inline void tracenf(size_t n, char const* fmt, ...) { VA_LOGN(LTRACE, n); }
+    inline void trace(char const* msg) { log(LTRACE, msg); }
+    inline void trace(std::string const& msg) { log(LTRACE, msg); }
+    
+    inline void debugf(char const* fmt, ...) { VA_LOG(LDEBUG); }
+    inline void debugnf(size_t n, char const* fmt, ...) { VA_LOGN(LDEBUG, n); }
+    inline void debug(char const* msg) { log(LDEBUG, msg); }
+    inline void debug(std::string const& msg) { log(LDEBUG, msg); }
+    
+    inline void infof(char const* fmt, ...) { VA_LOG(LINFO); }
+    inline void infonf(size_t n, char const* fmt, ...) { VA_LOGN(LINFO, n); }
+    inline void info(char const* msg) { log(LINFO, msg); }
+    inline void info(std::string const& msg) { log(LINFO, msg); }
+    
+    inline void warnf(char const* fmt, ...) { VA_LOG(LWARNING); }
+    inline void warnnf(size_t n, char const* fmt, ...) { VA_LOGN(LWARNING, n); }
+    inline void warn(char const* msg) { log(LWARNING, msg); }
+    inline void warn(std::string const& msg) { log(LWARNING, msg); }
+    
+    inline void errorf(char const* fmt, ...) { VA_LOG(LERROR); }
+    inline void errornf(size_t n, char const* fmt, ...) { VA_LOGN(LERROR, n); }
+    inline void error(char const* msg) { log(LERROR, msg); }
+    inline void error(std::string const& msg) { log(LERROR, msg); }
+    
+    inline void criticalf(char const* fmt, ...) { VA_LOG(LCRITICAL); }
+    inline void criticalnf(size_t n, char const* fmt, ...) { VA_LOGN(LCRITICAL, n); }
+    inline void critical(char const* msg) { log(LCRITICAL, msg); }
+    inline void critical(std::string const& msg) { log(LCRITICAL, msg); }
+    
+    inline void fatalf(char const* fmt, ...) { VA_LOG(LFATAL); }
+    inline void fatalnf(size_t n, char const* fmt, ...) { VA_LOGN(LFATAL, n); }
+    inline void fatal(char const* msg) { log(LFATAL, msg); }
+    inline void fatal(std::string const& msg) { log(LFATAL, msg); }
+    
+    template <typename... Args>
+    inline void log(log_level ll, std::string const & interp, Args && ...args);
+    
+    void flush();
+    
+    ~c_logger();
+    
+  protected:
+    friend class manager;
+    c_logger(std::string const & name, std::shared_ptr<logger_impl> impl);
+
+  private:
+    void vlognf(log_level, size_t, char const*, va_list);
+    void log(log_level, std::string const&);
+    std::string get_header(log_level level);
+    
+  private:
+    log_level min_level_;
+    std::string logger_name_;
+    std::shared_ptr<logger_impl> impl_;
+  };
+}
+#undef VA_LOG
+#undef LA_LOGN

+ 1 - 13
include/logger/logger.h

@@ -33,9 +33,7 @@
 namespace logging {
   class logger_impl;
   class manager;
-    
-  const char* level_header(log_level);
-  
+
   class logger {
   public:
     ~logger();
@@ -69,14 +67,4 @@ namespace logging {
     std::string const logger_name_;
     std::shared_ptr<logger_impl> impl_;
   };
-  
-  class logger_impl {
-  public:
-    bool should_log( log_level ll ) const;
-    virtual void write( logpacket const & pkt ) = 0;
-    virtual void flush() = 0;
-    virtual ~logger_impl() = default;
-  protected:
-    log_level min_log_level;
-  };
 }

+ 3 - 1
include/logger/logger_fwd.h

@@ -7,6 +7,8 @@
 
 #pragma once
 
+#include <string>
+
 namespace logging {
   enum log_level {
     LTRACE,
@@ -18,7 +20,7 @@ namespace logging {
     LFATAL,
     LNONE
   };
-  
+    
   struct location_info {
     char const * filename = "???";
     int line = 0;

+ 19 - 0
include/logger/logger_impl.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#include "logger_fwd.h"
+
+namespace logging {
+  class logger_impl {
+  public:
+    virtual ~logger_impl() = default;
+    virtual void write(logpacket const & pkt) = 0;
+    virtual void write(log_level level, std::string const& msg) = 0;
+    virtual void flush() = 0;
+    bool should_log(log_level ll) const {
+      return ll >= min_log_level;
+    }
+
+  protected:
+    log_level min_log_level;
+  };
+}

+ 10 - 0
logger.xcodeproj/project.pbxproj

@@ -15,6 +15,8 @@
 		CD6F742E225189290081ED74 /* libcfmt_logger.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CD6F742D225189290081ED74 /* libcfmt_logger.dylib */; };
 		CD6F746C22518A2C0081ED74 /* GoogleMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD6F746B22518A2C0081ED74 /* GoogleMock.framework */; };
 		CD88E9572252BDFC00927F40 /* log_manager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CD88E9552252BDFC00927F40 /* log_manager.cxx */; };
+		CD88E95F2252D3EF00927F40 /* c_logger.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CD88E95D2252D3EF00927F40 /* c_logger.cxx */; };
+		CD88E9632252D67A00927F40 /* common.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CD88E9612252D67A00927F40 /* common.cxx */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -68,6 +70,9 @@
 		CD6F742F225189470081ED74 /* GoogleMock.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GoogleMock.xcodeproj; path = "../../../gmock-xcode-master/GoogleMock.xcodeproj"; sourceTree = "<group>"; };
 		CD6F746B22518A2C0081ED74 /* GoogleMock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleMock.framework; path = "../../../gmock-xcode-master/build/Release/GoogleMock.framework"; sourceTree = "<group>"; };
 		CD88E9552252BDFC00927F40 /* log_manager.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = log_manager.cxx; sourceTree = "<group>"; };
+		CD88E95D2252D3EF00927F40 /* c_logger.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = c_logger.cxx; sourceTree = "<group>"; };
+		CD88E9612252D67A00927F40 /* common.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = common.cxx; sourceTree = "<group>"; };
+		CD88E9642252D6C700927F40 /* common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -117,6 +122,9 @@
 			isa = PBXGroup;
 			children = (
 				CD2973991D7B401F00E37217 /* logger.cxx */,
+				CD88E9642252D6C700927F40 /* common.h */,
+				CD88E9612252D67A00927F40 /* common.cxx */,
+				CD88E95D2252D3EF00927F40 /* c_logger.cxx */,
 				CD88E9552252BDFC00927F40 /* log_manager.cxx */,
 				CD3C80BE1D6A2CA300ACC795 /* format.cxx */,
 			);
@@ -300,6 +308,8 @@
 				CD29739B1D7B401F00E37217 /* logger.cxx in Sources */,
 				CD88E9572252BDFC00927F40 /* log_manager.cxx in Sources */,
 				CD3C80C01D6A2CA300ACC795 /* format.cxx in Sources */,
+				CD88E95F2252D3EF00927F40 /* c_logger.cxx in Sources */,
+				CD88E9632252D67A00927F40 /* common.cxx in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 50 - 0
src/c_logger.cxx

@@ -0,0 +1,50 @@
+//
+//  c_logger.cxx
+//  logging
+//
+//  Created by Sam Jaffe on 4/1/19.
+//
+
+#include "logger/c_logger.h"
+
+#include "common.h"
+#include "logger/logger_impl.h"
+
+using namespace logging;
+
+c_logger::c_logger(std::string const & name, std::shared_ptr<logger_impl> impl)
+: min_level_(LDEBUG), logger_name_(name), impl_(impl)
+{
+}
+
+c_logger::~c_logger() {
+  if (impl_) impl_->flush();
+}
+
+std::string c_logger::get_header(log_level level) {
+  std::string ts = timestamp();
+  char data[64];
+  snprintf(data, sizeof(data), "[%-5s] %s %s - ",
+           level_header(level), logger_name_.c_str(), ts.c_str());
+  return data;
+}
+
+void c_logger::vlognf(log_level level, size_t num_bytes, char const* fmt,
+                    va_list args) {
+  if (level < min_level_) return;
+  const std::unique_ptr<char[]> data(new char[num_bytes]);
+  int n = vsnprintf(data.get(), num_bytes, fmt, args);
+  if (n >= 0) {
+    data[num_bytes-1] = '\0';
+    log(level, get_header(level) + data.get() + "\n");
+  }
+}
+
+void c_logger::log(log_level level, std::string const& msg) {
+  impl_->write(level, msg);
+}
+
+void c_logger::flush() {
+  impl_->flush();
+}
+

+ 34 - 0
src/common.cxx

@@ -0,0 +1,34 @@
+//
+//  common.cxx
+//  logging
+//
+//  Created by Sam Jaffe on 4/1/19.
+//
+
+#include "common.h"
+
+#include <cassert>
+
+#define X(l)          \
+  case logging::L##l: \
+    return #l;
+const char* logging::level_header(log_level l) {
+  assert(l != logging::LNONE);
+  switch (l) {
+    X(FATAL)
+    X(CRITICAL)
+    X(ERROR)
+    X(WARNING)
+    X(INFO)
+    X(DEBUG)
+    X(TRACE)
+    X(NONE)
+  }
+}
+#undef X
+
+timeval logging::now() {
+  struct timeval tv;
+  gettimeofday( &tv, nullptr );
+  return tv;
+}

+ 21 - 0
src/common.h

@@ -0,0 +1,21 @@
+//
+//  common.hpp
+//  logging
+//
+//  Created by Sam Jaffe on 4/1/19.
+//
+
+#pragma once
+
+#include <sys/time.h>
+
+#include "logger/logger_fwd.h"
+
+namespace logging {
+  const char* level_header(log_level l);
+  timeval now();
+  
+  std::ostream & operator<<(std::ostream & os, log_level l) {
+    return os << std::string(level_header(l));
+  }
+}

+ 6 - 39
src/logger.cxx

@@ -5,6 +5,8 @@
 //  Created by Sam Jaffe on 9/3/16.
 //
 
+#include "logger/logger.h"
+
 #include <sys/time.h>
 
 #include <cassert>
@@ -13,39 +15,10 @@
 #include <map>
 #include <stdexcept>
 
-#include "logger/logger.h"
+#include "common.h"
+#include "logger/logger_impl.h"
 //#include "properties.hpp"
 
-namespace logging {
-#define X(l) \
-case logging::L##l: \
-return #l;
-  
-  const char* level_header(log_level l) {
-    assert(l != logging::LNONE);
-    switch (l) {
-        X(FATAL)
-        X(CRITICAL)
-        X(ERROR)
-        X(WARNING)
-        X(INFO)
-        X(DEBUG)
-        X(TRACE)
-        X(NONE)
-    }
-  }
-  
-#undef X
-}
-
-namespace {
-  struct timeval now( ) {
-    struct timeval tv;
-    gettimeofday( &tv, nullptr );
-    return tv;
-  }
-}
-
 namespace logging {
   logger::logger(std::string const & name, std::shared_ptr<logger_impl> impl)
   : min_level_(LDEBUG), logger_name_(name), impl_(impl)
@@ -58,10 +31,10 @@ namespace logging {
   
   void logger::log(log_level ll, location_info info,
                    std::string const & msg) {
-    impl_->write({ now( ), ll, info, logger_name_.c_str(), msg });
+    impl_->write({ now(), ll, info, logger_name_.c_str(), msg });
   }
   
-  bool logger::should_log( log_level ll ) const {
+  bool logger::should_log(log_level ll) const {
     return ll >= min_level_ && impl_->should_log( ll );
   }
   
@@ -69,9 +42,3 @@ namespace logging {
     impl_->flush();
   }
 }
-
-namespace logging {
-  bool logger_impl::should_log( log_level ll ) const {
-    return ll >= min_log_level;
-  }
-}

+ 3 - 1
test/logger_test.cxx

@@ -8,6 +8,7 @@
 #include <gmock/gmock.h>
 
 #include "logger/logger.h"
+#include "logger/logger_impl.h"
 
 namespace logging {
   void PrintTo(location_info const & info, std::ostream * os) {
@@ -19,7 +20,7 @@ namespace logging {
     }
   }
   void PrintTo(logpacket const & pkt, std::ostream * os) {
-    (*os) << "{ " << logging::level_header(pkt.level) << ", ";
+    (*os) << "{ " << pkt.level << ", ";
     PrintTo(pkt.info, os);
     (*os) << ", \"" << pkt.logger << "\", \"" << pkt.message << "\" }";
   }
@@ -34,6 +35,7 @@ struct MockLoggerImpl : public logging::logger_impl {
   }
   MOCK_METHOD0(flush, void());
   MOCK_METHOD1(write, void(logging::logpacket const &));
+  MOCK_METHOD2(write, void(logging::log_level, std::string const &));
 };
 
 struct LoggerTest : public testing::Test {