This is an automated email from the ASF dual-hosted git repository. vy pushed a commit to branch release-2.x in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit e4f651725f07f2b90374c68075ca42de0771102c Author: Volkan Yazici <[email protected]> AuthorDate: Tue Jan 19 16:03:29 2021 +0100 LOG4J2-2999 Replace JsonTemplateLayout resolver configurations table in docs with sections. --- .../template/json/resolver/TemplateResolvers.java | 6 +- src/changes/changes.xml | 3 + .../asciidoc/manual/json-template-layout.adoc.vm | 330 +++++++++++---------- 3 files changed, 175 insertions(+), 164 deletions(-) diff --git a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolvers.java b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolvers.java index 737ed87..d713edd 100644 --- a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolvers.java +++ b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolvers.java @@ -385,8 +385,10 @@ public final class TemplateResolvers { else { final String replacedText = context.getSubstitutor().replace(null, fieldValue); if (replacedText == null) { - // noinspection unchecked - return (TemplateResolver<V>) NULL_RESOLVER; + @SuppressWarnings("unchecked") + final TemplateResolver<V> resolver = + (TemplateResolver<V>) NULL_RESOLVER; + return resolver; } else { // Prepare the escaped replacement first. final String escapedReplacedText = diff --git a/src/changes/changes.xml b/src/changes/changes.xml index faa9b94..cb9faea 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -30,6 +30,9 @@ - "remove" - Removed --> <release version="2.14.1" date="2021-MM-DD" description="GA Release 2.14.1"> + <action issue="LOG4J2-2999" dev="vy" type="add"> + Replace JsonTemplateLayout resolver configurations table in docs with sections. + </action> <action issue="LOG4J2-2993" dev="vy" type="add"> Support stack trace truncation in JsonTemplateLayout. </action> diff --git a/src/site/asciidoc/manual/json-template-layout.adoc.vm b/src/site/asciidoc/manual/json-template-layout.adoc.vm index ff57244..cddcba9 100644 --- a/src/site/asciidoc/manual/json-template-layout.adoc.vm +++ b/src/site/asciidoc/manual/json-template-layout.adoc.vm @@ -409,23 +409,14 @@ templates: `JsonTemplateLayout` employs the `StackTraceElementLayout.json` template for stack traces to generate a document-store-friendly flat structure.) -Below is the list of supported event template resolvers: - [#event-template-resolvers] -.`LogEvent` template resolvers -[cols="1m,3,2,2,4"] -|=== -| Resolver Name -| Syntax -| Description -| Garbage Footprint -| Examples +==== Event Template Resolvers + +[#event-template-resolver-endOfBatch] +===== `endOfBatch` + +Resolves `logEvent.isEndOfBatch()` boolean flag: -| endOfBatch -| -| `logEvent.isEndOfBatch()` -| none -a| [source,json] ---- { @@ -433,8 +424,9 @@ a| } ---- -| exception -a| +[#event-template-resolver-exception] +===== `exception` + [source] ---- config = field , [ stringified ] , [ stackTrace ] @@ -451,7 +443,7 @@ suffix = "suffix" -> string pointMatcherStrings = "pointMatcherStrings" -> string[] pointMatcherRegexes = "pointMatcherRegexes" -> string[] ---- -a| + Resolves fields of the `Throwable` returned by `logEvent.getThrown()`. `stringified` is set to `false` by default. `stringified` at the root level is @@ -468,13 +460,16 @@ the layout, unless explicitly provided. Note that this resolver is toggled by `log4j.layout.jsonTemplate.stackTraceEnabled` property. -a| + +[WARNING] +==== Since `Throwable#getStackTrace()` clones the original `StackTraceElement[]`, access to (and hence rendering of) stack traces are not garbage-free. Each `pointMatcherRegexes` item triggers a `Pattern#matcher()` call, which is -not garbage-free. -a| +not garbage-free either. +==== + Resolve `logEvent.getThrown().getClass().getCanonicalName()`: [source,json] @@ -527,26 +522,26 @@ truncated by the given point matcher: } ---- -| exceptionRootCause -| identical to `exception` resolver -| identical to `exception` resolver with the exception that the innermost - `Throwable` in the causal-chain of `logEvent.getThrown()` is resolved -| identical to `exception` resolver -| identical to `exception` resolver with the exception that `${dollar}resolver` - field needs to be set to `exceptionRootCause` +[#event-template-resolver-exceptionRootCause] +===== `exceptionRootCause` + +Resolves the fields of the innermost `Throwable` returned by +`logEvent.getThrown()`. Its syntax and garbage-footprint are identical to the +link:#event-template-exception[`exception`] resolver. + +[#event-template-resolver-level] +===== `level` -| level -a| [source] ---- config = field , [ severity ] -field = "field" -> ( "name" \| "severity" ) +field = "field" -> ( "name" | "severity" ) severity = severity-field -severity-field = "field" -> ( "keyword" \| "code" ) +severity-field = "field" -> ( "keyword" | "code" ) ---- -| resolves the fields of the `logEvent.getLevel()` -| none -a| + +Resolves the fields of the `logEvent.getLevel()`. + Resolve the level name: [source,json] @@ -585,15 +580,16 @@ code: } ---- -| logger -a| +[#event-template-resolver-logger] +===== `logger` + [source] ---- -config = "field" -> ( "name" \| "fqcn" ) +config = "field" -> ( "name" | "fqcn" ) ---- -| resolves `logEvent.getLoggerFqcn()` and `logEvent.getLoggerName()` -| none -a| + +Resolves `logEvent.getLoggerFqcn()` and `logEvent.getLoggerName()`. + Resolve the logger name: [source,json] @@ -614,18 +610,19 @@ Resolve the logger's fully qualified class name: } ---- -| main -a| +[#event-template-resolver-main] +===== `main` + [source] ---- -config = ( index \| key ) +config = ( index | key ) index = "index" -> number key = "key" -> string ---- -| performs link:lookups.html#AppMainArgsLookup[Main Argument Lookup] for the - given `index` or `key` -| none -a| + +Performs link:lookups.html#AppMainArgsLookup[Main Argument Lookup] for the +given `index` or `key`. + Resolve the 1st `main()` method argument: [source,json] @@ -646,32 +643,42 @@ Resolve the argument coming right after `--userId`: } ---- -| map -| see link:#map-resolver-template[Map Resolver Template] -| resolves ``MapMessage``s -| see link:#map-resolver-template[Map Resolver Template] -| see link:#map-resolver-template[Map Resolver Template] +[#event-template-resolver-map] +===== `map` -| mdc -| see link:#map-resolver-template[Map Resolver Template] -| resolves Mapped Diagnostic Context (MDC), aka. Thread Context Data -| `log4j2.garbagefreeThreadContextMap` flag needs to be turned on to iterate - the map without allocations. See - link:#map-resolver-template[Map Resolver Template] for other details. -| see link:#map-resolver-template[Map Resolver Template] +Resolves ``MapMessage``s. See link:#map-resolver-template[Map Resolver Template] +for details. + +[#event-template-resolver-mdc] +===== `mdc` + +Resolves Mapped Diagnostic Context (MDC), aka. Thread Context Data. See +link:#map-resolver-template[Map Resolver Template] for details. + +[WARNING] +==== +`log4j2.garbagefreeThreadContextMap` flag needs to be turned on to iterate +the map without allocations. +==== + +[#event-template-resolver-message] +===== `message` -| message -a| [source] ---- config = [ stringified ] , [ fallbackKey ] stringified = "stringified" -> boolean fallbackKey = "fallbackKey" -> string ---- -a| `logEvent.getMessage()` -| For simple string messages, the resolution is performed without allocations. - For ``ObjectMessage``s and ``MultiformatMessage``s, it depends. -a| + +Resolves `logEvent.getMessage()`. + +[WARNING] +==== +For simple string messages, the resolution is performed without allocations. +For ``ObjectMessage``s and ``MultiformatMessage``s, it depends. +==== + Resolve the message into a string: [source,json] @@ -713,20 +720,26 @@ Using this configuration, a `SimpleMessage` will generate a `{"action": "login", "sessionId": "87asd97a"}`. Note that both emitted JSONs are of type `object` and have no type-conflicting fields. -| messageParameter -a| +[#event-template-resolver-messageParameter] +===== `messageParameter` + [source] ---- config = [ stringified ] , [ index ] stringified = "stringified" -> boolean index = "index" -> number ---- -| `logEvent.getMessage().getParameters()` -| `stringified` flag translates to `String.valueOf(value)`, hence mind - not-`String`-typed values. Further, `logEvent.getMessage()` is expected to - implement `ParameterVisitable` interface, which is the case if - `log4j2.enableThreadlocals` property set to true. -a| + +Resolves `logEvent.getMessage().getParameters()`. + +[WARNING] +==== +Regarding garbage footprint, `stringified` flag translates to +`String.valueOf(value)`, hence mind not-`String`-typed values. Further, +`logEvent.getMessage()` is expected to implement `ParameterVisitable` interface, +which is the case if `log4j2.enableThreadLocals` property set to true. +==== + Resolve the message parameters into an array: [source,json] @@ -767,17 +780,18 @@ Resolve the string representation of the first message parameter: } ---- -| ndc -a| +[#event-template-resolver-ndc] +===== `ndc` + [source] ---- config = [ pattern ] pattern = "pattern" -> string ---- -| Resolves the Nested Diagnostic Context (NDC), aka. Thread Context Stack, - `String[]` returned by `logEvent.getContextStack()` -| none -a| + +Resolves the Nested Diagnostic Context (NDC), aka. Thread Context Stack, +`String[]` returned by `logEvent.getContextStack()`. + Resolve all NDC values into a list: [source,json] @@ -793,25 +807,25 @@ Resolve all NDC values matching with the `pattern` regex: ---- { "$resolver": "ndc", - "pattern": "user(Role\|Rank):\\w+" + "pattern": "user(Role|Rank):\\w+" } ---- -| pattern -a| +[#event-template-resolver-pattern] +===== `pattern` + [source] ---- config = pattern , [ stackTraceEnabled ] pattern = "pattern" -> string stackTraceEnabled = "stackTraceEnabled" -> boolean ---- -a| + Resolver delegating to link:layouts.html#PatternLayout[`PatternLayout`]. The default value of `stackTraceEnabled` is inherited from the parent `JsonTemplateLayout`. -| none -a| + Resolve the string produced by `%p %c{1.} [%t] %X{userId} %X %m%ex` pattern: [source,json] @@ -822,24 +836,24 @@ Resolve the string produced by `%p %c{1.} [%t] %X{userId} %X %m%ex` pattern: } ---- -| source -a| +[#event-template-resolver-source] +===== `source` + [source] ---- config = "field" -> ( - "className" \| - "fileName" \| - "methodName" \| + "className" | + "fileName" | + "methodName" | "lineNumber" ) ---- -a| + Resolves the fields of the `StackTraceElement` returned by `logEvent.getSource()`. Note that this resolver is toggled by `log4j.layout.jsonTemplate.locationInfoEnabled` property. -| none -a| + Resolve the line number: [source,json] @@ -850,16 +864,17 @@ Resolve the line number: } ---- -| thread -a| +[#event-template-resolver-thread] +===== `thread` + [source] ---- -config = "field" -> ( "name" \| "id" \| "priority" ) +config = "field" -> ( "name" | "id" | "priority" ) ---- -| resolves `logEvent.getThreadId()`, `logEvent.getThreadName()`, - `logEvent.getThreadPriority()` -| none -a| + +Resolves `logEvent.getThreadId()`, `logEvent.getThreadName()`, +`logEvent.getThreadPriority()`. + Resolve the thread name: [source,json] @@ -870,53 +885,51 @@ Resolve the thread name: } ---- -| timestamp -a| +[#event-template-resolver-timestamp] +===== `timestamp` + [source] ---- -config = [ patternConfig \| epochConfig ] +config = [ patternConfig | epochConfig ] -patternConfig = "pattern" -> ( - [ format ] , - [ timeZone ] , - [ locale ] ) +patternConfig = "pattern" -> ( [ format ] , [ timeZone ] , [ locale ] ) format = "format" -> string timeZone = "timeZone" -> string locale = "locale" -> ( - language \| - ( language , "_" , country ) \| + language | + ( language , "_" , country ) | ( language , "_" , country , "_" , variant ) - ) + ) epochConfig = "epoch" -> ( unit , [ rounded ] ) unit = "unit" -> ( - "nanos" \| - "millis" \| - "secs" \| - "millis.nanos" \| - "secs.nanos" \| + "nanos" | + "millis" | + "secs" | + "millis.nanos" | + "secs.nanos" | ) rounded = "rounded" -> boolean ---- -| resolves `logEvent.getInstant()` in various forms -| none -a| + +Resolves `logEvent.getInstant()` in various forms. + .`timestamp` template resolver examples [cols="5,2m"] -!=== -! Configuration -! Output +|=== +| Configuration +| Output -a! +a| [source,json] ---- { "$resolver": "timestamp" } ---- -! 2020-02-07T13:38:47.098+02:00 +| 2020-02-07T13:38:47.098+02:00 -a! +a| [source,json] ---- { @@ -928,9 +941,9 @@ a! } } ---- -! 2020-02-07T13:38:47.098Z +| 2020-02-07T13:38:47.098Z -a! +a| [source,json] ---- { @@ -940,9 +953,9 @@ a! } } ---- -! 1581082727.982123456 +| 1581082727.982123456 -a! +a| [source,json] ---- { @@ -953,9 +966,9 @@ a! } } ---- -! 1581082727 +| 1581082727 -a! +a| [source,json] ---- { @@ -965,9 +978,9 @@ a! } } ---- -! 982123456 +| 982123456 -a! +a| [source,json] ---- { @@ -977,9 +990,9 @@ a! } } ---- -! 1581082727982.123456 +| 1581082727982.123456 -a! +a| [source,json] ---- { @@ -990,9 +1003,9 @@ a! } } ---- -! 1581082727982 +| 1581082727982 -a! +a| [source,json] ---- { @@ -1002,9 +1015,9 @@ a! } } ---- -! 123456 +| 123456 -a! +a| [source,json] ---- { @@ -1014,8 +1027,7 @@ a! } } ---- -! 1581082727982123456 -!=== +| 1581082727982123456 |=== [#map-resolver-template] @@ -1029,19 +1041,9 @@ these are provided by a single backend: `ReadOnlyStringMapResolver`. Put another way, both `mdc` and `map` resolvers support identical configuration, behaviour, and garbage footprint, which are detailed below. -[#stringmap-template-resolver] -.`ReadOnlyStringMap` template resolver -[cols="3,2,2,4"] -|=== -| Syntax -| Description -| Garbage Footprint -| Examples - -a| [source] ---- -config = singleAccess \| multiAccess +config = singleAccess | multiAccess singleAccess = key , [ stringified ] key = "key" -> string @@ -1049,16 +1051,21 @@ stringified = "stringified" -> boolean multiAccess = [ pattern ] , [ flatten ] , [ stringified ] pattern = "pattern" -> string -flatten = "flatten" -> ( boolean \| flattenConfig ) +flatten = "flatten" -> ( boolean | flattenConfig ) flattenConfig = [ flattenPrefix ] flattenPrefix = "prefix" -> string ---- -| `singleAccess` resolves a single field, whilst `multiAccess` resolves a - multitude of fields. If `flatten` is provided, `multiAccess` merges the fields - with the parent, otherwise creates a new JSON object containing the values. -| `stringified` flag translates to `String.valueOf(value)`, hence mind - not-`String`-typed values. -a| + +`singleAccess` resolves a single field, whilst `multiAccess` resolves a +multitude of fields. If `flatten` is provided, `multiAccess` merges the fields +with the parent, otherwise creates a new JSON object containing the values. + +[WARNING] +==== +Regarding garbage footprint, `stringified` flag translates to +`String.valueOf(value)`, hence mind not-`String`-typed values. +==== + `"${dollar}resolver"` is left out in the following examples, since it is to be defined by the actual resolver, e.g., `map`, `mdc`. @@ -1102,7 +1109,7 @@ Resolve all fields into an object such that values are converted to string: } ---- -Merge all fields whose keys are matching with the `user(Role\|Rank)` regex into +Merge all fields whose keys are matching with the `user(Role|Rank)` regex into the parent: [source,json] @@ -1110,7 +1117,7 @@ the parent: { "$resolver": "…", "flatten": true, - "pattern": "user(Role\|Rank)" + "pattern": "user(Role|Rank)" } ---- @@ -1127,7 +1134,6 @@ parent such that keys are prefixed with `_`: } } ---- -|=== [#stack-trace-element-templates] === Stack Trace Element Templates
