Bläddra i källkod

Start writing JSON Layout tests.

Sam Jaffe 6 år sedan
förälder
incheckning
3fbb44a785

+ 6 - 0
include/logger/logger_fwd.h

@@ -20,6 +20,12 @@ namespace logging {
     int line = 0;
     char const * function = "";
   };
+  
+#if defined( _WIN32 )
+  constexpr char const * const NEWLINE_TOKEN{"\r\n"};
+#else
+  constexpr char const * const NEWLINE_TOKEN{"\n"};
+#endif
 }
 
 #define LIST_OF_LOGGING_LEVELS \

+ 4 - 0
logger.xcodeproj/project.pbxproj

@@ -26,6 +26,7 @@
 		CD760CB922621776008A62DE /* pattern_layout_test.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CD760CB822621776008A62DE /* pattern_layout_test.cxx */; };
 		CD760CBF226221F6008A62DE /* console_appender_test.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CD760CBE226221F6008A62DE /* console_appender_test.cxx */; };
 		CD760CC1226226CC008A62DE /* file_appender_test.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CD760CC0226226CC008A62DE /* file_appender_test.cxx */; };
+		CD760CC922627202008A62DE /* json_layout_test.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CD760CC822627202008A62DE /* json_layout_test.cxx */; };
 		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 */; };
@@ -97,6 +98,7 @@
 		CD760CB822621776008A62DE /* pattern_layout_test.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = pattern_layout_test.cxx; sourceTree = "<group>"; };
 		CD760CBE226221F6008A62DE /* console_appender_test.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = console_appender_test.cxx; sourceTree = "<group>"; };
 		CD760CC0226226CC008A62DE /* file_appender_test.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = file_appender_test.cxx; sourceTree = "<group>"; };
+		CD760CC822627202008A62DE /* json_layout_test.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = json_layout_test.cxx; 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>"; };
@@ -182,6 +184,7 @@
 				CD6F73FC225187E10081ED74 /* logger_test.cxx */,
 				CD1CDEB22256B04600E5B6B2 /* format_test.cxx */,
 				CD760CB822621776008A62DE /* pattern_layout_test.cxx */,
+				CD760CC822627202008A62DE /* json_layout_test.cxx */,
 				CD760CBE226221F6008A62DE /* console_appender_test.cxx */,
 				CD760CC0226226CC008A62DE /* file_appender_test.cxx */,
 				CD1CDE8C22540D9B00E5B6B2 /* c_logger_test.cxx */,
@@ -384,6 +387,7 @@
 				CD760CB922621776008A62DE /* pattern_layout_test.cxx in Sources */,
 				CD760CC1226226CC008A62DE /* file_appender_test.cxx in Sources */,
 				CD1CDE9222543E7E00E5B6B2 /* test_properties.cxx in Sources */,
+				CD760CC922627202008A62DE /* json_layout_test.cxx in Sources */,
 				CD1CDEB32256B04600E5B6B2 /* format_test.cxx in Sources */,
 				CD1CDE8D22540D9B00E5B6B2 /* c_logger_test.cxx in Sources */,
 			);

+ 1 - 7
src/format.cxx

@@ -21,12 +21,6 @@
 #include "logger/logger.h"
 #include "logger/logpacket.h"
 
