├── .gitignore ├── pom.xml └── src ├── main └── resources │ └── logback.xml └── test └── java └── StructuredLoggingTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 5 | 6 | # User-specific stuff 7 | .idea/**/workspace.xml 8 | .idea/**/tasks.xml 9 | .idea/**/usage.statistics.xml 10 | .idea/**/dictionaries 11 | .idea/**/shelf 12 | 13 | # Sensitive or high-churn files 14 | .idea/**/dataSources/ 15 | .idea/**/dataSources.ids 16 | .idea/**/dataSources.local.xml 17 | .idea/**/sqlDataSources.xml 18 | .idea/**/dynamic.xml 19 | .idea/**/uiDesigner.xml 20 | .idea/**/dbnavigator.xml 21 | 22 | # Gradle 23 | .idea/**/gradle.xml 24 | .idea/**/libraries 25 | 26 | # Gradle and Maven with auto-import 27 | # When using Gradle or Maven with auto-import, you should exclude module files, 28 | # since they will be recreated, and may cause churn. Uncomment if using 29 | # auto-import. 30 | # .idea/modules.xml 31 | # .idea/*.iml 32 | # .idea/modules 33 | 34 | # CMake 35 | cmake-build-*/ 36 | 37 | # Mongo Explorer plugin 38 | .idea/**/mongoSettings.xml 39 | 40 | # File-based project format 41 | *.iws 42 | 43 | # IntelliJ 44 | out/ 45 | 46 | # mpeltonen/sbt-idea plugin 47 | .idea_modules/ 48 | 49 | # JIRA plugin 50 | atlassian-ide-plugin.xml 51 | 52 | # Cursive Clojure plugin 53 | .idea/replstate.xml 54 | 55 | # Crashlytics plugin (for Android Studio and IntelliJ) 56 | com_crashlytics_export_strings.xml 57 | crashlytics.properties 58 | crashlytics-build.properties 59 | fabric.properties 60 | 61 | # Editor-based Rest Client 62 | .idea/httpRequests 63 | ### Maven template 64 | target/ 65 | pom.xml.tag 66 | pom.xml.releaseBackup 67 | pom.xml.versionsBackup 68 | pom.xml.next 69 | release.properties 70 | dependency-reduced-pom.xml 71 | buildNumber.properties 72 | .mvn/timing.properties 73 | .mvn/wrapper/maven-wrapper.jar 74 | ### Java template 75 | # Compiled class file 76 | *.class 77 | 78 | # Log file 79 | *.log 80 | 81 | # BlueJ files 82 | *.ctxt 83 | 84 | # Mobile Tools for Java (J2ME) 85 | .mtj.tmp/ 86 | 87 | # Package Files # 88 | *.jar 89 | *.war 90 | *.nar 91 | *.ear 92 | *.zip 93 | *.tar.gz 94 | *.rar 95 | 96 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 97 | hs_err_pid* 98 | 99 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | de.jochenchrist 8 | structured-logging 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | org.apache.maven.plugins 14 | maven-compiler-plugin 15 | 16 | 11 17 | 11 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | org.slf4j 27 | slf4j-api 28 | 1.7.26 29 | 30 | 31 | ch.qos.logback 32 | logback-classic 33 | 1.2.3 34 | 35 | 36 | net.logstash.logback 37 | logstash-logback-encoder 38 | 5.2 39 | 40 | 41 | 42 | org.junit.jupiter 43 | junit-jupiter-engine 44 | test 45 | 5.3.2 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/test/java/StructuredLoggingTests.java: -------------------------------------------------------------------------------- 1 | import static net.logstash.logback.argument.StructuredArguments.keyValue; 2 | import static net.logstash.logback.argument.StructuredArguments.kv; 3 | import static net.logstash.logback.argument.StructuredArguments.v; 4 | import static net.logstash.logback.argument.StructuredArguments.value; 5 | 6 | import org.junit.jupiter.api.Test; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.slf4j.MDC; 10 | 11 | class StructuredLoggingTests { 12 | 13 | private static final Logger log = LoggerFactory.getLogger("MyApplication"); 14 | 15 | @Test 16 | void simpleLog() { 17 | log.info("Order {} saved", 123); 18 | } 19 | 20 | @Test 21 | void simpleLog2() { 22 | log.info("Order saved orderId", 123); 23 | } 24 | 25 | @Test 26 | void logValue() { 27 | String orderId = "123"; 28 | log.info("Order {} saved", value("orderId", orderId)); 29 | } 30 | 31 | @Test 32 | void logMdc() { 33 | String orderId = "123"; 34 | try (var ignored = MDC.putCloseable("orderId", orderId)) { 35 | log.info("Order saved"); 36 | } 37 | } 38 | 39 | @Test 40 | void logMdc2() { 41 | String orderId = "123"; 42 | MDC.put("orderId", orderId); 43 | log.info("Order saved"); 44 | MDC.remove("orderId"); 45 | } 46 | 47 | @Test 48 | void logValue2() { 49 | String orderId = "123"; 50 | log.info("Order saved {}", v("orderId", orderId)); 51 | } 52 | 53 | @Test 54 | void logValue3() { 55 | String oldStatus = "NEW"; 56 | String newStatus = "READY"; 57 | log.info("Status changed {}->{}.", v("oldStatus", oldStatus), v("newStatus", newStatus)); 58 | } 59 | 60 | @Test 61 | void logKeyValue() { 62 | String orderId = "123"; 63 | log.info("Order saved {}", keyValue("orderId", orderId)); 64 | } 65 | 66 | @Test 67 | void logKeyValue2() { 68 | String orderId = "123"; 69 | String status = "NEW"; 70 | log.info("Order saved", kv("orderId", orderId), kv("status", status)); 71 | } 72 | 73 | @Test 74 | void logObject() { 75 | Order order = new Order("123", "NEW", null); 76 | log.info("Order saved", kv("order", order)); 77 | } 78 | 79 | static class Order { 80 | String orderId; 81 | String status; 82 | String canceled; 83 | 84 | Order(String orderId, String status, String canceled) { 85 | this.orderId = orderId; 86 | this.status = status; 87 | this.canceled = canceled; 88 | } 89 | 90 | public String getOrderId() { 91 | return orderId; 92 | } 93 | 94 | public String getStatus() { 95 | return status; 96 | } 97 | 98 | public String getCanceled() { 99 | return canceled; 100 | } 101 | } 102 | } 103 | --------------------------------------------------------------------------------