From 88e2f312518006904da607c6c58dd0803b07fa06 Mon Sep 17 00:00:00 2001 From: Heiko Holz Date: Thu, 1 Dec 2022 07:10:54 +0100 Subject: [PATCH] feat(logging): add support for logstash encoder --- inspectit-ocelot-core/build.gradle | 2 + .../logback/LogbackInitializerIntTest.java | 228 +++++++++--------- .../resources/test-logback-with-logstash.xml | 21 ++ 3 files changed, 131 insertions(+), 120 deletions(-) create mode 100644 inspectit-ocelot-core/src/test/resources/test-logback-with-logstash.xml diff --git a/inspectit-ocelot-core/build.gradle b/inspectit-ocelot-core/build.gradle index 2d8e9d673c..cffb7661e5 100644 --- a/inspectit-ocelot-core/build.gradle +++ b/inspectit-ocelot-core/build.gradle @@ -46,6 +46,8 @@ dependencies { // logging "ch.qos.logback:logback-classic:${logbackVersion}", + // logstash support (JSON logging) + "net.logstash.logback:logstash-logback-encoder:7.0.1", // utils "org.apache.commons:commons-lang3:3.+", diff --git a/inspectit-ocelot-core/src/test/java/rocks/inspectit/ocelot/core/logging/logback/LogbackInitializerIntTest.java b/inspectit-ocelot-core/src/test/java/rocks/inspectit/ocelot/core/logging/logback/LogbackInitializerIntTest.java index 239ddb08fe..3b16e9f7d2 100644 --- a/inspectit-ocelot-core/src/test/java/rocks/inspectit/ocelot/core/logging/logback/LogbackInitializerIntTest.java +++ b/inspectit-ocelot-core/src/test/java/rocks/inspectit/ocelot/core/logging/logback/LogbackInitializerIntTest.java @@ -27,6 +27,7 @@ class LogbackInitializerIntTest { private static final String EXCEPTIONS_LOG_FILE = "exceptions.log"; + private static final String AGENT_LOG_FILE = "agent.log"; @Nested @@ -50,7 +51,8 @@ void propertiesSet() { assertThat(System.getProperty(LogbackInitializer.INSPECTIT_LOG_LEVEL)).isNull(); assertThat(System.getProperty(LogbackInitializer.INSPECTIT_LOG_PATH)).isNull(); - assertThat(System.getProperty(LogbackInitializer.INSPECTIT_LOG_SERVICE_NAME)).isEqualTo("[" + environment.getCurrentConfig().getServiceName() + "]"); + assertThat(System.getProperty(LogbackInitializer.INSPECTIT_LOG_SERVICE_NAME)).isEqualTo("[" + environment.getCurrentConfig() + .getServiceName() + "]"); assertThat(System.getProperty(LogbackInitializer.INSPECTIT_LOG_CONSOLE_PATTERN)).isNull(); assertThat(System.getProperty(LogbackInitializer.INSPECTIT_LOG_FILE_PATTERN)).isNull(); @@ -67,32 +69,24 @@ void logMessage() throws Exception { logger.info(testMessage); Path output = Paths.get(tempDirectory.toString(), "inspectit-ocelot"); - Optional agentLog = Files.walk(output) - .filter(p -> p.endsWith(AGENT_LOG_FILE)) - .findFirst(); - assertThat(agentLog) - .isPresent() - .hasValueSatisfying(p -> { - try { - assertThat(Files.lines(p).anyMatch(l -> l.contains(testMessage))).isTrue(); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); + Optional agentLog = Files.walk(output).filter(p -> p.endsWith(AGENT_LOG_FILE)).findFirst(); + assertThat(agentLog).isPresent().hasValueSatisfying(p -> { + try { + assertThat(Files.lines(p).anyMatch(l -> l.contains(testMessage))).isTrue(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); // nothing to error log due to the level - Optional errorLog = Files.walk(output) - .filter(p -> p.endsWith(EXCEPTIONS_LOG_FILE)) - .findFirst(); - assertThat(errorLog) - .isPresent() - .hasValueSatisfying(p -> { - try { - assertThat(Files.readAllLines(p)).isEmpty(); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); + Optional errorLog = Files.walk(output).filter(p -> p.endsWith(EXCEPTIONS_LOG_FILE)).findFirst(); + assertThat(errorLog).isPresent().hasValueSatisfying(p -> { + try { + assertThat(Files.readAllLines(p)).isEmpty(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); } @Test @@ -106,35 +100,27 @@ void logExceptionMessage() throws Exception { logger.warn(testMessage, exception); Path output = Paths.get(tempDirectory.toString(), "inspectit-ocelot"); - Optional agentLog = Files.walk(output) - .filter(p -> p.endsWith(AGENT_LOG_FILE)) - .findFirst(); - assertThat(agentLog) - .isPresent() - .hasValueSatisfying(p -> { - try { - List lines = Files.readAllLines(p); - assertThat(lines.stream().anyMatch(l -> l.contains(testMessage))).isTrue(); - assertThat(lines.stream().anyMatch(l -> l.contains(exceptionMessage))).isTrue(); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); - - Optional errorLog = Files.walk(output) - .filter(p -> p.endsWith(EXCEPTIONS_LOG_FILE)) - .findFirst(); - assertThat(errorLog) - .isPresent() - .hasValueSatisfying(p -> { - try { - List lines = Files.readAllLines(p); - assertThat(lines.stream().anyMatch(l -> l.contains(testMessage))).isTrue(); - assertThat(lines.stream().anyMatch(l -> l.contains(exceptionMessage))).isTrue(); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); + Optional agentLog = Files.walk(output).filter(p -> p.endsWith(AGENT_LOG_FILE)).findFirst(); + assertThat(agentLog).isPresent().hasValueSatisfying(p -> { + try { + List lines = Files.readAllLines(p); + assertThat(lines.stream().anyMatch(l -> l.contains(testMessage))).isTrue(); + assertThat(lines.stream().anyMatch(l -> l.contains(exceptionMessage))).isTrue(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + + Optional errorLog = Files.walk(output).filter(p -> p.endsWith(EXCEPTIONS_LOG_FILE)).findFirst(); + assertThat(errorLog).isPresent().hasValueSatisfying(p -> { + try { + List lines = Files.readAllLines(p); + assertThat(lines.stream().anyMatch(l -> l.contains(testMessage))).isTrue(); + assertThat(lines.stream().anyMatch(l -> l.contains(exceptionMessage))).isTrue(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); } @Test @@ -147,32 +133,24 @@ void logTraceMessage() throws Exception { logger.trace(testMessage); Path output = Paths.get(tempDirectory.toString(), "inspectit-ocelot"); - Optional agentLog = Files.walk(output) - .filter(p -> p.endsWith(AGENT_LOG_FILE)) - .findFirst(); - assertThat(agentLog) - .isPresent() - .hasValueSatisfying(p -> { - try { - assertThat(Files.lines(p).anyMatch(l -> l.contains(testMessage))).isTrue(); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); + Optional agentLog = Files.walk(output).filter(p -> p.endsWith(AGENT_LOG_FILE)).findFirst(); + assertThat(agentLog).isPresent().hasValueSatisfying(p -> { + try { + assertThat(Files.lines(p).anyMatch(l -> l.contains(testMessage))).isTrue(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); // nothing to error log due to the level - Optional errorLog = Files.walk(output) - .filter(p -> p.endsWith(EXCEPTIONS_LOG_FILE)) - .findFirst(); - assertThat(errorLog) - .isPresent() - .hasValueSatisfying(p -> { - try { - assertThat(Files.readAllLines(p)).isEmpty(); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); + Optional errorLog = Files.walk(output).filter(p -> p.endsWith(EXCEPTIONS_LOG_FILE)).findFirst(); + assertThat(errorLog).isPresent().hasValueSatisfying(p -> { + try { + assertThat(Files.readAllLines(p)).isEmpty(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); } @AfterEach @@ -198,15 +176,7 @@ void clean() { } @Nested - @TestPropertySource(properties = { - "inspectit.logging.trace=true", - "inspectit.logging.debug=true", - "inspectit.logging.console.enabled=false", - "inspectit.logging.console.pattern=my-console-pattern", - "inspectit.logging.file.enabled=false", - "inspectit.logging.file.pattern=my-file-pattern", - "inspectit.logging.file.include-service-name=false", - }) + @TestPropertySource(properties = {"inspectit.logging.trace=true", "inspectit.logging.debug=true", "inspectit.logging.console.enabled=false", "inspectit.logging.console.pattern=my-console-pattern", "inspectit.logging.file.enabled=false", "inspectit.logging.file.pattern=my-file-pattern", "inspectit.logging.file.include-service-name=false",}) @DirtiesContext class OverwrittenDefaults extends SpringTestBase { @@ -226,7 +196,8 @@ void propertiesSet() { LogbackInitializer.initLogging(environment.getCurrentConfig()); assertThat(System.getProperty(LogbackInitializer.INSPECTIT_LOG_LEVEL)).isEqualTo("TRACE"); - assertThat(System.getProperty(LogbackInitializer.INSPECTIT_LOG_PATH)).isEqualTo(tempDirectory.toAbsolutePath().toString()); + assertThat(System.getProperty(LogbackInitializer.INSPECTIT_LOG_PATH)).isEqualTo(tempDirectory.toAbsolutePath() + .toString()); assertThat(System.getProperty(LogbackInitializer.INSPECTIT_LOG_SERVICE_NAME)).isEmpty(); assertThat(System.getProperty(LogbackInitializer.INSPECTIT_LOG_CONSOLE_PATTERN)).isEqualTo("my-console-pattern"); assertThat(System.getProperty(LogbackInitializer.INSPECTIT_LOG_FILE_PATTERN)).isEqualTo("my-file-pattern"); @@ -243,20 +214,16 @@ void logMessageFileDisabled() throws Exception { Logger logger = LoggerFactory.getLogger(OverwrittenDefaults.class); logger.info(testMessage); - Optional agentLog = Files.walk(tempDirectory) - .filter(p -> p.endsWith(AGENT_LOG_FILE)) - .findFirst(); + Optional agentLog = Files.walk(tempDirectory).filter(p -> p.endsWith(AGENT_LOG_FILE)).findFirst(); // nothing written - assertThat(agentLog) - .isPresent() - .hasValueSatisfying(p -> { - try { - assertThat(Files.readAllLines(p)).isEmpty(); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); + assertThat(agentLog).isPresent().hasValueSatisfying(p -> { + try { + assertThat(Files.readAllLines(p)).isEmpty(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); } @AfterEach @@ -275,28 +242,10 @@ void clean() throws Exception { } @Nested - @TestPropertySource(properties = { - "inspectit.logging.config-file=src/test/resources/test-logback.xml" - }) - @DirtiesContext - class CustomLogFile extends SpringTestBase { + class CustomLogFiles { private final Path OUTPUT_FILE = Paths.get("test-agent.log"); - @Autowired - InspectitEnvironment environment; - - @Test - void logMessage() throws Exception { - LogbackInitializer.initLogging(environment.getCurrentConfig()); - - String testMessage = "test message with custom config file"; - Logger logger = LoggerFactory.getLogger(CustomLogFile.class); - logger.info(testMessage); - - assertThat(Files.lines(OUTPUT_FILE).anyMatch(l -> l.contains(testMessage))).isTrue(); - } - @AfterEach void clean() throws Exception { ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory(); @@ -311,6 +260,45 @@ void clean() throws Exception { Files.deleteIfExists(OUTPUT_FILE); } - } + @Nested + @TestPropertySource(properties = {"inspectit.logging.config-file=src/test/resources/test-logback.xml"}) + @DirtiesContext + class CustomLogFile extends SpringTestBase { + + @Autowired + InspectitEnvironment environment; + + @Test + void logMessage() throws Exception { + LogbackInitializer.initLogging(environment.getCurrentConfig()); + + String testMessage = "test message with custom config file"; + Logger logger = LoggerFactory.getLogger(CustomLogFile.class); + logger.info(testMessage); + + assertThat(Files.lines(OUTPUT_FILE).anyMatch(l -> l.contains(testMessage))).isTrue(); + } + } + + @Nested + @TestPropertySource(properties = {"inspectit.logging.config-file=src/test/resources/test-logback-with-logstash.xml"}) + @DirtiesContext + class CustomLogFileWithLogstash extends SpringTestBase { + + @Autowired + InspectitEnvironment environment; + + @Test + void logMessageJson() throws Exception { + LogbackInitializer.initLogging(environment.getCurrentConfig()); + + String testMessage = "test message with custom config file that contains logstash encoders"; + Logger logger = LoggerFactory.getLogger(CustomLogFileWithLogstash.class); + logger.info(testMessage); + String regex = "\\{.*" + testMessage + ".*}"; + assertThat(Files.lines(OUTPUT_FILE).anyMatch(l -> l.matches(regex))).isTrue(); + } + } + } } \ No newline at end of file diff --git a/inspectit-ocelot-core/src/test/resources/test-logback-with-logstash.xml b/inspectit-ocelot-core/src/test/resources/test-logback-with-logstash.xml new file mode 100644 index 0000000000..3d252cd6e9 --- /dev/null +++ b/inspectit-ocelot-core/src/test/resources/test-logback-with-logstash.xml @@ -0,0 +1,21 @@ + + + test-agent.log + true + + + + + { "loglevel": "%level", "datetime": "%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ}", "type": + "message", "loggerName": "%logger","thread": "%thread","message": "%message", "exception": + "%exception" } + + + + + + + + + +