Log4j1Test.groovy 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * Copyright The OpenTelemetry Authors
  3. * SPDX-License-Identifier: Apache-2.0
  4. */
  5. import io.opentelemetry.api.common.AttributeKey
  6. import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
  7. import io.opentelemetry.api.logs.Severity
  8. import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
  9. import org.apache.log4j.Logger
  10. import org.apache.log4j.MDC
  11. import org.apache.log4j.helpers.Loader
  12. import spock.lang.Unroll
  13. import static org.assertj.core.api.Assertions.assertThat
  14. import static org.awaitility.Awaitility.await
  15. class Log4j1Test extends AgentInstrumentationSpecification {
  16. static {
  17. // this is needed because log4j1 incorrectly thinks the initial releases of Java 10-19
  18. // (which have no '.' in their versions since there is no minor version) are Java 1.1,
  19. // which is before ThreadLocal was introduced and so log4j1 disables MDC functionality
  20. // (and the MDC tests below fail)
  21. Loader.java1 = false
  22. }
  23. private static final Logger logger = Logger.getLogger("abc")
  24. @Unroll
  25. def "test method=#testMethod with exception=#exception and parent=#parent"() {
  26. when:
  27. if (parent) {
  28. runWithSpan("parent") {
  29. if (exception) {
  30. logger."$testMethod"("xyz", new IllegalStateException("hello"))
  31. } else {
  32. logger."$testMethod"("xyz")
  33. }
  34. }
  35. } else {
  36. if (exception) {
  37. logger."$testMethod"("xyz", new IllegalStateException("hello"))
  38. } else {
  39. logger."$testMethod"("xyz")
  40. }
  41. }
  42. then:
  43. if (parent) {
  44. waitForTraces(1)
  45. }
  46. if (severity != null) {
  47. await()
  48. .untilAsserted(
  49. () -> {
  50. assertThat(logRecords).hasSize(1)
  51. })
  52. def log = logRecords.get(0)
  53. assertThat(log.getBody().asString()).isEqualTo("xyz")
  54. assertThat(log.getInstrumentationScopeInfo().getName()).isEqualTo("abc")
  55. assertThat(log.getSeverity()).isEqualTo(severity)
  56. assertThat(log.getSeverityText()).isEqualTo(severityText)
  57. if (exception) {
  58. assertThat(log.getAttributes().size()).isEqualTo(5)
  59. assertThat(log.getAttributes().get(SemanticAttributes.EXCEPTION_TYPE)).isEqualTo(IllegalStateException.getName())
  60. assertThat(log.getAttributes().get(SemanticAttributes.EXCEPTION_MESSAGE)).isEqualTo("hello")
  61. assertThat(log.getAttributes().get(SemanticAttributes.EXCEPTION_STACKTRACE)).contains(Log4j1Test.name)
  62. } else {
  63. assertThat(log.getAttributes().size()).isEqualTo(2)
  64. assertThat(log.getAttributes().get(SemanticAttributes.EXCEPTION_TYPE)).isNull()
  65. assertThat(log.getAttributes().get(SemanticAttributes.EXCEPTION_MESSAGE)).isNull()
  66. assertThat(log.getAttributes().get(SemanticAttributes.EXCEPTION_STACKTRACE)).isNull()
  67. }
  68. assertThat(log.getAttributes().get(SemanticAttributes.THREAD_NAME)).isEqualTo(Thread.currentThread().getName())
  69. assertThat(log.getAttributes().get(SemanticAttributes.THREAD_ID)).isEqualTo(Thread.currentThread().getId())
  70. if (parent) {
  71. assertThat(log.getSpanContext()).isEqualTo(traces.get(0).get(0).getSpanContext())
  72. } else {
  73. assertThat(log.getSpanContext().isValid()).isFalse()
  74. }
  75. } else {
  76. Thread.sleep(500) // sleep a bit just to make sure no log is captured
  77. logRecords.size() == 0
  78. }
  79. where:
  80. [args, exception, parent] << [
  81. [
  82. ["debug", null, null],
  83. ["info", Severity.INFO, "INFO"],
  84. ["warn", Severity.WARN, "WARN"],
  85. ["error", Severity.ERROR, "ERROR"]
  86. ],
  87. [true, false],
  88. [true, false]
  89. ].combinations()
  90. testMethod = args[0]
  91. severity = args[1]
  92. severityText = args[2]
  93. }
  94. def "test mdc"() {
  95. when:
  96. MDC.put("key1", "val1")
  97. MDC.put("key2", "val2")
  98. try {
  99. logger.info("xyz")
  100. } finally {
  101. MDC.remove("key1")
  102. MDC.remove("key2")
  103. }
  104. then:
  105. await()
  106. .untilAsserted(
  107. () -> {
  108. assertThat(logRecords).hasSize(1)
  109. })
  110. def log = logRecords.get(0)
  111. assertThat(log.getBody().asString()).isEqualTo("xyz")
  112. assertThat(log.getInstrumentationScopeInfo().getName()).isEqualTo("abc")
  113. assertThat(log.getSeverity()).isEqualTo(Severity.INFO)
  114. assertThat(log.getSeverityText()).isEqualTo("INFO")
  115. assertThat(log.getAttributes().size()).isEqualTo(4)
  116. assertThat(log.getAttributes().get(AttributeKey.stringKey("log4j.mdc.key1"))).isEqualTo("val1")
  117. assertThat(log.getAttributes().get(AttributeKey.stringKey("log4j.mdc.key2"))).isEqualTo("val2")
  118. assertThat(log.getAttributes().get(SemanticAttributes.THREAD_NAME)).isEqualTo(Thread.currentThread().getName())
  119. assertThat(log.getAttributes().get(SemanticAttributes.THREAD_ID)).isEqualTo(Thread.currentThread().getId())
  120. }
  121. }