vy commented on code in PR #3586:
URL: https://github.com/apache/logging-log4j2/pull/3586#discussion_r2046314420


##########
log4j-layout-template-json/src/main/resources/GcpLayout.json:
##########
@@ -49,25 +55,15 @@
     "key": "span_id"
   },
   "logging.googleapis.com/trace_sampled": true,
-  "_exception": {
-    "class": {
-      "$resolver": "exception",
-      "field": "className"
-    },
-    "message": {
-      "$resolver": "exception",
-      "field": "message"
-    },
-    "stackTrace": {
-      "$resolver": "pattern",
-      "pattern": "%xEx"
-    }
+  "exception": {
+    "$resolver": "pattern",
+    "pattern": "%xEx"
   },

Review Comment:
   I've figured what is going on. Guess what does `new 
ActiveMQIllegalStateException().printStackTrace()` produce? `%xEx` output? Or 
the JTL output? :wink: The JTL output. `Throwable::printStackTrace` (used by 
both JTL and PL's `%ex`, but not `%xEx`) has the following logic:
   
   ```java
       private void printStackTrace(PrintStreamOrWriter s) {
           // ...
           synchronized(s.lock()) {
               s.println(this);
               StackTraceElement[] trace = getOurStackTrace();
               for (StackTraceElement traceElement : trace)
   ```
   
   That is, first `ActiveMQIllegalStateException::toString` will be invoked 
(due to `s.println(this)`) and then its stack trace will be dumped. But 
`ActiveMQIllegalStateException` has a `toString()` override inherited from its 
parent `ActiveMQException`:
   
   ```java
      @Override
      public String toString() {
         return this.getClass().getSimpleName() + "[errorType=" + type + " 
message=" + getMessage() + "]";
      }
   ```
   
   As a demonstration, consider the following Java program:
   
   ```java
   ActiveMQIllegalStateException exception = new 
ActiveMQIllegalStateException();
   exception.printStackTrace();
   System.out.println("---");
   System.out.println(JsonTemplateLayout
           .newBuilder()
           .setConfiguration(new DefaultConfiguration())
           .setEventTemplate(("{" +
                   "'jtl': {'$resolver': 'exception', 'field': 'stackTrace', 
'stackTrace': {'stringified': true}}, " +
                   "'pl': {'$resolver': 'pattern', 'pattern': '%xEx'}" +
                   "}").replaceAll("'", "\""))
           .build()
           .toSerializable(Log4jLogEvent
                   .newBuilder()
                   .setMessage(new SimpleMessage("AMQ212028: error starting 
server locator"))
                   .setThrown(exception)
                   .build()));
   ```
   
   This produces the following output:
   
   ```
   ActiveMQIllegalStateException[errorType=ILLEGAL_STATE message=]
        at ci.yazi.volkan.Log4jPull3586Test.main(Log4jPull3586Test.java:11)
   ---
   {"jtl":"ActiveMQIllegalStateException[errorType=ILLEGAL_STATE 
message=]\n\tat 
ci.yazi.volkan.Log4jPull3586Test.main(Log4jPull3586Test.java:11)\n","pl":"org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException:
 \n\tat ci.yazi.volkan.Log4jPull3586Test.main(Log4jPull3586Test.java:11) 
[classes/:?]\n"}
   ```
   
   In conclusion, JTL's `exception` resolver and PL's `%ex` delegates to 
`Throwable::printStackTrace`, and, AFAICT, this is the correct behavior. OTOH, 
PL's `%xEx` rolls out its own stack trace dumper, which _misses_ the 
`s.println(this)` that `Throwable::printStackTrace` has (I'd qualify this as a 
bug!), and hence, emits an output which directly starts with the stack trace 
dump.
   
   In the light of this, I'd prefer keeping JTL's exception resolver in 
`GcpLayout.json` instead of relying on the (buggy?) behavior of PL's `%xEx`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscr...@logging.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to