理解Log4J2异常(抛出)输出

huangapple go评论83阅读模式
英文:

Understanding Log4J2 exception(throwing) output

问题

我试图理解Log4J2输出中throwing字段的含义。

这段代码有意生成一个异常,并将异常发送到Log4J2:

class HelloWorld1 {
    private static final Logger logger = LogManager.getLogger(HelloWorld1.class.getName());

    public void method() {
        try {
            System.out.println("Division: " + (1 / 0));
        } catch (Exception ex) {
            logger.error("Got exception", ex);
        }
    }
}

检查日志输出,我得到类似以下的内容:

{
	...
	"level": "ERROR",
	"loggerName": "logforj2.HelloWorld1",
	"message": "Got exception",
	"thrown": {
		"commonElementCount": 0,
		"localizedMessage": "/ by zero",
		"message": "/ by zero",
		"name": "java.lang.ArithmeticException",
		"extendedStackTrace": [
			{
				"class": "logforj2.HelloWorld1",
				"method": "main",
				"file": "HelloWorld1.java",
				"line": 23,
				"exact": true,
				"location": "classes/",
				"version": "?"
			}
		]
	},
	...
}

到目前为止都好,但我在在线示例中看到了与我预期不同的异常输出,这些输出比我预期的有更多的字段:

{
	...
	"level": "DEBUG",
	"message": "Msg",
	"thrown": {
		"commonElementCount": 0,
		"localizedMessage": "testIOEx",
		"message": "testIOEx",
		"name": "java.io.IOException",
		"extendedStackTrace": [
			{
				"class": "org.apache.logging.log4j.core.layout.LogEventFixtures",
				"method": "createLogEvent",
				"file": "LogEventFixtures.java",
				"line": 56,
				"exact": true,
				"location": "test-classes/",
				"version": "?"
			},
			{
				"class": "org.apache.logging.log4j.core.layout.JsonLayoutTest",
				"method": "testAllFeatures",
				"file": "JsonLayoutTest.java",
				"line": 105,
				"exact": true,
				"location": "test-classes/",
				"version": "?"
			}...
		],
		"cause": {
			"commonElementCount": 27,
			"extendedStackTrace": [
				{
					"class": "org.apache.logging.log4j.core.layout.LogEventFixtures",
					"method": "createLogEvent",
					"file": "LogEventFixtures.java",
					"line": 53,
					"exact": false,
					"location": "test-classes/",
					"version": "?"
				}
			],
			"localizedMessage": "testNPEx",
			"message": "testNPEx",
			"name": "java.lang.NullPointerException"
		},
		"suppressed": [
			{
				"commonElementCount": 0,
				"localizedMessage": "I am suppressed exception 1",
				"message": "I am suppressed exception 1",
				"name": "java.lang.IndexOutOfBoundsException",
				"extendedStackTrace": [
					{
						"class": "org.apache.logging.log4j.core.layout.LogEventFixtures",
						"method": "createLogEvent",
						"file": "LogEventFixtures.java",
						"line": 57,
						"exact": true,
						"location": "test-classes/",
						"version": "?"
					},
					{
						"class": "org.apache.logging.log4j.core.layout.JsonLayoutTest",
						"method": "testAllFeatures",
						"file": "JsonLayoutTest.java",
						"line": 105,
						"exact": true,
						"location": "test-classes/",
						"version": "?"
					}...
				]
			},
			{
				"commonElementCount": 0,
				"localizedMessage": "I am suppressed exception 2",
				"message": "I am suppressed exception 2",
				"name": "java.lang.IndexOutOfBoundsException",
				"extendedStackTrace": [
					{
						"class": "org.apache.logging.log4j.core.layout.LogEventFixtures",
						"method": "createLogEvent",
						"file": "LogEventFixtures.java",
						"line": 58,
						"exact": true,
						"location": "test-classes/",
						"version": "?"
					}...
				],
				
			}
		]
	},
	...
}

我的问题是,我不理解大多数字段的含义:

  1. 为什么称为extendedStackTrace?是否有其他非扩展的堆栈跟踪?有何区别?
  2. commonElementCount是什么意思?
  3. localizedMessagemessage之间有什么区别?
  4. cause字段是什么意思?
  5. suppressed字段是什么意思?
英文:

I'm trying to make sense about the output of throwing field of Log4J2 output.

This code deliberately generates an exception and sends the exception to Log4J2:

class HelloWorld1 {
    private static final Logger logger = LogManager.getLogger(HelloWorld1.class.getName());