-#if defined( _WIN32 )
-# define NEWLINE "\r\n"
-#else
-# define NEWLINE "\n"
-#endif
-
 namespace logging {
   std::string fmt_time_with_milis(struct timeval, std::string const &);
   string_generator parse_date_format_string(char const *);
@@ -125,7 +119,7 @@ namespace logging {
         out.gen.push_back(convert(date_token(next)));
         if (is('{')) next = std::strchr(next, '}');
       } else if (is('n')) {
-        out.gen.push_back(convert(string_token(NEWLINE)));
+        out.gen.push_back(convert(string_token(NEWLINE_TOKEN)));
       } else if (is('%')) {
         out.gen.push_back(convert(string_token("%")));
       } else if (is('.') || is('-') || isdigit( *next )) {

+ 49 - 0
src/loggers/json_layout.cxx

@@ -5,10 +5,26 @@
 //  Created by Sam Jaffe on 4/7/19.
 //
 
+#include "resource_factory/prototype_factory.hpp"
+
+#include "logger/detail/layout.h"
+#include "logger/log_manager.h"
+#include "logger/logpacket.h"
 #include "logger/properties.h"
 
 using namespace logging;
 
+class json_layout : public layout {
+public:
+  static std::shared_ptr<layout> create(properties const &);
+  
+  json_layout(properties const & props);
+  void format(std::ostream & os, logpacket const & pkt) const override;
+  
+private:
+  bool compact_, eol_, log_as_json_;
+};
+
 using namespace logging::property;
 properties const DEFAULT_JSON_LAYOUT{_obj({
   {"charset", _v("en_US.UTF-8")},
@@ -19,3 +35,36 @@ properties const DEFAULT_JSON_LAYOUT{_obj({
   {"includeNullDelimiter", _v(false)},
   {"objectMessageAsJsonObject", _v(false)}
 })};
+
+std::shared_ptr<layout> json_layout::create(properties const & props) {
+  properties const actual = DEFAULT_JSON_LAYOUT.mergedWith(props);
+  return std::make_shared<json_layout>(actual);
+}
+
+json_layout::json_layout(properties const & props)
+: compact_(props["compact"]),
+  eol_(props["eventEol"]),
+  log_as_json_(props["objectMessageAsJsonObject"]) {
+  
+}
+
+static void write_timestamp(std::ostream & os, struct timeval time) {
+  os << "\"instant\": {\n    \"epochSecond\": " << time.tv_sec;
+  os << ",\n    \"nanoOfSecond\": " << (time.tv_usec * 1000) << "\n  }";
+}
+
+void json_layout::format(std::ostream & os, logpacket const & pkt) const {
+  os << "{\n  ";
+  write_timestamp(os, pkt.time);
+  os << "\n  \"level\": \"" << pkt.level << "\",";
+  os << "\n  \"loggerName\": \"" << pkt.logger << "\",";
+  os << "\n  \"message\": \"" << pkt.message.str() << "\"";
+  os << "\n}";
+  if (eol_) {
+    os << NEWLINE_TOKEN;
+  }
+}
+
+namespace {
+  bool _ = layouts::instance().bind("JsonLayout", json_layout::create);
+}

+ 46 - 0
test/json_layout_test.cxx

@@ -0,0 +1,46 @@
+//
+//  json_layout_test.cxx
+//  logger_test
+//
+//  Created by Sam Jaffe on 4/13/19.
+//
+
+#include <gmock/gmock.h>
+
+#include "resource_factory/prototype_factory.hpp"
+
+#include "logger/detail/layout.h"
+#include "logger/log_manager.h"
+#include "logger/logpacket.h"
+#include "logger/properties.h"
+
+TEST(JsonLayoutTest, CanConstructWithNoConfig) {
+  EXPECT_NO_THROW(logging::layouts::instance().get("JsonLayout", {}));
+}
+
+// Thursday, April 4, 2019 6:17:20 PM GMT
+namespace {
+  constexpr const int NOW = 1554401840;
+}
+
+std::string const formatted_output = R"({
+  "instant": {
+    "epochSecond": 1554401840,
+    "nanoOfSecond": 123456000
+  }
+  "level": "warning",
+  "loggerName": "UnitTest",
+  "message": "This is a test message"
+})";
+
+TEST(JsonLayoutTest, TestInvokesFormatter) {
+  using namespace logging;
+  auto playout = layouts::instance().get("JsonLayout", {});
+  
+  std::stringstream ss;
+  playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest",
+    "This is a test message"});
+    
+  using testing::Eq;
+  EXPECT_THAT(ss.str(), Eq(formatted_output));
+}