    public void method() {
        try {
            System.out.println("Division: " + (1 / 0));
        } catch (Exception ex) {
            logger.error("Got exception", ex);
        }
    }

Examining the log output, I get something like this:

{
	...
	"level": "ERROR",
	"loggerName": "logforj2.HelloWorld1",
	"message": "Got exception",
	"thrown": {
		"commonElementCount": 0,
		"localizedMessage": "/ by zero",
		"message": "/ by zero",
		"name": "java.lang.ArithmeticException",
		"extendedStackTrace": [
			{
				"class": "logforj2.HelloWorld1",
				"method": "main",
				"file": "HelloWorld1.java",
				"line": 23,
				"exact": true,
				"location": "classes/",
				"version": "?"
			}
		]
	},
	...
}

So far so good but I see examples online showing a different output for an exception and those outputs have much more fields than I was expecting:

{
	...
	"level": "DEBUG",
	"message": "Msg",
	"thrown": {
		"commonElementCount": 0,
		"localizedMessage": "testIOEx",
		"message": "testIOEx",
		"name": "java.io.IOException",
		"extendedStackTrace": [
			{
				"class": "org.apache.logging.log4j.core.layout.LogEventFixtures",
				"method": "createLogEvent",
				"file": "LogEventFixtures.java",
				"line": 56,
				"exact": true,
				"location": "test-classes/",
				"version": "?"
			},
			{
				"class": "org.apache.logging.log4j.core.layout.JsonLayoutTest",
				"method": "testAllFeatures",
				"file": "JsonLayoutTest.java",
				"line": 105,
				"exact": true,
				"location": "test-classes/",
				"version": "?"
			}...
		],
		"cause": {
			"commonElementCount": 27,
			"extendedStackTrace": [
				{
					"class": "org.apache.logging.log4j.core.layout.LogEventFixtures",
					"method": "createLogEvent",
					"file": "LogEventFixtures.java",
					"line": 53,
					"exact": false,
					"location": "test-classes/",
					"version": "?"
				}
			],
			"localizedMessage": "testNPEx",
			"message": "testNPEx",
			"name": "java.lang.NullPointerException"
		},
		"suppressed": [
			{
				"commonElementCount": 0,
				"localizedMessage": "I am suppressed exception 1",
				"message": "I am suppressed exception 1",
				"name": "java.lang.IndexOutOfBoundsException",
				"extendedStackTrace": [
					{
						"class": "org.apache.logging.log4j.core.layout.LogEventFixtures",
						"method": "createLogEvent",
						"file": "LogEventFixtures.java",
						"line": 57,
						"exact": true,
						"location": "test-classes/",
						"version": "?"
					},
					{
						"class": "org.apache.logging.log4j.core.layout.JsonLayoutTest",
						"method": "testAllFeatures",
						"file": "JsonLayoutTest.java",
						"line": 105,
						"exact": true,
						"location": "test-classes/",
						"version": "?"
					}...
				]
			},
			{
				"commonElementCount": 0,
				"localizedMessage": "I am suppressed exception 2",
				"message": "I am suppressed exception 2",
				"name": "java.lang.IndexOutOfBoundsException",
				"extendedStackTrace": [
					{
						"class": "org.apache.logging.log4j.core.layout.LogEventFixtures",
						"method": "createLogEvent",
						"file": "LogEventFixtures.java",
						"line": 58,
						"exact": true,
						"location": "test-classes/",
						"version": "?"
					}...
				],
				
			}
		]
	},
	...
}

My problem is, I don't understand most of the fields.
For example:

  1. Why is it called extendedStackTrace? Is there any other stack trace that is not extended? What is the difference?
  2. What does commonElementCount mean?
  3. What is the difference between localizedMessage and message?
  4. What does cause field mean?
  5. What does suppressed field mean?

答案1

得分: 1

  1. 输出中所见取决于您选择的布局以及您的配置方式。PatternLayout 描述了3种不同类型的Throwable PatternConverters;默认的ThrowablePatternConverter、ExtendedThrowablePatternConverter 和 RootThrowablePatternConverter。

这些之间的区别是:

  • 默认的ThrowablePatternConverter打印堆栈跟踪,就像您从Throwable.printStackTrace()中看到的那样(实际上,输出是这样生成的)。
  • ExtendedThrowablePatternConverter在堆栈跟踪的每一行中包含了jar的名称和版本。在诊断问题时,这可能非常有帮助。
  • RootThrowablePatternConverter首先打印最内层的“caused by”异常,然后是链中的每个Throwable。换句话说,它以与ThrowablePatternConverter相反的顺序打印异常,这样首先打印出故障的异常,可以节省一些时间。

从您上面的示例中,看起来您正在使用JsonLayout。该布局使用Jackson格式化其输出,并指定LogEvent包括ExtendedStakTrace,其中会包含jar和版本信息。

  1. 当异常链接在一起时,几乎可以肯定每个异常的堆栈帧与其链接的异常具有共同点。一旦找到第一个共同的元素,堆栈跟踪底部的所有其余元素几乎总是共同的。此字段标识与前一个异常中共有多少元素,允许不打印共同元素。

  2. localizedMessage和message在java.lang.Throwable中有记录。

  3. cause是链中的下一个Throwable。它也在java.lang.Throwable中有记录。

  4. suppressed是一组被抑制的异常。同样,请参阅java.lang.Throwable

英文:
  1. What you see in the output depends on the Layout you have chosen and how you configured it. The PatternLayout describes 3 different types of Throwable PatternConverters; the default ThrowablePatternConverter, the ExtendedThrowablePatternConverter, and the RootThrowablePatternConverter.

The difference between these are:

  • The default ThrowablePatternConverter prints a stack trace just as you would see it from Throwable.printStackTrace() (in fact, that is how the output is generated).
  • The ExtendedThrowablePatternConverter includes the name and version of the jar for each line in the stack trace. This can be quite helpful when diagnosing problems.
  • The RootThrowablePatternConverter prints the innermost "caused by" exception first followed by each of the Throwables in the chain. In other words, it prints the Exceptions in the reverse order of the ThrowablePatternConverter so that the exception at fault is printed first, which can save some time.

From your example above it looks like you are using the JsonLayout. That Layout formats its output using Jackson and specifies that the LogEvent includes an ExtendedStakTrace, which would include the jar and version information.

  1. It is almost true that when exceptions are chained the each exception will have stack frames that are common with the exception it is chained with. Once the first common element is found all the rest to the bottom of the stack trace are almost always in common as well. This field identifies how many elements are in common with the predecessor allowing the common elements to be not be printed.
  2. localizedMessage and message are documented in the java.lang.Throwable.
  3. cause is the next Throwable in the chain. It is also documented in java.lang.Throwable.
  4. suppressed is a set of exceptions that were suppressed. Again, see java.lang.Throwable.

huangapple
  • 本文由 发表于 2020年8月17日 03:53:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/63441360.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定