diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.json b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.json new file mode 100644 index 00000000000..a8a4eb0b9bb --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.json @@ -0,0 +1,29 @@ +{ + "Configuration": { + "Appenders": { + "File": { + "name": "MAIN", + // tag::select[] + "Select": { + "SystemPropertyArbiter": { // <1> + "propertyName": "env", + "propertyValue": "dev", + "PatternLayout": {} + }, + "DefaultArbiter": { // <2> + "JsonTemplateLayout": {} + } + } + // end::select[] + } + }, + "Loggers": { + "Root": { + "level": "INFO", + "AppenderRef": { + "ref": "MAIN" + } + } + } + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.properties new file mode 100644 index 00000000000..8fa74a1d8ee --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.properties @@ -0,0 +1,32 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +appender.0.type = File +appender.0.name = MAIN +# tag::select[] +appender.0.select.type = Select + +appender.0.select.0.type = SystemPropertyArbiter # <1> +appender.0.select.0.propertyName = env +appender.0.select.0.propertyValue = dev +appender.0.select.0.layout.type = PatternLayout + +appender.0.select.1.type = DefaultArbiter # <2> +appender.0.select.1.layout.type = JsonTemplateLayout +# end::select[] + +rootLogger.level = INFO +rootLogger.appenderRef.0.ref = MAIN diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.xml new file mode 100644 index 00000000000..a7190f30183 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.yaml new file mode 100644 index 00000000000..046b09fc08a --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.yaml @@ -0,0 +1,35 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Configuration: + Appenders: + File: + name: "MAIN" + fileName: "logs/app.log" + # tag::select[] + Select: + SystemPropertyArbiter: # <1> + propertyName: "env" + propertyValue: "dev" + PatternLayout: {} + DefaultArbiter: # <2> + JsonTemplateLayout: {} + # end::select[] + Loggers: + Root: + level: "INFO" + AppenderRef: + ref: "MAIN" diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.json b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.json new file mode 100644 index 00000000000..d732aaaa7ae --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.json @@ -0,0 +1,33 @@ +{ + "Configuration": { + "Appenders": { + "File": { + "name": "MAIN", + "SystemPropertyArbiter": [ + // <1> + { + "propertyName": "env", + "propertyValue": "dev", + "PatternLayout": { + "pattern": "%d [%t] %p %c - %m%n" + } + }, + // <2> + { + "propertyName": "env", + "propertyValue": "prod", + "JsonTemplateLayout": {} + } + ] + } + }, + "Loggers": { + "Root": { + "level": "INFO", + "AppenderRef": { + "ref": "MAIN" + } + } + } + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.properties new file mode 100644 index 00000000000..72e81e778c7 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.properties @@ -0,0 +1,32 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +appender.0.type = File +appender.0.name = MAIN + +appender.0.arbiter[0].type = SystemPropertyArbiter # <1> +appender.0.arbiter[0].propertyName = env +appender.0.arbiter[0].propertyValue = dev +appender.0.arbiter[0].layout.type = PatternLayout +appender.0.arbiter[0].layout.pattern = %d [%t] %p %c - %m%n + +appender.0.arbiter[1].type = SystemPropertyArbiter # <2> +appender.0.arbiter[1].propertyName = env +appender.0.arbiter[1].propertyValue = prod +appender.0.arbiter[1].layout.type = JsonTemplateLayout + +rootLogger.level = INFO +rootLogger.appenderRef.0.ref = MAIN diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.xml new file mode 100644 index 00000000000..f030f4733ab --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.yaml new file mode 100644 index 00000000000..53cd2477b1e --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.yaml @@ -0,0 +1,34 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Configuration: + Appenders: + File: + name: "MAIN" + fileName: "logs/app.log" + SystemPropertyArbiter: + - propertyName: "env" # <1> + propertyValue: "dev" + PatternLayout: + pattern: "%d [%t] %p %c - %m%n" + - propertyName: "env" # <2> + propertyValue: "prod" + JsonTemplateLayout: {} + Loggers: + Root: + level: "INFO" + AppenderRef: + ref: "MAIN" diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.json b/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.json new file mode 100644 index 00000000000..725de4263b7 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.json @@ -0,0 +1,29 @@ +{ + "Configuration": { + "Appenders": {}, + "Loggers": { + // tag::loggers[] + "Root": { + "Property": { + "name": "client.address", + "value": "$${web:request.remoteAddress}" + } + }, + "Logger": [ + { + "name": "org.hibernate", + "Property": { + "subsystem": "Database" + } + }, + { + "name": "io.netty", + "Property": { + "subsystem": "Networking" + } + } + ] + // end::loggers[] + } + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.properties new file mode 100644 index 00000000000..5533e1140cd --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.properties @@ -0,0 +1,32 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +## +# tag::loggers[] +rootLogger.property.type = Property +rootLogger.name = client.address +rootLogger.value = $${web:request.remoteAddress} + +logger.0.name = org.hibernate +logger.0.property.type = Property +logger.0.property.name = subsystem +logger.0.property.value = Database + +logger.1.name = io.netty +logger.1.property.type = Property +logger.1.property.name = subsystem +logger.1.property.value = Networking +# end::loggers[] diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.xml new file mode 100644 index 00000000000..44ec26a0e6e --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.yaml new file mode 100644 index 00000000000..e7467216165 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.yaml @@ -0,0 +1,34 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Configuration: + Appenders: {} + Loggers: + # tag::loggers[] + Root: + Property: + name: "client.address" + value: "$${web:request.remoteAddress}" + Logger: + - name: "org.hibernate" + Property: + name: "subsystem" + value: "Database" + - name: "io.netty" + Property: + name: "subsystem" + value: "Networking" + # end::loggers[] diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.json b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.json new file mode 100644 index 00000000000..e381ea3642e --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.json @@ -0,0 +1,37 @@ +{ + "Configuration": { + // tag::loggers[] + "Loggers": { + "Root": { // <1> + "level": "INFO", + "AppenderRef": { + "ref": "APPENDER1" + } + }, + "Logger": [ + { // <2> + "name": "org.example.no_additivity", + "additivity": false, + "AppenderRef": { + "ref": "APPENDER2" + } + }, + { // <3> + "name": "org.example.no_location", + "includeLocation": false, + "AppenderRef": { + "ref": "APPENDER3" + } + }, + { // <4> + "name": "org.example.level", + "level": "DEBUG", + "AppenderRef": { + "ref": "APPENDER4" + } + } + ] + } + // end::loggers[] + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.properties new file mode 100644 index 00000000000..01b945ebace --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.properties @@ -0,0 +1,33 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +## +# tag::loggers[] +rootLogger.level = INFO # <1> +rootLogger.appenderRef.0.ref = APPENDER1 + +logger.0.name = org.example.no_additivity # <2> +logger.0.additivity = false +logger.0.appenderRef.0.ref = APPENDER2 + +logger.1.name = org.example.no_location # <3> +logger.1.includeLocation = false +logger.1.appenderRef.0.ref = APPENDER3 + +logger.2.name = org.example.level # <4> +logger.2.level = DEBUG +logger.2.appenderRef.0.ref = APPENDER4 +# end::loggers[] diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.xml new file mode 100644 index 00000000000..4549b534f25 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.yaml new file mode 100644 index 00000000000..eae440e5259 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.yaml @@ -0,0 +1,37 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Configuration: + # tag::loggers[] + Loggers: + Root: # <1> + level: "INFO" + AppenderRef: + ref: "APPENDER1" + Logger: + - name: "org.example.no_additivity" # <2> + additivity: false + AppenderRef: + ref: "APPENDER2" + - name: "org.example.no_location" # <3> + includeLocation: false + AppenderRef: + ref: "APPENDER3" + - name: "org.example.level" # <4> + level: "DEBUG" + AppenderRef: + ref: "APPENDER4" + # end::loggers[] diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.json b/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.json new file mode 100644 index 00000000000..0d17c826861 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.json @@ -0,0 +1,47 @@ +{ + "Configuration": { + "Appenders": { + "Console": { // <1> + "name": "CONSOLE", + "PatternLayout": { + "pattern": "%p - %m%n" + } + }, + "File": [ + { // <2> + "name": "MAIN", + "fileName": "logs/main.log", + "JsonTemplateLayout": {} + }, + { // <3> + "name": "DEBUG_LOG", + "fileName": "logs/debug.log", + "PatternLayout": { + "pattern": "%d [%t] %p %c - %m%n" + } + } + ] + }, + "Loggers": { + "Root": { // <4> + "level": "INFO", + "AppenderRef": [ + { + "ref": "CONSOLE", + "level": "WARN" + }, + { + "ref": "MAIN" + } + ] + }, + "Logger": { // <5> + "name": "org.example", + "level": "DEBUG", + "AppenderRef": { + "ref": "DEBUG_LOG" + } + } + } + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.properties new file mode 100644 index 00000000000..2b98fbe6576 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.properties @@ -0,0 +1,40 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +appender.0.type = Console # <1> +appender.0.name = CONSOLE +appender.0.layout.type = PatternLayout +appender.0.layout.pattern = %p - %m%n + +appender.1.type = File # <2> +appender.1.name = MAIN +appender.1.fileName = logs/main.log +appender.1.layout.type = JsonTemplateLayout + +appender.2.type = File # <3> +appender.2.name = DEBUG_LOG +appender.2.fileName = logs/debug.log +appender.2.layout.type = PatternLayout +appender.2.layout.pattern = %d [%t] %p %c - %m%n + +rootLogger.level = INFO # <4> +rootLogger.appenderRef.0.ref = CONSOLE +rootLogger.appenderRef.0.level = WARN +rootLogger.appenderRef.1.ref = MAIN + +logger.0.name = org.example # <5> +logger.0.level = DEBUG +logger.0.appenderRef.0.ref = DEBUG_LOG diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.xml new file mode 100644 index 00000000000..6f3957d6148 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.yaml new file mode 100644 index 00000000000..e29280933eb --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.yaml @@ -0,0 +1,42 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Configuration: + Appenders: + Console: # <1> + name: "CONSOLE" + PatternLayout: + pattern: "%p - %m%n" + File: + - name: "MAIN" # <2> + fileName: "logs/main.log" + JsonTemplateLayout: {} + - name: "DEBUG_LOG" # <3> + fileName: "logs/debug.log" + PatternLayout: + pattern: "%d [%t] %p %c - %m%n" + Loggers: + Root: # <4> + level: "INFO" + AppenderRef: + - ref: "CONSOLE" + level: "WARN" + - ref: "MAIN" + Logger: # <5> + name: "org.example" + level: "DEBUG" + AppenderRef: + ref: "DEBUG_LOG" diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.json b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.json new file mode 100644 index 00000000000..2928369686f --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.json @@ -0,0 +1,14 @@ +{ + "Properties": { + "Property": [ + { + "name": "FOO", + "value": "foo" + }, + { + "name": "BAR", + "value": "bar" + } + ] + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.properties new file mode 100644 index 00000000000..099524cc744 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.properties @@ -0,0 +1,18 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +property.FOO = foo +property.BAR = bar diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.xml new file mode 100644 index 00000000000..5d13d93732b --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.yaml new file mode 100644 index 00000000000..35ef189004b --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.yaml @@ -0,0 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Properties: + Property: + - name: "FOO" + value: "foo" + - name: "BAR" + value: "bar" diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.json b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.json new file mode 100644 index 00000000000..6cfdc627990 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.json @@ -0,0 +1,18 @@ +{ + "Properties": { + "Property": [ + { + "name": "logging.file", + "value": "${logging.path}/app.log" + }, + { + "name": "logging.dir", + "value": "${env:APP_BASE}/logs" + }, + { + "name": "APP_BASE", + "value": "." + } + ] + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.properties new file mode 100644 index 00000000000..0c54dd40cb4 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.properties @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +property.logging.file = ${logging.dir}/app.log +property.logging.dir = ${env:APP_BASE}/logs +property.APP_BASE = . diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.xml new file mode 100644 index 00000000000..98ac38dd07f --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.yaml new file mode 100644 index 00000000000..2fa6ecc24c5 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.yaml @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Properties: + Property: + - name: "logging.file" + value: "${logging.dir}/app.log" + - name: "logging.dir" + value: "${env:APP_BASE}/logs" + - name: "APP_BASE" + value: "." diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties.json b/src/site/antora/modules/ROOT/examples/manual/configuration/properties.json new file mode 100644 index 00000000000..c3fb1911b27 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties.json @@ -0,0 +1,17 @@ +{ + "Configuration": { + "Properties": { + "Property": [ + { + "name": "log.dir", + "value": "/var/log" + }, + { + "name": "log.file", + "value": "${log.dir}/app.log" + } + ] + } + // ... + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/properties.properties new file mode 100644 index 00000000000..77a67b7823b --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties.properties @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +property.log.dir = /var/log +property.log.file = ${log.dir}/app.log +# ... diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/properties.xml new file mode 100644 index 00000000000..8851bfd36c6 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties.xml @@ -0,0 +1,28 @@ + + + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/properties.yaml new file mode 100644 index 00000000000..4723e42f67d --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties.yaml @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Configuration: + Properties: + Property: + - name: "log.dir" + value: "/var/log" + - name: "log.file" + value: "${log.dir}/app.log" +# ... diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/routing.json b/src/site/antora/modules/ROOT/examples/manual/configuration/routing.json new file mode 100644 index 00000000000..cc6ab3b5e63 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/routing.json @@ -0,0 +1,34 @@ +{ + "Configuration": { + "Appenders": { + // tag::appender[] + "Routing": { + "name": "ROUTING", + "Routes": { + "pattern": "$${sd:type}", // <1> + "Route": { + "File": { + "name": "ROUTING-${sd:type}", // <2> + "fileName": "logs/${sd:type}.log", // <2> + "JsonTemplateLayout": { + "EventTemplateAdditionalField": { + "name": "type", + "value": "${sd:type}" // <2> + } + } + } + } + } + } + // end::appender[] + }, + "Loggers": { + "Root": { + "AppenderRef": { + "level": "INFO", + "ref": "ROUTING" + } + } + } + } +} diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/routing.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/routing.properties new file mode 100644 index 00000000000..912e5be0c9d --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/routing.properties @@ -0,0 +1,37 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +## +# tag::appender[] +appender.0.type = Routing +appender.0.name = ROUTING + +appender.0.routes.type = Routes +appender.0.routes.pattern = $${sd:type} # <1> + +appender.0.routes.route.type = Route + +appender.0.routes.route.file.type = File +appender.0.routes.route.file.name = ROUTING-${sd:type} # <2> +appender.0.routes.route.file.fileName = logs/${sd:type}.log # <2> +appender.0.routes.route.file.layout.type = JsonTemplateLayout +appender.0.routes.route.file.layout.field.type = EventTemplateAdditionalField +appender.0.routes.route.file.layout.field.name = type +appender.0.routes.route.file.layout.field.value = ${sd:type} # <2> +# end::appender[] + +rootLogger.level = INFO +rootLogger.appenderRef.0.ref = ROUTING diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/routing.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/routing.xml new file mode 100644 index 00000000000..ebda4946e52 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/routing.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/routing.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/routing.yaml new file mode 100644 index 00000000000..b71bf5d4ca5 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/routing.yaml @@ -0,0 +1,36 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Configuration: + Appenders: + # tag::appender[] + Routing: + name: "ROUTING" + Routes: + pattern: "$${sd:type}" # <1> + Route: + File: + name: "ROUTING-${sd:type}" # <2> + fileName: "logs/${sd:type}.log" # <2> + JsonTemplateLayout: + EventTemplateAdditionalField: + name: "type" + value: "${sd:type}" # <2> + # end::appender[] + Loggers: + Root: + level: "INFO" + AppenderRef: "ROUTING" diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.json b/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.json new file mode 100644 index 00000000000..73db82029ca --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.json @@ -0,0 +1,65 @@ +{ + "Configuration": { + "Appenders": { + "Console": { + "name": "STDOUT", + "PatternLayout": { + "ScriptPatternSelector": { + "defaultPattern": "%d %p %m%n", + "ScriptRef": { + "ref": "SELECTOR_SCRIPT", + "PatternMatch": [ + { + "key": "NoLocation", + "pattern": "[%-5level] %c{1.} %msg%n" + }, + { + "key": "Flow", + "pattern": "[%-5level] %c{1.} ====== %C{1.}.%M:%L %msg ======%n" + } + ] + } + } + } + }, + "Loggers": { + "Logger": { + "name": "EventLogger", + "ScriptFilter": { + "onMatch": "ACCEPT", + "onMismatch": "DENY", + "Script": { + "name": "EVENT_LOGGER_FILTER", + "language": "groovy", + "scriptText": "if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf('FLOW'))) { return true; } else if (logEvent.getContextMap().containsKey('UserId')) { return true; } return false;" + } + } + }, + "Root": { + "level": "INFO", + "ScriptFilter": { + "onMatch": "ACCEPT", + "onMismatch": "DENY", + "ScriptRef": { + "ref": "ROOT_FILTER" + } + }, + "AppenderRef": { + "ref": "STDOUT" + } + }, + "Scripts": { + "Script": { + "name": "SELECTOR_SCRIPT", + "language": "javascript", + "scriptText": "var result; if (logEvent.getLoggerName().equals('JavascriptNoLocation')) { result = 'NoLocation'; } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf('FLOW')) { result = 'Flow'; } result;" + }, + "ScriptFile": { + "name": "ROOT_FILTER", + "path": "scripts/filter.groovy" + } + } + } + } + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.properties new file mode 100644 index 00000000000..8c41afe7d59 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.properties @@ -0,0 +1,67 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +appender.0.type = Console +appender.0.name = STDOUT +appender.0.layout.type = PatternLayout + +appender.0.layout.selector = ScriptPatternSelector +appender.0.layout.selector.defaultPattern = %d %p %m%n +appender.0.layout.selector.scriptRef.type = ScriptRef +appender.0.layout.selector.scriptRef.ref = SELECTOR_SCRIPT +appender.0.layout.selector.match[0].type = PatternMatch +appender.0.layout.selector.match[0].key = NoLocation +appender.0.layout.selector.match[0].pattern = [%-5level] %c{1.} %msg%n +appender.0.layout.selector.match[1].type = PatternMatch +appender.0.layout.selector.match[1].key = Flow +appender.0.layout.selector.match[1].pattern = [%-5level] %c{1.} ====== %C{1.}.%M:%L %msg ======%n + +logger.0.name = EventLogger +logger.0.filter.0.type = ScriptFilter +logger.0.filter.0.onMatch = ACCEPT +logger.0.filter.0.onMismatch = DENY +logger.0.filter.0.script.type = Script +logger.0.filter.0.script.name = EVENT_LOGGER_FILTER +logger.0.filter.0.script.language = groovy +logger.0.filter.0.script.scriptText = if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW"))) {\ + return true;\ + } else if (logEvent.getContextMap().containsKey("UserId")) {\ + return true;\ + }\ + return false; + +rootLogger.level = INFO +rootLogger.filter.0.type = ScriptFilter +rootLogger.filter.0.onMatch = ACCEPT +rootLogger.filter.0.onMismatch = DENY +rootLogger.filter.0.scriptRef.type = ScriptRef +rootLogger.filter.0.scriptRef.ref = ROOT_FILTER +rootLogger.appenderRef.0.ref = STDOUT + +script.0.type = Script +script.0.name = SELECTOR_SCRIPT +script.0.language = javascript +script.0.scriptText = var result;\ + if (logEvent.getLoggerName().equals("JavascriptNoLocation")) {\ + result = "NoLocation";\ + } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {\ + result = "Flow";\ + }\ + result; + +script.1.type = ScriptFile +script.1.name = ROOT_FILTER +script.1.path = scripts/filter.groovy diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.xml new file mode 100644 index 00000000000..f7e8b4cfeb1 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.yaml new file mode 100644 index 00000000000..6b5d6ccca1a --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.yaml @@ -0,0 +1,70 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Configuration: + Appenders: + Console: + name: "STDOUT" + PatternLayout: + ScriptPatternSelector: + defaultPattern: "%d %p %m%n" + ScriptRef: + ref: "SELECTOR_SCRIPT" + PatternMatch: + - key: "NoLocation" + pattern: "[%-5level] %c{1.} %msg%n" + - key: "Flow" + pattern: "[%-5level] %c{1.} ====== %C{1.}.%M:%L %msg ======%n" + Loggers: + Logger: + name: "EventLogger" + ScriptFilter: + onMatch: "ACCEPT" + onMismatch: "DENY" + Script: + name: "EVENT_LOGGER_FILTER" + language: "groovy" + scriptText: | + if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) { + return true; + } else if (logEvent.getContextMap().containsKey("UserId")) { + return true; + } + return false; + Root: + level: "INFO" + ScriptFilter: + onMatch: "ACCEPT" + onMismatch: "DENY" + ScriptRef: + ref: "ROOT_FILTER" + AppenderRef: + ref: "STDOUT" + Scripts: + Script: + name: "SELECTOR_SCRIPT" + language: "javascript" + scriptText: | + var result; + if (logEvent.getLoggerName().equals("JavascriptNoLocation")) { + result = "NoLocation"; + } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) { + result = "Flow"; + } + result; + ScriptFile: + name: "ROOT_FILTER" + path: "scripts/filter.groovy" diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-appenders.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-appenders.xml new file mode 100644 index 00000000000..b34c7b2a713 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-appenders.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-loggers.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-loggers.xml new file mode 100644 index 00000000000..eeb674535d3 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-loggers.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-main.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-main.xml new file mode 100644 index 00000000000..8eb0e666a0e --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-main.xml @@ -0,0 +1,29 @@ + + + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/filters/filters.json b/src/site/antora/modules/ROOT/examples/manual/filters/filters.json new file mode 100644 index 00000000000..4acc4c43b76 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/filters/filters.json @@ -0,0 +1,36 @@ +{ + "Configuration": { + "Appenders": { + "Console": { + "name": "CONSOLE", + "ThresholdFilter": { + "level": "WARN" // <6> + } + } + }, + "Loggers": { + "Root": { + "level": "INFO", + "ThresholdFilter": { // <3> + "level": "DEBUG" + }, + "AppenderRef": { + "ref": "CONSOLE", + "level": "WARN", // <5> + "MarkerFilter": { // <4> + "marker": "ALERT", + "onMatch": "NEUTRAL", + "onMismatch": "DENY" + } + } + }, + "Logger": { + "name": "org.example", + "level": "TRACE" // <2> + } + } + }, + "MarkerFilter": { // <1> + "marker": "PRIVATE" + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/filters/filters.properties b/src/site/antora/modules/ROOT/examples/manual/filters/filters.properties new file mode 100644 index 00000000000..1077fc44e7e --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/filters/filters.properties @@ -0,0 +1,38 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +appender.0.type = Console +appender.0.name = CONSOLE +appender.0.filter.type = ThresholdFilter # <6> +appender.0.filter.level = WARN + +rootLogger.level = INFO +rootLogger.filter.type = ThresholdFilter # <3> +rootLogger.filter.level = DEBUG +rootLogger.appenderRef.0.ref = CONSOLE +rootLogger.appenderRef.0.level = WARN # <5> +rootLogger.appenderRef.0.filter.type = MarkerFilter # <4> +rootLogger.appenderRef.0.filter.marker = ALERT +rootLogger.appenderRef.0.filter.onMatch = NEUTRAL +rootLogger.appenderRef.0.filter.onMismatch = DENY + +logger.0.name = org.example +logger.0.level = DEBUG # <2> +logger.0.filter.type = ThresholdFilter # <3> +logger.0.filter.level = TRACE + +filter.type = MarkerFilter # <1> +filter.marker = PRIVATE diff --git a/src/site/antora/modules/ROOT/examples/manual/filters/filters.xml b/src/site/antora/modules/ROOT/examples/manual/filters/filters.xml new file mode 100644 index 00000000000..4c86b04faf5 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/filters/filters.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/filters/filters.yaml b/src/site/antora/modules/ROOT/examples/manual/filters/filters.yaml new file mode 100644 index 00000000000..9a4f61f3467 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/filters/filters.yaml @@ -0,0 +1,41 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Configuration: + Appenders: + Console: + name: "CONSOLE" + ThresholdFilter: # <6> + level: "WARN" + Loggers: + Root: + level: "INFO" + ThreadsholdFilter: # <3> + level: "DEBUG" + AppenderRef: + ref: "CONSOLE" + level: "WARN" # <5> + MarkerFilter: # <4> + marker: "ALERT" + onMatch: "NEUTRAL" + onMismatch: "DENY" + Logger: + name: "org.example" + level: "TRACE" # <2> + ThresholdFilter: + level: "TRACE" # <3> + MarkerFilter: # <1> + marker: "PRIVATE" diff --git a/src/site/antora/modules/ROOT/nav.adoc b/src/site/antora/modules/ROOT/nav.adoc index b7789787fdc..b3a7b574d7d 100644 --- a/src/site/antora/modules/ROOT/nav.adoc +++ b/src/site/antora/modules/ROOT/nav.adoc @@ -40,20 +40,23 @@ ** xref:manual/thread-context.adoc[] ** xref:manual/scoped-context.adoc[] ** xref:manual/resource-logger.adoc[] -* xref:manual/configuration.adoc[] +* Configuration +** xref:manual/configuration.adoc[Configuration file] +** xref:manual/appenders.adoc[] +** xref:manual/layouts.adoc[] +*** xref:manual/json-template-layout.adoc[] +** xref:manual/lookups.adoc[] +** xref:manual/customloglevels.adoc[] +** xref:manual/filters.adoc[] +** xref:manual/scripts.adoc[] +** xref:manual/systemproperties.adoc[] * xref:manual/usage.adoc[] * xref:manual/cloud.adoc[] -* xref:manual/lookups.adoc[] -* xref:manual/appenders.adoc[] -* xref:manual/layouts.adoc[] -** xref:manual/json-template-layout.adoc[] -* xref:manual/filters.adoc[] * xref:manual/async.adoc[] * xref:manual/garbagefree.adoc[] * xref:manual/extending.adoc[] +** xref::manual/customconfig.adoc[] * xref:manual/plugins.adoc[] -* xref:manual/customconfig.adoc[] -* xref:manual/customloglevels.adoc[] * xref:manual/jmx.adoc[] * xref:manual/logsep.adoc[] * xref:manual/performance.adoc[] diff --git a/src/site/antora/modules/ROOT/pages/log4j-jul.adoc b/src/site/antora/modules/ROOT/pages/log4j-jul.adoc index c0d869e14e4..d6974a822e2 100644 --- a/src/site/antora/modules/ROOT/pages/log4j-jul.adoc +++ b/src/site/antora/modules/ROOT/pages/log4j-jul.adoc @@ -35,15 +35,28 @@ This must be done either through the command line (i.e., using the `-Djava.util. == Compatibility -The use of a http://docs.oracle.com/javase/6/docs/api/java/util/logging/Filter.html[`java.util.logging.Filter`] is supported on a per-http://docs.oracle.com/javase/6/docs/api/java/util/logging/Logger.html[`Logger`] basis. +The use of a +https://docs.oracle.com/javase/{java-target-version}/docs/api/java/util/logging/Filter.html[java.util.logging.Filter] +is supported on a +https://docs.oracle.com/javase/{java-target-version}/docs/api/java/util/logging/Logger.html[per-Logger] +basis. However, it is recommended to use the standard xref:manual/filters.adoc[Filters] feature in Log4j instead. -The use of http://docs.oracle.com/javase/6/docs/api/java/util/logging/Handler.html[`java.util.logging.Handler`] classes is _NOT_ supported. -Custom Handlers should instead use an appropriate xref:manual/appenders.adoc[Appender] or code their own link:javadoc/log4j-core/org/apache/logging/log4j/core/Appender.adoc[`Appender`] plugin. +The use of +https://docs.oracle.com/javase/{java-target-version}/docs/api/java/util/logging/Handler.html[java.util.logging.Handler] +classes is +_NOT_ supported. +Custom Handlers should instead use an appropriate +xref:manual/appenders.adoc[Appender] +or code their own +link:../javadoc/log4j-core/org/apache/logging/log4j/core/Appender.html[Appender] +plugin. Java logging levels are translated into Log4j logging levels dynamically. The following table lists the conversions between a Java logging level and its equivalent Log4j level. -Custom levels should be implemented as an implementation of `LevelConverter`, and the Log4j property xref:manual/configuration.adoc#log4j2.julLevelConverter[log4j2.julLevelConverter] must be set to your custom class name. +Custom levels should be implemented as an implementation of `LevelConverter`, and the Log4j property +xref:manual/systemproperties.adoc#log4j2.julLevelConverter[log4j2.julLevelConverter] +must be set to your custom class name. Using the default `LevelConverter` implementation, custom logging levels are mapped to whatever the current level of the `Logger` being logged to is using. [#default-level-conversions] diff --git a/src/site/antora/modules/ROOT/pages/log4j-spring-cloud-config-client.adoc b/src/site/antora/modules/ROOT/pages/log4j-spring-cloud-config-client.adoc index dd81aa136ed..ce8e4b31caa 100644 --- a/src/site/antora/modules/ROOT/pages/log4j-spring-cloud-config-client.adoc +++ b/src/site/antora/modules/ROOT/pages/log4j-spring-cloud-config-client.adoc @@ -24,7 +24,9 @@ Spring Boot applications initialize logging 3 times. . SpringApplication declares a Logger. This Logger will be initialized using Log4j's "normal" mechanisms. -Thus the xref:manual/configuration.adoc#log4j2.configurationFile[`log4j2.configurationFile`] system property will be checked to see if a specific configuration file has been provided, otherwise it will search for a configuration file on the classpath. +Thus, the +xref:manual/systemproperties.adoc#log4j2.configurationFile[`log4j2.configurationFile`] +system property will be checked to see if a specific configuration file has been provided, otherwise it will search for a configuration file on the classpath. The property may also be declare in log4j2.component.properties. == Usage @@ -122,7 +124,9 @@ logging: Note that Log4j currently does not directly support encrypting the password. However, Log4j does use Spring's standard APIs to access properties in the Spring configuration so any customizations made to Spring's property handling would apply to the properties Log4j uses as well. -If more extensive authentication is required an `AuthorizationProvider` can be implemented and its fully qualified class name should be specified in the xref:manual/configuration.adoc#log4j2.configurationAuthorizationProvider[log4j2.configurationAuthorizationProvider] system property, in log4j2.component.properties or in Spring's `bootstrap.yml` using either the `log4j2.authorizationProvider` or `logging.auth.authorizationProvider` key. +If more extensive authentication is required an `AuthorizationProvider` can be implemented and its fully qualified class name should be specified in the +xref:manual/systemproperties.adoc#log4j2.configurationAuthorizationProvider[log4j2.configurationAuthorizationProvider] +system property, in log4j2.component.properties or in Spring's `bootstrap.yml` using either the `log4j2.authorizationProvider` or `logging.auth.authorizationProvider` key. For the properties required by TLS configuration see xref:manual/configuration.adoc#transport-security[the Transport Security configuration]. diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc index f473f73483e..dd33e64af31 100644 --- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc @@ -20,49 +20,39 @@ Ralph Goers; Gary Gregory; Nick Williams; Matt Sicker Appenders are responsible for delivering LogEvents to their destination. Every Appender must implement the link:../javadoc/log4j-core/org/apache/logging/log4j/core/Appender.html[`Appender`] -interface. Most Appenders will extend +interface. +Most Appenders will extend link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/AbstractAppender.html[`AbstractAppender`] which adds link:../javadoc/log4j-core/org/apache/logging/log4j/core/LifeCycle.html[`Lifecycle`] and link:../javadoc/log4j-core/org/apache/logging/log4j/core/filter/Filterable.html[`Filterable`] -support. `Lifecycle` allows components to finish initialization after -configuration has completed and to perform cleanup during shutdown. -`Filterable` allows the component to have `Filter`s attached to it which are -evaluated during event processing. - -Appenders usually are only responsible for writing the event data to the -target destination. In most cases they delegate responsibility for -formatting the event to a xref:manual/layouts.adoc[layout]. Some appenders wrap -other appenders so that they can modify the `LogEvent`, handle a failure -in an `Appender`, route the event to a subordinate `Appender` based on -advanced `Filter` criteria or provide similar functionality that does not -directly format the event for viewing. - -Appenders always have a name so that they can be referenced from -Loggers. - -In the tables below, the "Type" column corresponds to the Java type -expected. For non-JDK classes, these should usually be in -link:../javadoc/log4j-core/index.html[Log4j Core] unless otherwise -noted. +support. `Lifecycle` allows components to finish initialization after configuration has been completed and to perform cleanup during shutdown. +`Filterable` allows the component to have `Filter` attached to it which are evaluated during event processing. + +Appenders usually are only responsible for writing the event data to the target destination. +In most cases, they delegate responsibility for formatting the event to a xref:manual/layouts.adoc[layout]. +Some appenders wrap other appenders so that they can modify the `LogEvent`, handle a failure in an `Appender`, route the event to a subordinate `Appender` based on advanced `Filter` criteria or provide similar functionality that does not directly format the event for viewing. + +Appenders always have a name so that they can be referenced from Loggers. + +In the tables below, the "Type" column corresponds to the Java type expected. +For non-JDK classes, these should usually be in +link:../javadoc/log4j-core/index.html[Log4j Core] unless otherwise noted. [#AsyncAppender] == AsyncAppender -The AsyncAppender accepts references to other Appenders and causes -LogEvents to be written to them on a separate Thread. Note that -exceptions while writing to those Appenders will be hidden from the -application. The AsyncAppender should be configured after the appenders -it references to allow it to shut down properly. +The AsyncAppender accepts references to other Appenders and causes LogEvents to be written to them on a separate Thread. +Note that exceptions while writing to those Appenders will be hidden from the application. +The AsyncAppender should be configured after the appenders it references to allow it to shut down properly. By default, AsyncAppender uses https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ArrayBlockingQueue.html[`java.util.concurrent.ArrayBlockingQueue`] -which does not require any external libraries. Note that multi-threaded -applications should exercise care when using this appender as such: the -blocking queue is susceptible to lock contention and our -xref:manual/performance.adoc#asyncLogging[tests showed] performance may -become worse when more threads are logging concurrently. Consider using +which does not require any external libraries. +Note that multi-threaded applications should exercise care when using this appender as such: the blocking queue is susceptible to lock contention and our +xref:manual/performance.adoc#asyncLogging[tests showed] performance may become worse when more threads are logging concurrently. +Consider using xref:manual/async.adoc[lock-free Async Loggers] for optimal performance. .AsyncAppender Parameters @@ -77,7 +67,7 @@ slots in the queue. If false, the event will be written to the error appender if the queue is full. The default is true. |shutdownTimeout |integer |How many milliseconds the Appender should -wait to flush outstanding log events in the queue on shutdown. The +wait to flush outstanding log events in the queue on shutdown? The default is zero which means to wait forever. |bufferSize |integer a| @@ -86,7 +76,7 @@ is 1024. Note that when using a disruptor-style `BlockingQueue`, this buffer size must be a power of 2. When the application is logging faster than the underlying appender can -keep up with for a long enough time to fill up the queue, the behaviour +keep up with for a long enough time to fill up the queue, the behavior is determined by the link:../javadoc/log4j-core/org/apache/logging/log4j/core/async/AsyncQueueFullPolicy.html[`AsyncQueueFullPolicy`]. @@ -116,14 +106,13 @@ type of `BlockingQueue` to use. See link:#BlockingQueueFactory[below documentation] for more details. |======================================================================= -There are also a few system properties that can be used to maintain -application throughput even when the underlying appender cannot keep up -with the logging rate and the queue is filling up. See the details for -system properties -xref:manual/configuration.adoc#log4j2.AsyncQueueFullPolicy[`log4j2.AsyncQueueFullPolicy` -and `log4j2.DiscardThreshold`]. +There are also a few system properties that can be used to maintain application throughput even when the underlying appender cannot keep up with the logging rate and the queue is filling up. +See the details for system properties +xref:manual/systemproperties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy`] +and +xref:manual/systemproperties.adoc#log4j2.discardThreshold[`log4j2.DiscardThreshold`]. -A typical AsyncAppender configuration might look like: +A typical AsyncAppender configuration might look like this: [source,xml] ---- @@ -147,11 +136,11 @@ A typical AsyncAppender configuration might look like: ---- -[[BlockingQueueFactory]] Starting in Log4j 2.7, a custom implementation -of `BlockingQueue` or `TransferQueue` can be specified using a +[[BlockingQueueFactory]] +Starting in Log4j 2.7, a custom implementation of `BlockingQueue` or `TransferQueue` can be specified using a link:../javadoc/log4j-core/org/apache/logging/log4j/core/async/BlockingQueueFactory.html[`BlockingQueueFactory`] -plugin. To override the default `BlockingQueueFactory`, specify the -plugin inside an `` element like so: +plugin. +To override the default `BlockingQueueFactory`, specify the plugin inside an `` element like so: [source,xml] ---- @@ -190,29 +179,26 @@ https://jctools.github.io/JCTools/[JCTools], specifically the MPSC bounded lock-free queue. This implementation is provided by the `log4j-jctools` artifact. -|LinkedTransferQueue |This uses the new in Java 7 implementation +|LinkedTransferQueue |This uses the new Java 7 implementation https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/LinkedTransferQueue.html[`LinkedTransferQueue`]. Note that this queue does not use the `bufferSize` configuration attribute from AsyncAppender as `LinkedTransferQueue` does not support a maximum capacity. |======================================================================= - [#CassandraAppender] == CassandraAppender The CassandraAppender writes its output to an https://cassandra.apache.org/[Apache Cassandra] -database. A keyspace and table must be configured ahead of time, and the columns of that table are mapped -in a configuration file. Each column can specify either a https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout[StringLayout] (e.g., a -PatternLayout) along with an optional conversion type, or only -a conversion type for `org.apache.logging.log4j.spi.ThreadContextMap` or -`org.apache.logging.log4j.spi.ThreadContextStack` to store the MDC or NDC -in a map or list column respectively. A conversion type compatible with `java.util.Date` will -use the log event timestamp converted to that type (e.g., use `java.util.Date` to fill a +database. +A keyspace and table must be configured ahead of time, and the columns of that table are mapped in a configuration file. +Each column can specify either a https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout[StringLayout] (e.g., a PatternLayout) along with an optional conversion type, or only a conversion type for `org.apache.logging.log4j.spi.ThreadContextMap` or +`org.apache.logging.log4j.spi.ThreadContextStack` to store the MDC or NDC in a map or list column respectively. +A conversion type compatible with `java.util.Date` will use the log event timestamp converted to that type (e.g., use `java.util.Date` to fill a `timestamp` column type in Cassandra). .CassandraAppender Parameters -[cols="1,1,3", options="header"] +[cols="1,1,3",options="header"] |=== | Parameter Name | Type | Description @@ -294,7 +280,7 @@ TimestampGenerator. By default, this is `false`. | Whether or not to use TLS/SSL to connect to Cassandra. This is `false` by default. |=== -Here is an example CassandraAppender configuration: +Here is an example `CassandraAppender` configuration: [source,xml] ---- @@ -339,12 +325,12 @@ CREATE TABLE logs ( ); ---- -[#ConsoleAppender] -== ConsoleAppender +[id=consoleappender] +== [[ConsoleAppender]] ConsoleAppender As one might expect, the ConsoleAppender writes its output to either -System.out or System.err with System.out being the default target. A -Layout must be provided to format the LogEvent. +`System.out` or `System.err` with `System.out` being the default target. +A Layout must be provided to format the LogEvent. .ConsoleAppender Parameters [cols="20%,20%,60%",options="header",] @@ -358,14 +344,14 @@ CompositeFilter. is supplied the default pattern layout of "%m%n" will be used. |follow |boolean |Identifies whether the appender honors reassignments -of System.out or System.err via System.setOut or System.setErr made +of `System.out` or `System.err` via `System.setOut` or `System.setErr` made after configuration. Note that the follow attribute cannot be used with Jansi on Windows. Cannot be used with `direct`. |direct |boolean |Write directly to `java.io.FileDescriptor` and bypass `java.lang.System.out/.err`. Can give up to 10x performance boost when -the output is redirected to file or other process. Cannot be used with -Jansi on Windows. Cannot be used with `follow`. Output will not respect +the output is redirected to a file or other process. Cannot be used with +Jansi on Windows. Cannot be used with `follow`. The output will not respect `java.lang.System.setOut()/.setErr()` and may get intertwined with other output to `java.lang.System.out/.err` in a multi-threaded application. _New since 2.6.2. Be aware that this is a new addition, and it has only @@ -405,9 +391,8 @@ A typical Console configuration might look like: [#FailoverAppender] == FailoverAppender -The FailoverAppender wraps a set of appenders. If the primary Appender -fails the secondary appenders will be tried in order until one succeeds -or there are no more secondaries to try. +The FailoverAppender wraps a set of appenders. +If the primary Appender fails the secondary appenders will be tried in order until one succeeds or there are no more secondaries to try. .FailoverAppender Parameters [cols="20%,20%,60%",options="header",] @@ -466,17 +451,13 @@ A Failover configuration might look like: ---- -[#FileAppender] -== FileAppender +[id=fileappender] +== [[FileAppender]] FileAppender -The FileAppender is an OutputStreamAppender that writes to the File -named in the fileName parameter. The FileAppender uses a FileManager -(which extends OutputStreamManager) to actually perform the file I/O. -While FileAppenders from different Configurations cannot be shared, the -FileManagers can be if the Manager is accessible. For example, two web -applications in a servlet container can have their own configuration and -safely write to the same file if Log4j is in a ClassLoader that is -common to both of them. +The FileAppender is an OutputStreamAppender that writes to the File defined in the `fileName` parameter. +The FileAppender uses a FileManager (which extends OutputStreamManager) to perform the file I/O. +While FileAppenders from different Configurations cannot be shared, the FileManagers can be if the Manager is accessible. +For example, two web applications in a servlet container can have their configuration and safely write to the same file if Log4j is in a ClassLoader that is common to both of them. .FileAppender Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -489,11 +470,11 @@ new records are written. |bufferedIO |boolean |When true - the default, records will be written to a buffer and the data will be written to disk when the buffer is full or, if immediateFlush is set, when the record is written. File locking -cannot be used with bufferedIO. Performance tests have shown that using -buffered I/O significantly improves performance, even if immediateFlush +cannot be used with `bufferedIO`. Performance tests have shown that using +buffered I/O significantly improves performance, even if `immediateFlush` is enabled. -|bufferSize |int |When bufferedIO is true, this is the buffer size, the +|bufferSize |int |When `bufferedIO` is true, this is the buffer size, the default is 8192 bytes. |createOnDemand |boolean |The appender creates the file on-demand. The @@ -510,7 +491,7 @@ of its parent directories, do not exist, they will be created. |immediateFlush |boolean a| When set to true - the default, each write will be followed by a flush. This will guarantee that the data is passed to the operating system for writing; -it does not guarantee that the data is actually written to a physical device +it does not guarantee that the data is written to a physical device such as a disk drive. Note that if this flag is set to false, and the logging activity is sparse, @@ -532,7 +513,7 @@ is supplied the default pattern layout of "%m%n" will be used. while the file lock is held allowing FileAppenders in multiple JVMs and potentially multiple hosts to write to the same file simultaneously. This will significantly impact performance so should be used carefully. -Furthermore, on many systems the file lock is "advisory" meaning that +Furthermore, on many systems, the file lock is "advisory" meaning that other applications can perform operations on the file without acquiring a lock. The default value is false. @@ -548,7 +529,7 @@ Appender in a link:#FailoverAppender[FailoverAppender]. File attribute permissions in POSIX format to apply whenever the file is created. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -557,21 +538,21 @@ Examples: `rw-------` or `rw-rw-rw-` etc... |fileOwner |String a| File owner to define whenever the file is created. -Changing file's owner may be restricted for security reason and +Changing the file's owner may be restricted for security reasons and Operation not permitted IOException thrown. Only processes with an effective user ID equal to the user ID of the file or with appropriate privileges may change the ownership of a file if http://www.gnu.org/software/libc/manual/html_node/Options-for-Files.html[_POSIX_CHOWN_RESTRICTED] is in effect for path. -Underlying files system shall support file +The underlying files system shall support file https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/FileOwnerAttributeView.html[owner] attribute view. |fileGroup |String a| File group to define whenever the file is created. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -603,29 +584,19 @@ Here is a sample File configuration: _This is an optional component supplied in a separate jar._ -http://flume.apache.org/index.html[Apache Flume] is a distributed, -reliable, and available system for efficiently collecting, aggregating, -and moving large amounts of log data from many different sources to a -centralized data store. The FlumeAppender takes LogEvents and sends them -to a Flume agent as serialized Avro events for consumption. +http://flume.apache.org/index.html[Apache Flume] is a distributed, reliable, and available system for efficiently collecting, aggregating, and moving large amounts of log data from many different sources to a centralized data store. +The FlumeAppender takes LogEvents and sends them to a Flume agent as serialized Avro events for consumption. The Flume Appender supports three modes of operation. -1. It can act as a remote Flume client which sends Flume events via -Avro to a Flume Agent configured with an Avro Source. -2. It can act as an embedded Flume Agent where Flume events pass -directly into Flume for processing. -3. It can persist events to a local BerkeleyDB data store and then -asynchronously send the events to Flume, similar to the embedded Flume -Agent but without most of the Flume dependencies. - -Usage as an embedded agent will cause the messages to be directly passed -to the Flume Channel and then control will be immediately returned to -the application. All interaction with remote agents will occur -asynchronously. Setting the "type" attribute to "Embedded" will force -the use of the embedded agent. In addition, configuring agent properties -in the appender configuration will also cause the embedded agent to be -used. +1. It can act as a remote Flume client which sends Flume events via Avro to a Flume Agent configured with an Avro Source. +2. It can act as an embedded Flume Agent where Flume events pass directly into Flume for processing. +3. It can persist events to a local BerkeleyDB data store and then asynchronously send the events to Flume, similar to the embedded Flume Agent but without most of the Flume dependencies. + +Usage as an embedded agent will cause the messages to be directly passed to the Flume Channel and then control will be immediately returned to the application. +All interaction with remote agents will occur asynchronously. +Setting the "type" attribute to "Embedded" will force the use of the embedded agent. +In addition, configuring agent properties in the appender configuration will also cause the embedded agent to be used. .FlumeAppender Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -635,13 +606,13 @@ used. be sent. If more than one agent is specified the first Agent will be the primary and subsequent Agents will be used in the order specified as secondaries should the primary Agent fail. Each Agent definition -supplies the Agents host and port. The specification of agents and +supplies the Agent's host and port. The specification of agents and properties are mutually exclusive. If both are configured an error will result. |agentRetries |integer |The number of times the agent should be retried before failing to a secondary. This parameter is ignored when -type="persistent" is specified (agents are tried once before failing to +`type="persistent"` is specified (agents are tried once before failing to the next). |batchSize |integer |Specifies the number of events that should be sent @@ -654,7 +625,7 @@ using gzip |connectTimeoutMillis |integer |The number of milliseconds Flume will wait before timing out the connection. -|dataDir |String |Directory where the Flume write ahead log should be +|dataDir |String |Directory where the Flume write-ahead log should be written. Valid only when embedded is set to true and Agent elements are used instead of Property elements. @@ -663,7 +634,7 @@ this Appender. More than one Filter may be used by using a CompositeFilter. |eventPrefix |String |The character string to prepend to each event -attribute in order to distinguish it from MDC attributes. The default is +attribute to distinguish it from MDC attributes. The default is an empty string. |flumeEventFactory |FlumeEventFactory |Factory that generates the Flume @@ -680,21 +651,20 @@ is 5. |maxDelayMillis |integer |The maximum number of milliseconds to wait for batchSize events before publishing the batch. -|mdcExcludes |String |A comma separated list of mdc keys that should be +|mdcExcludes |String |A comma-separated list of mdc keys that should be excluded from the FlumeEvent. This is mutually exclusive with the mdcIncludes attribute. -|mdcIncludes |String |A comma separated list of mdc keys that should be +|mdcIncludes |String |A comma-separated list of mdc keys that should be included in the FlumeEvent. Any keys in the MDC not found in the list will be excluded. This option is mutually exclusive with the mdcExcludes attribute. -|mdcRequired |String |A comma separated list of mdc keys that must be +|mdcRequired |String |A comma-separated list of `mdc` keys that must be present in the MDC. If a key is not present a LoggingException will be thrown. -|mdcPrefix |String |A string that should be prepended to each MDC key in -order to distinguish it from event attributes. The default string is +|mdcPrefix |String |A string that should be prepended to each MDC key to distinguish it from event attributes. The default string is "mdc:". |name |String |The name of the Appender. @@ -710,7 +680,7 @@ result in an error. When used to configure in Persistent mode the valid properties are: -1. "keyProvider" to specify the name of the plugin to provide the +1. `keyProvider` to specify the name of the plugin to provide the secret key for encryption. |requestTimeoutMillis |integer |The number of milliseconds Flume will @@ -726,9 +696,7 @@ Appender in a link:#FailoverAppender[FailoverAppender]. indicate which variation of the Appender is desired. |======================================================================= -A sample FlumeAppender configuration that is configured with a primary -and a secondary agent, compresses the body, and formats the body using -the RFC5424Layout: +A sample FlumeAppender configuration that is configured with a primary and a secondary agent compresses the body and formats the body using the RFC5424Layout: [source,xml] ---- @@ -749,9 +717,7 @@ the RFC5424Layout: ---- -A sample FlumeAppender configuration that is configured with a primary -and a secondary agent, compresses the body, formats the body using the -RFC5424Layout, and persists encrypted events to disk: +A sample FlumeAppender configuration that is configured with a primary and a secondary agent compresses the body, formats the body using the RFC5424Layout, and persists encrypted events to disk: [source,xml] ---- @@ -773,9 +739,7 @@ RFC5424Layout, and persists encrypted events to disk: ---- -A sample FlumeAppender configuration that is configured with a primary -and a secondary agent, compresses the body, formats the body using -RFC5424Layout and passes the events to an embedded Flume Agent. +A sample FlumeAppender configuration that is configured with a primary and a secondary agent compresses the body, and formats the body using RFC5424Layout and passes the events to an embedded Flume Agent. [source,xml] ---- @@ -802,10 +766,7 @@ RFC5424Layout and passes the events to an embedded Flume Agent. ---- -A sample FlumeAppender configuration that is configured with a primary -and a secondary agent using Flume configuration properties, compresses -the body, formats the body using RFC5424Layout and passes the events to -an embedded Flume Agent. +A sample FlumeAppender configuration that is configured with a primary and a secondary agent using Flume configuration properties compresses the body, formats the body using RFC5424Layout and passes the events to an embedded Flume Agent. [source,xml] ---- @@ -856,27 +817,20 @@ an embedded Flume Agent. As of Log4j 2.11.0, JDBC support has moved from the existing module `log4j-core` to the new module `log4j-jdbc`. -The JDBC Appender configured with a `DataSource` requires JNDI support so as of release 2.17.1 -this appender will not function unless `log4j2.enableJndiJdbc=true` is configured as a system property -or environment variable. See the xref:manual/configuration.adoc#enableJndiJdbc[enableJndiJdbc] system property. - -The JDBCAppender writes log events to a relational database table using -standard JDBC. It can be configured to obtain JDBC connections using a -JNDI `DataSource` or a custom factory method. Whichever approach you -take, it *_must_* be backed by a connection pool. Otherwise, logging -performance will suffer greatly. If batch statements are supported by -the configured JDBC driver and a `bufferSize` is configured to be a -positive number, then log events will be batched. Note that as of Log4j -2.8, there are two ways to configure log event to column mappings: the -original `ColumnConfig` style that only allows strings and timestamps, -and the new `ColumnMapping` plugin that uses Log4j's built-in type -conversion to allow for more data types. - -To get off the ground quickly during development, an alternative to -using a connection source based on JNDI is to use the non-pooling -`DriverManager` connection source. This connection source uses a JDBC -connection string, a user name, and a password. Optionally, you can also -use properties. +The JDBC Appender configured with a `DataSource` requires JNDI support so as of release 2.17.1 this appender will not function unless `log4j2.enableJndiJdbc=true` is configured as a system property or environment variable. +See the xref:manual/configuration.adoc#enableJndiJdbc[enableJndiJdbc] system property. + +The JDBCAppender writes log events to a relational database table using standard JDBC. +It can be configured to obtain JDBC connections using a JNDI `DataSource` or a custom factory method. +Whichever approach you take, it *_must_* be backed by a connection pool. +Otherwise, logging performance will suffer greatly. +If batch statements are supported by the configured JDBC driver and a `bufferSize` is configured to be a positive number, then log events will be batched. +Note that as of Log4j 2.8, there are two ways to configure log event to column mappings: the original `ColumnConfig` style that only allows strings and timestamps, and the new `ColumnMapping` plugin that uses Log4j's built-in type conversion to allow for more data types. + +To get off the ground quickly during development, an alternative to using a connection source based on JNDI is to use the non-pooling +`DriverManager` connection source. +This connection source uses a JDBC connection string, a username, and a password. +Optionally, you can also use properties. .JDBCAppender Parameters [cols="20%,20%,60%",options="header",] @@ -894,10 +848,10 @@ Appender in a link:#FailoverAppender[FailoverAppender]. this Appender. More than one Filter may be used by using a CompositeFilter. -|bufferSize |int |If an integer greater than 0, this causes the appender +|bufferSize |int |If an integer is greater than 0, this causes the appender to buffer log events and flush whenever the buffer reaches this size. -|connectionSource |ConnectionSource |_Required._ The connections source +|connectionSource |ConnectionSource |_Required._ The connection source from which database connections should be retrieved. |tableName |String |_Required._ The name of the database table to insert @@ -905,7 +859,7 @@ log events into. |columnConfigs |ColumnConfig[] |_Required (and/or columnMappings)._ Information about the columns that log event data should be inserted -into and how to insert that data. This is represented with multiple +into and how to insert that data. This is represented by multiple `` elements. |columnMappings |ColumnMapping[] |_Required (and/or columnConfigs)._ A @@ -942,16 +896,13 @@ application if `ignoreExceptions` is set to `false`). New in 2.11.2. |======================================================================= When configuring the JDBCAppender, you must specify a `ConnectionSource` -implementation from which the Appender gets JDBC connections. You must -use exactly one of the following nested elements: +implementation from which the Appender gets JDBC connections. +You must use exactly one of the following nested elements: * link:#JDBCDataSource[``]: Uses JNDI. -* link:#JDBCConnectionFactory[``]: Points to a -class-method pair to provide JDBC connections. -* link:#JDBCDriverManager[``]: A quick and dirty way to -get off the ground, no connection pooling. -* link:#JDBCPoolingDriver[``]: Uses Apache Commons DBCP -to provide connection pooling. +* link:#JDBCConnectionFactory[``]: Points to a class-method pair to provide JDBC connections. +* link:#JDBCDriverManager[``]: A quick and dirty way to get off the ground, no connection pooling. +* link:#JDBCPoolingDriver[``]: Uses Apache Commons DBCP to provide connection pooling. [#JDBCDataSource] .DataSource Parameters @@ -991,16 +942,16 @@ be backed by a connection pool for the same reasons. connection string. |userName |String |The database user name. You cannot specify both -properties and a user name or password. +properties and a username or password. |password |String |The database password. You cannot specify both -properties and a user name or password. +properties and a username or password. |driverClassName |String |The JDBC driver class name. Some old JDBC -Driver can only be discovered by explicitly loading them by class name. +driver can only be discovered by explicitly loading them by class name. |properties |Property[] |A list of properties. You cannot specify both -properties and a user name or password. +properties and a username or password. |======================================================================= [#JDBCPoolingDriver] @@ -1009,7 +960,7 @@ properties and a user name or password. |======================================================================= |Parameter Name |Type |Description |DriverManager parameters |DriverManager parameters |This connection -source inherits all parameter from the DriverManager connection source. +source inherits all parameters from the DriverManager connection source. |poolName |String |The pool name used to pool JDBC Connections. Defaults to `example`. You can use the JDBC connection string prefix @@ -1043,11 +994,9 @@ a pooled connection elsewhere. For example: |validationQueryTimeoutSeconds |int | See http://commons.apache.org/proper/commons-dbcp/api-2.5.0/org/apache/commons/dbcp2/PoolableConnectionFactory.html[Apache Commons DBCP PoolableConnectionFactory.] |======================================================================= -When configuring the JDBCAppender, use the nested `` elements to -specify which columns in the table should be written to and how to write -to them. The JDBCAppender uses this information to formulate a -`PreparedStatement` to insert records without SQL injection -vulnerability. +When configuring the JDBCAppender, use the nested `` elements to specify which columns in the table should be written to and how to write to them. +The JDBCAppender uses this information to formulate a +`PreparedStatement` to insert records without SQL injection vulnerability. .Column Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -1083,7 +1032,7 @@ your value should contain single quotes around it like this: You can only specify one of `literal` or `parameter`. |isEventTimestamp |boolean |Use this attribute to insert the event -timestamp in this column, which should be a SQL datetime. The value will +timestamp in this column, which should be a SQL `datetime`. The value will be inserted as a `java.sql.Types.TIMESTAMP`. Either this attribute (equal to `true`), `pattern`, or `isEventTimestamp` must be specified, but not more than one of these. @@ -1091,7 +1040,7 @@ but not more than one of these. |isUnicode |boolean |This attribute is ignored unless `pattern` is specified. If `true` or omitted (default), the value will be inserted as unicode (`setNString` or `setNClob`). Otherwise, the value will be -inserted non-unicode (`setString` or `setClob`). +inserted non-Unicode (`setString` or `setClob`). |isClob |boolean |This attribute is ignored unless `pattern` is specified. Use this attribute to indicate that the column stores @@ -1126,12 +1075,10 @@ these. |layout |Layout |The Layout to format the LogEvent. -|type |String |Conversion type name, a fully-qualified class name. +|type |String |Conversion type name, a fully qualified class name. |======================================================================= -Here are a couple sample configurations for the JDBCAppender, as well as -a sample factory implementation that uses Commons Pooling and Commons -DBCP to pool database connections: +Here are a couple of sample configurations for the JDBCAppender, as well as a sample factory implementation that uses Commons Pooling and Commons DBCP to pool database connections: [source,xml] ---- @@ -1225,11 +1172,10 @@ public class ConnectionFactory { This appender is xref:manual/messages.adoc#MapMessage[`MapMessage`]-aware. -The following configuration uses no layout to indicate that the -Appender should match the keys of a `MapMessage` to the names of +The following configuration uses no layout to indicate that the appender should match the keys of a `MapMessage` to the names of `ColumnMapping`s when setting the values of the Appender's SQL INSERT -statement. This let you insert rows for custom values in a database -table based on a Log4j `MapMessage` instead of values from `LogEvent`s. +statement. This lets you insert rows for custom values in a database +table based on a Log4j `MapMessage` instead of values from `LogEvent`. [source,xml] ---- @@ -1264,12 +1210,15 @@ table based on a Log4j `MapMessage` instead of values from `LogEvent`s. The JMS Appender sends the formatted log event to a JMS Destination. -The JMS Appender requires JNDI support so as of release 2.17.0, this appender will not function unless `log4j2.enableJndiJms=true` is configured as a system property or environment variable. See the https://logging.apache.org/log4j/2.x/manual/configuration.html#enableJndiJms[enableJndiJms] system property. +The JMS Appender requires JNDI support so as of release 2.17.0, this appender will not function unless `log4j2.enableJndiJms=true` is configured as a system property or environment variable. +See the https://logging.apache.org/log4j/2.x/manual/configuration.html#enableJndiJms[enableJndiJms] system property. -Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JMSTopicAppender. Starting in Log4j 2.1, these appenders were combined into the JMS Appender, which makes no distinction between queues and topics. However, configurations written for 2.0 which use the `` or `` elements will continue to work with the new `` configuration element. +Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JMSTopicAppender. +Starting in Log4j 2.1, these appenders were combined into the JMS Appender, which makes no distinction between queues and topics. +However, configurations written for 2.0 that use the `` or `` elements will continue to work with the new `` configuration element. .JMS Appender Parameters -[cols="1,1,1,3", options="header"] +[cols="1,1,1,3",options="header"] |=== | Parameter Name | Type | Default | Description @@ -1281,7 +1230,7 @@ Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JM | factoryName | String | _Required_ -| The fully qualified class name that should be used to define the Initial Context Factory as defined in https://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#INITIAL_CONTEXT_FACTORY[INITIAL_CONTEXT_FACTORY]. If a factoryName is specified without a providerURL, a warning message will be logged as this is likely to cause problems. +| The fully qualified class name that should be used to define the Initial Context Factory as defined in https://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#INITIAL_CONTEXT_FACTORY[INITIAL_CONTEXT_FACTORY]. If a `factoryName` is specified without a `providerURL`, a warning message will be logged as this is likely to cause problems. | filter | Filter @@ -1316,7 +1265,7 @@ Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JM | securityPrincipalName | String | null -| The name of the identity of the Principal as specified by https://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#SECURITY_PRINCIPAL[SECURITY_PRINCIPAL]. If a securityPrincipalName is specified without securityCredentials, a warning message will be logged as this is likely to cause problems. +| The name of the identity of the Principal as specified by https://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#SECURITY_PRINCIPAL[SECURITY_PRINCIPAL]. If a securityPrincipalName is specified without `securityCredentials`, a warning message will be logged as this is likely to cause problems. | securityCredentials | String @@ -1346,7 +1295,7 @@ Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JM | userName | String | null -| The user id used to create the JMS connection. +| The user ID used to create the JMS connection. |=== Here is a sample JMS Appender configuration: @@ -1369,8 +1318,7 @@ Here is a sample JMS Appender configuration: ---- -To map your Log4j `MapMessage` to JMS `javax.jms.MapMessage`, set the -layout of the appender to `MessageLayout` with `<MessageLayout />` (Since 2.9.): +To map your Log4j `MapMessage` to JMS `javax.jms.MapMessage`, set the layout of the appender to `MessageLayout` with `<MessageLayout />` (Since 2.9.): [source,xml] ---- @@ -1395,7 +1343,14 @@ layout of the appender to `MessageLayout` with `<MessageLayout />` (Since As of Log4j 2.11.0, JPA support has moved from the existing module `log4j-core` to the new module `log4j-jpa`. -The JPAAppender writes log events to a relational database table using the Java Persistence API 2.1. It requires the API and a provider implementation be on the classpath. It also requires a decorated entity configured to persist to the table desired. The entity should either extend `org.apache.logging.log4j.core.appender.db.jpa.BasicLogEventEntity` (if you mostly want to use the default mappings) and provide at least an `@Id` property, or `org.apache.logging.log4j.core.appender.db.jpa.AbstractLogEventWrapperEntity` (if you want to significantly customize the mappings). See the Javadoc for these two classes for more information. You can also consult the source code of these two classes as an example of how to implement the entity. +The JPAAppender writes log events to a relational database table using the Java Persistence API 2.1. +It requires the API and a provider implementation to be on the classpath. +It also requires a decorated entity configured to persist to the table desired. + +If you want to use the default mappings, you can extend `org.apache.logging.log4j.core.appender.db.jpa.BasicLogEventEntity` and provide an `@Id` property. +If you want to significantly customize the mappings, you can extend `org.apache.logging.log4j.core.appender.db.jpa.AbstractLogEventWrapperEntity`. + +See the Javadoc or source code for these two classes for more information and examples. [width="100%",options="header"] |=== @@ -1415,7 +1370,7 @@ The JPAAppender writes log events to a relational database table using the Java |bufferSize |int -|If an integer greater than 0, this causes the appender to buffer log events and flush whenever the buffer reaches this size. +|If an integer is greater than 0, this causes the appender to buffer log events and flush whenever the buffer reaches this size. |entityClassName |String @@ -1426,7 +1381,13 @@ The JPAAppender writes log events to a relational database table using the Java |_Required._ The name of the JPA persistence unit that should be used for persisting log events. |=== -Here is a sample configuration for the JPAAppender. The first XML sample is the Log4j configuration file, the second is the `persistence.xml` file. EclipseLink is assumed here, but any JPA 2.1 or higher provider will do. You should _always_ create a _separate_ persistence unit for logging, for two reasons. First, `` _must_ be set to "NONE," which is usually not desired in normal JPA usage. Also, for performance reasons the logging entity should be isolated in its own persistence unit away from all other entities and you should use a non-JTA data source. Note that your persistence unit _must_ also contain `` elements for all of the `org.apache.logging.log4j.core.appender.db.jpa.converter` converter classes. +Here is a sample configuration for the JPAAppender. +The first XML sample is the Log4j configuration file, the second is the `persistence.xml` file. +EclipseLink is assumed here, but any JPA 2.1 or higher provider will do. +You should _always_ create a _separate_ persistence unit for logging, for two reasons. +First, `` _must_ be set to "NONE," which is usually not desired in normal JPA usage. +Also, for performance reasons the logging entity should be isolated in its persistence unit away from all other entities and you should use a non-JTA data source. +Note that your persistence unit _must_ also contain `` elements for all of the `org.apache.logging.log4j.core.appender.db.jpa.converter` converter classes. [source,xml] ---- @@ -1558,14 +1519,13 @@ public class JpaLogEntity extends AbstractLogEventWrapperEntity { [#HttpAppender] == HttpAppender -The HttpAppender sends log events over HTTP. A Layout must be provided -to format the LogEvent. +The HttpAppender sends log events over HTTP. +A Layout must be provided to format the LogEvent. -Will set the `Content-Type` header according to the layout. Additional -headers can be specified with embedded Property elements. +It will set the `Content-Type` header according to the layout. +Additional headers can be specified with embedded Property elements. -Will wait for response from server, and throw error if no 2xx response -is received. +It will also wait for a response from the server, and throw an error if no 2xx response is received. Implemented with https://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html[HttpURLConnection]. @@ -1633,7 +1593,8 @@ Here is a sample HttpAppender configuration snippet: [[KafkaAppender]] == KafkaAppender -The KafkaAppender logs events to an https://kafka.apache.org/[Apache Kafka] topic. Each log event is sent as a Kafka record. +The KafkaAppender logs events to an https://kafka.apache.org/[Apache Kafka] topic. +Each log event is sent as a Kafka record. [width="100%",options="header"] |=== @@ -1665,7 +1626,7 @@ The KafkaAppender logs events to an https://kafka.apache.org/[Apache Kafka] topi |syncSend |boolean -|The default is `true`, causing sends to block until the record has been acknowledged by the Kafka server. When set to `false`, sends return immediately, allowing for lower latency and significantly higher throughput. _New since 2.8. Be aware that this is a new addition, and it has not been extensively tested. Any failure sending to Kafka will be reported as error to StatusLogger and the log event will be dropped (the ignoreExceptions parameter will not be effective). Log events may arrive out of order to the Kafka server._ +|The default is `true`, causing sends to block until the record has been acknowledged by the Kafka server. When set to `false`, sends a return immediately, allowing for lower latency and significantly higher throughput. _New since 2.8. Be aware that this is a new addition, and it has not been extensively tested. Any failure sending to Kafka will be reported as an error to StatusLogger and the log event will be dropped (the ignoreExceptions parameter will not be effective). Log events may arrive out of order on the Kafka server._ |properties |Property[] @@ -1689,9 +1650,11 @@ Here is a sample KafkaAppender configuration snippet: ---- -This appender is synchronous by default and will block until the record has been acknowledged by the Kafka server, timeout for this can be set with the `timeout.ms` property (defaults to 30 seconds). Wrap with https://logging.apache.org/log4j/2.x/manual/appenders.html#AsyncAppender[Async appender] and/or set syncSend to `false` to log asynchronously. +This appender is synchronous by default and will block until the record has been acknowledged by the Kafka server, timeout for this can be set with the `timeout.ms` property (defaults to 30 seconds). +Wrap with https://logging.apache.org/log4j/2.x/manual/appenders.html#AsyncAppender[Async appender] and/or set syncSend to `false` to log asynchronously. -This appender requires the https://kafka.apache.org/[Kafka client library]. Note that you need to use a version of the Kafka client library matching the Kafka server used. +This appender requires the https://kafka.apache.org/[Kafka client library]. +Note that you need to use a version of the Kafka client library matching the Kafka server used. _Note:_ Make sure to not let `org.apache.kafka` log to a Kafka appender on DEBUG level, since that will cause recursive logging: @@ -1710,45 +1673,28 @@ _Note:_ Make sure to not let `org.apache.kafka` log to a Kafka appender on DEBUG ---- - [#MemoryMappedFileAppender] == MemoryMappedFileAppender -_New since 2.1. Be aware that this is a new addition, and although it -has been tested on several platforms, it does not have as much track -record as the other file appenders._ - -The MemoryMappedFileAppender maps a part of the specified file into -memory and writes log events to this memory, relying on the operating -system's virtual memory manager to synchronize the changes to the -storage device. The main benefit of using memory mapped files is I/O -performance. Instead of making system calls to write to disk, this -appender can simply change the program's local memory, which is orders -of magnitude faster. Also, in most operating systems the memory region -mapped actually is the kernel's -http://en.wikipedia.org/wiki/Page_cache[page cache] (file cache), -meaning that no copies need to be created in user space. +_New since 2.1. Be aware that this is a new addition, and although it has been tested on several platforms, it does not have as much track record as the other file appenders._ + +The MemoryMappedFileAppender maps a part of the specified file into memory and writes log events to this memory, relying on the operating system's virtual memory manager to synchronize the changes to the storage device. +The main benefit of using memory-mapped files is I/O performance. +Instead of making system calls to write to disk, this appender can simply change the program's local memory, which is orders of magnitude faster. +Also, in most operating systems the memory region mapped is the kernel's +http://en.wikipedia.org/wiki/Page_cache[page cache] (file cache), meaning that no copies need to be created in user space. // TODO: // performance tests that compare performance of this appender to // RandomAccessFileAppender and FileAppender.) -There is some overhead with mapping a file region into memory, -especially very large regions (half a gigabyte or more). The default -region size is 32 MB, which should strike a reasonable balance between -the frequency and the duration of remap operations. +There is some overhead with mapping a file region into memory, especially very large regions (half a gigabyte or more). +The default region size is 32 MB, which should strike a reasonable balance between the frequency and the duration of remap operations. -// (TODO: performance -// test remapping various sizes.) +// (TODO: performance test remapping various sizes.) -Similar to the FileAppender and the RandomAccessFileAppender, -MemoryMappedFileAppender uses a MemoryMappedFileManager to actually -perform the file I/O. While MemoryMappedFileAppender from different -Configurations cannot be shared, the MemoryMappedFileManagers can be if -the Manager is accessible. For example, two web applications in a -servlet container can have their own configuration and safely write to -the same file if Log4j is in a ClassLoader that is common to both of -them. +Similar to the FileAppender and the RandomAccessFileAppender, MemoryMappedFileAppender uses a MemoryMappedFileManager to actually perform the file I/O. While MemoryMappedFileAppender from different Configurations cannot be shared, the MemoryMappedFileManagers can be if the manager is accessible. +For example, two web applications in a servlet container can have its own configuration and safely write to the same file if Log4j is in a ClassLoader that is common to both of them. .MemoryMappedFileAppender Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -1775,7 +1721,7 @@ written to the storage device even if the Java process crashes, but there may be data loss if the operating system crashes. Note that manually forcing a sync on every log event loses most of the -performance benefits of using a memory mapped file. +performance benefits of using a memory-mapped file. Flushing after every write is only useful when using this appender with synchronous loggers. Asynchronous loggers and appenders will @@ -1825,10 +1771,8 @@ Here is a sample MemoryMappedFile configuration: [#NoSQLAppender] == NoSQLAppender -The NoSQLAppender writes log events to a NoSQL database using an -internal lightweight provider interface. Provider implementations -currently exist for MongoDB, and writing a custom -provider is quite simple. +The NoSQLAppender writes log events to a NoSQL database using an internal lightweight provider interface. +Provider implementations currently exist for MongoDB, and writing a custom provider is quite simple. .NoSQLAppender Parameters [cols="20%,20%,60%",options="header",] @@ -1846,7 +1790,7 @@ Appender in a link:#FailoverAppender[FailoverAppender]. this Appender. More than one Filter may be used by using a CompositeFilter. -|bufferSize |int |If an integer greater than 0, this causes the appender +|bufferSize |int |If an integer is greater than 0, this causes the appender to buffer log events and flush whenever the buffer reaches this size. |NoSqlProvider |NoSQLProvider>> |_Required._ The NoSQL provider that provides connections to the chosen NoSQL database. |======================================================================= -You specify which NoSQL provider to use by specifying the appropriate -configuration element within the `` element. The only type currently -supported is ``. To create your own custom -provider, read the JavaDoc for the `NoSQLProvider`, `NoSQLConnection`, -and `NoSQLObject` classes and the documentation about creating Log4j -plugins. We recommend you review the source code for the MongoDB -providers as a guide for creating your own provider. +You specify which NoSQL provider to use by specifying the appropriate configuration element within the `` element. +The only type currently supported is ``. +To create your custom provider, read the JavaDoc for the `NoSQLProvider`, `NoSQLConnection`, and `NoSQLObject` classes and the documentation about creating Log4j plugins. +We recommend you review the source code for the MongoDB providers as a guide for creating your provider. -The following example demonstrates how log events are persisted in NoSQL -databases if represented in a JSON format: +The following example demonstrates how log events are persisted in NoSQL databases if represented in a JSON format: [source,json] ---- @@ -1929,22 +1869,22 @@ Starting with Log4 2.11.0, we provide the following MongoDB modules: * Added in 2.14.0, deprecated in 2.24.0: `log4j-mongodb4` defines the configuration element link:#NoSQLAppenderMongoDB4[`MongoDb4`] matching the MongoDB Driver version 4. * Added in 2.24.0: `log4j-mongodb` defines the configuration element -link:#NoSQLAppenderMongoDBCurrent[`MongoDb`] matching the current MongoDB Driver (version 5). This module tracks the current MongoDB Driver. +link:#NoSQLAppenderMongoDBCurrent[`MongoDb`] matching the current MongoDB Driver (version 5). +This module tracks the current MongoDB Driver. [#NoSQLAppenderMongoDBCurrent] == NoSQL Appender for MongoDB This section details specializations of the -link:#NoSQLAppender[NoSQLAppender] provider for MongoDB using the -current MongoDB driver (version 5). The NoSQLAppender Appender writes log events -to a NoSQL database using an internal lightweight provider interface. +link:#NoSQLAppender[NoSQLAppender] provider for MongoDB using the current MongoDB driver (version 5). +The NoSQLAppender Appender writes log events to a NoSQL database using an internal lightweight provider interface. .MongoDB Provider Parameters [cols="20%,20%,60%",options="header",] |======================================================================= |Parameter Name |Type |Description -|connection |String |_Required._ The MongoDB -http://mongodb.github.io/mongo-java-driver/5.0/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html?is-external=true"[connection string] +|connection |String |_Required._ The MongoDB +http://mongodb.github.io/mongo-java-driver/5.0/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html?is-external=true"[connection string] in the format `mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database.collection][?options]]`. |capped |boolean |Enable support for @@ -1959,8 +1899,7 @@ collection documentation linked above for more information. This appender is xref:manual/messages.adoc#MapMessage[MapMessage]-aware. -Here are a few sample configurations for the NoSQLAppender and MongoDB4 -provider: +Here are a few sample configurations for the NoSQLAppender and MongoDB4 provider: [source,xml] ---- @@ -2028,16 +1967,14 @@ You can define additional fields to log using KeyValuePair elements, for example The `log4j-mongodb4` module is deprecated in favor of link:#NoSQLAppenderMongoDBCurrent[NoSQLAppender for MongoDB]. This section details specializations of the -link:#NoSQLAppender[NoSQLAppender] provider for MongoDB using the -MongoDB driver version 4. The NoSQLAppender Appender writes log events -to a NoSQL database using an internal lightweight provider interface. +link:#NoSQLAppender[NoSQLAppender] provider for MongoDB using the MongoDB driver version 4. The NoSQLAppender Appender writes log events to a NoSQL database using an internal lightweight provider interface. .MongoDB Provider Parameters [cols="20%,20%,60%",options="header",] |======================================================================= |Parameter Name |Type |Description -|connection |String |_Required._ The MongoDB -http://mongodb.github.io/mongo-java-driver/4.0/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html?is-external=true"[connection string] +|connection |String |_Required._ The MongoDB +http://mongodb.github.io/mongo-java-driver/4.0/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html?is-external=true"[connection string] in the format `mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database.collection][?options]]`. |capped |boolean |Enable support for @@ -2052,8 +1989,7 @@ collection documentation linked above for more information. This appender is xref:manual/messages.adoc#MapMessage[MapMessage]-aware. -Here are a few sample configurations for the NoSQLAppender and MongoDB4 -provider: +Here are a few sample configurations for the NoSQLAppender and MongoDB4 provider: [source,xml] ---- @@ -2118,7 +2054,8 @@ You can define additional fields to log using KeyValuePair elements, for example [[NoSQLAppenderApacheCouchDB]] == NoSQLAppender for Apache CouchDB -This section details specializations of the link:#NoSQLAppender[NoSQLAppender] provider for CouchDB. The NoSQLAppender writes log events to a NoSQL database using an internal lightweight provider interface. +This section details specializations of the link:#NoSQLAppender[NoSQLAppender] provider for CouchDB. +The NoSQLAppender writes log events to a NoSQL database using an internal lightweight provider interface. [width="100%",options="header"] |=== @@ -2126,7 +2063,7 @@ This section details specializations of the link:#NoSQLAppender[NoSQLAppender] p |factoryClassName |Class -|To provide a connection to the CouchDB database, you can use this attribute and `factoryMethodName` to specify a class and static method to get the connection from. The method must return a `org.lightcouch.CouchDbClient` or a `org.lightcouch.CouchDbProperties`. If you use the factory method for providing a connection, you must not specify the `databaseName`, `protocol`, `server`, `port`, `username`, or `password` attributes. +|To provide a connection to the CouchDB database, you can use this attribute and `factoryMethodName` to specify a class and static method to retrieve the connection. The method must return an `org.lightcouch.CouchDbClient` or a `org.lightcouch.CouchDbProperties`. If you use the factory method for providing a connection, you must not specify the `databaseName`, `protocol`, `server`, `port`, `username`, or `password` attributes. |factoryMethodName |Method @@ -2134,7 +2071,7 @@ This section details specializations of the link:#NoSQLAppender[NoSQLAppender] p |databaseName |String -|If you do not specify a `factoryClassName` and `factoryMethodName` for providing a CouchDB connection, you must specify a CouchDB database name using this attribute. You must also specify a `username` and `password`. You can optionally also specify a `protocol` (defaults to http), `server` (defaults to localhost), and a `port` (defaults to 80 for http and 443 for https). +|If you do not specify a `factoryClassName` and `factoryMethodName` for providing a CouchDB connection, you must specify a CouchDB database name using this attribute. You must also specify a `username` and `password`. You can optionally also specify a `protocol` (defaults to `http`), `server` (defaults to localhost), and a `port` (defaults to 80 for `http` and 443 for `https`). |protocol |String @@ -2177,35 +2114,24 @@ Here are a few sample configurations for the NoSQLAppender and CouchDB provider: ---- - [#OutputStreamAppender] == OutputStreamAppender -The OutputStreamAppender provides the base for many of the other -Appenders such as the File and Socket appenders that write the event to -an Output Stream. It cannot be directly configured. Support for -immediateFlush and buffering is provided by the OutputStreamAppender. -The OutputStreamAppender uses an OutputStreamManager to handle the -actual I/O, allowing the stream to be shared by Appenders in multiple -configurations. +The OutputStreamAppender provides the base for many of the other Appenders such as the File and Socket appenders that write the event to an Output Stream. +It cannot be directly configured. +Support for immediateFlush and buffering is provided by the OutputStreamAppender. +The OutputStreamAppender uses an OutputStreamManager to handle the actual I/O, allowing the stream to be shared by Appenders in multiple configurations. [#RandomAccessFileAppender] == RandomAccessFileAppender The RandomAccessFileAppender is similar to the standard -link:#FileAppender[FileAppender] except it is always buffered (this -cannot be switched off) and internally it uses a -`ByteBuffer + RandomAccessFile` instead of a `BufferedOutputStream`. We -saw a 20-200% performance improvement compared to FileAppender with -"bufferedIO=true" in our -xref:manual/performance.adoc#whichAppender[measurements]. Similar to the -FileAppender, RandomAccessFileAppender uses a RandomAccessFileManager to -actually perform the file I/O. While RandomAccessFileAppender from -different Configurations cannot be shared, the RandomAccessFileManagers -can be if the Manager is accessible. For example, two web applications -in a servlet container can have their own configuration and safely write -to the same file if Log4j is in a ClassLoader that is common to both of -them. +link:#FileAppender[FileAppender] except it is always buffered (this cannot be switched off) and internally it uses a +`ByteBuffer + RandomAccessFile` instead of a `BufferedOutputStream`. +We saw a 20-200% performance improvement compared to FileAppender with "bufferedIO=true" in our +xref:manual/performance.adoc#whichAppender[measurements]. +Similar to the FileAppender, RandomAccessFileAppender uses a RandomAccessFileManager to perform the file I/O. While RandomAccessFileAppender from different Configurations cannot be shared, the RandomAccessFileManagers can be if the Manager is accessible. +For example, two web applications in a servlet container can have their configuration and safely write to the same file if Log4j is in a ClassLoader that is common to both of them. .RandomAccessFileAppender Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -2225,7 +2151,7 @@ CompositeFilter. |immediateFlush |boolean a| When set to true - the default, each write will be followed by a flush. This will guarantee that the data is passed to the operating system for writing; -it does not guarantee that the data is actually written to a physical device +it does not guarantee that the data is written to a physical device such as a disk drive. Note that if this flag is set to false, and the logging activity is sparse, @@ -2279,12 +2205,10 @@ Here is a sample RandomAccessFile configuration: [#RewriteAppender] == RewriteAppender -The RewriteAppender allows the LogEvent to manipulated before it is -processed by another Appender. This can be used to mask sensitive -information such as passwords or to inject information into each event. -The RewriteAppender must be configured with a RewritePolicy. The -RewriteAppender should be configured after any Appenders it references -to allow it to shut down properly. +The RewriteAppender allows the LogEvent to be manipulated before it is processed by another Appender. +This can be used to mask sensitive information such as passwords or to inject information into each event. +The RewriteAppender must be configured with a RewritePolicy. +The RewriteAppender should be configured after any Appenders it references to allow it to shut down properly. .RewriteAppender Parameters [cols="20%,20%,60%",options="header",] @@ -2313,16 +2237,13 @@ Appender in a link:#FailoverAppender[FailoverAppender]. [#RewritePolicy] === RewritePolicy -RewritePolicy is an interface that allows implementations to inspect and -possibly modify LogEvents before they are passed to Appender. -RewritePolicy declares a single method named rewrite that must be -implemented. The method is passed the LogEvent and can return the same -event or create a new one. +RewritePolicy is an interface that allows implementations to inspect and possibly modify LogEvents before they are passed to Appender. +RewritePolicy declares a single method named rewrite that must be implemented. +The method is passed the LogEvent and can return the same event or create a new one. ==== MapRewritePolicy -MapRewritePolicy will evaluate LogEvents that contain a MapMessage and -will add or update elements of the Map. +MapRewritePolicy will evaluate LogEvents that contain a MapMessage and will add or update elements of the Map. [cols="20%,20%,60%",options="header",] |================================================================ @@ -2331,8 +2252,7 @@ will add or update elements of the Map. |keyValuePair |KeyValuePair[] |An array of keys and their values. |================================================================ -The following configuration shows a RewriteAppender configured to add a -product key and its value to the MapMessage.: +The following configuration shows a RewriteAppender configured to add a product key and its value to the MapMessage.: [source,xml] ---- @@ -2359,11 +2279,9 @@ product key and its value to the MapMessage.: ==== PropertiesRewritePolicy -PropertiesRewritePolicy will add properties configured on the policy to -the ThreadContext Map being logged. The properties will not be added to -the actual ThreadContext Map. The property values may contain variables -that will be evaluated when the configuration is processed as well as -when the event is logged. +PropertiesRewritePolicy will add properties configured on the policy to the ThreadContext Map being logged. +The properties will not be added to the actual ThreadContext Map. +The property values may contain variables that will be evaluated when the configuration is processed as well as when the event is logged. [cols="20%,20%,60%",options="header",] |======================================================================= @@ -2372,8 +2290,7 @@ when the event is logged. keys and values to be added to the ThreadContext Map. |======================================================================= -The following configuration shows a RewriteAppender configured to add a -product key and its value to the MapMessage: +The following configuration shows a RewriteAppender configured to add a product key and its value to the MapMessage: [source,xml] ---- @@ -2401,11 +2318,9 @@ product key and its value to the MapMessage: ==== LoggerNameLevelRewritePolicy -You can use this policy to make loggers in third party code less chatty -by changing event levels. The LoggerNameLevelRewritePolicy will rewrite -log event levels for a given logger name prefix. You configure a -LoggerNameLevelRewritePolicy with a logger name prefix and a pairs of -levels, where a pair defines a source level and a target level. +You can use this policy to make loggers in third-party code less chatty by changing event levels. +The LoggerNameLevelRewritePolicy will rewrite log event levels for a given logger name prefix. +You configure a LoggerNameLevelRewritePolicy with a logger name prefix and a pair of levels, where a pair defines a source level and a target level. [cols="20%,20%,60%",options="header",] |======================================================================= @@ -2417,9 +2332,7 @@ logger name. is a source level, each value a target level. |======================================================================= -The following configuration shows a RewriteAppender configured to map -level INFO to DEBUG and level WARN to INFO for all loggers that start -with `com.foo.bar`. +The following configuration shows a RewriteAppender configured to map level INFO to DEBUG and level WARN to INFO for all loggers that start with `com.foo.bar`. [source,xml] ---- @@ -2445,36 +2358,29 @@ with `com.foo.bar`. ---- -[#RollingFileAppender] -== RollingFileAppender +[id=rollingfileappender] +== [[RollingFileAppender]] RollingFileAppender -The RollingFileAppender is an OutputStreamAppender that writes to the -File named in the fileName parameter and rolls the file over according -the TriggeringPolicy and the RolloverPolicy. The RollingFileAppender -uses a RollingFileManager (which extends OutputStreamManager) to -actually perform the file I/O and perform the rollover. While -RolloverFileAppenders from different Configurations cannot be shared, -the RollingFileManagers can be if the Manager is accessible. For -example, two web applications in a servlet container can have their own -configuration and safely write to the same file if Log4j is in a -ClassLoader that is common to both of them. +The RollingFileAppender is an OutputStreamAppender that writes to the file named in the fileName parameter and rolls the file over according to the `TriggeringPolicy` and the `RolloverPolicy`. +The `RollingFileAppender` +uses a `RollingFileManager` (which extends `OutputStreamManager`) to perform the file I/O and perform the rollover. +While `RolloverFileAppenders` from different Configurations cannot be shared, the `RollingFileManagers` can be if the Manager is accessible. +For example, two web applications in a servlet container can have their configuration and safely write to the same file if Log4j is in a +`ClassLoader` that is common to both of them. A RollingFileAppender requires a link:#TriggeringPolicies[TriggeringPolicy] and a -link:#RolloverStrategies[RolloverStrategy]. The triggering policy -determines if a rollover should be performed while the RolloverStrategy -defines how the rollover should be done. If no RolloverStrategy is -configured, RollingFileAppender will use the -link:#DefaultRolloverStrategy[DefaultRolloverStrategy]. Since log4j-2.5, -a link:#CustomDeleteOnRollover[custom delete action] can be configured -in the DefaultRolloverStrategy to run at rollover. Since 2.8 if no file -name is configured then -link:#DirectWriteRolloverStrategy[DirectWriteRolloverStrategy] will be -used instead of DefaultRolloverStrategy. Since log4j-2.9, a +link:#RolloverStrategies[RolloverStrategy]. +The triggering policy determines if a rollover should be performed while the `RolloverStrategy` +defines how the rollover should be done. +If no `RolloverStrategy` is configured, `RollingFileAppender` will use the +link:#DefaultRolloverStrategy[DefaultRolloverStrategy]. +Since log4j-2.5, a link:#CustomDeleteOnRollover[custom delete action] can be configured in the DefaultRolloverStrategy to run at rollover. +Since 2.8 if no file name is configured then +link:#DirectWriteRolloverStrategy[DirectWriteRolloverStrategy] will be used instead of DefaultRolloverStrategy. +Since log4j-2.9, a link:#CustomPosixViewAttributeOnRollover[custom POSIX file attribute -view action] can be configured in the DefaultRolloverStrategy to run at -rollover, if not defined, inherited POSIX file attribute view from the -RollingFileAppender will be applied. +view action] can be configured in the DefaultRolloverStrategy to run at rollover, if not defined, the inherited POSIX file attribute view from the RollingFileAppender will be applied. File locking is not supported by the RollingFileAppender. @@ -2508,7 +2414,7 @@ CompositeFilter. of its parent directories, do not exist, they will be created. |filePattern |String |The pattern of the file name of the archived log -file. The format of the pattern is dependent on the RolloverPolicy that +file. The format of the pattern is dependent on the `RolloverPolicy` that is used. The DefaultRolloverPolicy will accept both a date/time pattern compatible with https://download.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html[`SimpleDateFormat`] @@ -2523,7 +2429,7 @@ pattern. |immediateFlush |boolean a| When set to true - the default, each write will be followed by a flush. This will guarantee that the data is passed to the operating system for writing; -it does not guarantee that the data is actually written to a physical device +it does not guarantee that the data is written to a physical device such as a disk drive. Note that if this flag is set to false, and the logging activity is sparse, @@ -2547,7 +2453,7 @@ is supplied the default pattern layout of "%m%n" will be used. should occur. |strategy |RolloverStrategy |The strategy to use to determine the name -and location of the archive file. +and the location of the archive file. |ignoreExceptions |boolean |The default is `true`, causing exceptions encountered while appending events to be internally logged and then @@ -2559,7 +2465,7 @@ Appender in a link:#FailoverAppender[FailoverAppender]. File attribute permissions in POSIX format to apply whenever the file is created. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -2568,21 +2474,21 @@ Examples: rw------- or rw-rw-rw- etc... |fileOwner |String a| File owner to define whenever the file is created. -Changing file's owner may be restricted for security reason and +Changing the file's owner may be restricted for security reasons and Operation not permitted IOException thrown. Only processes with an effective user ID equal to the user ID of the file or with appropriate privileges may change the ownership of a file if http://www.gnu.org/software/libc/manual/html_node/Options-for-Files.html[_POSIX_CHOWN_RESTRICTED] is in effect for path. -Underlying files system shall support file +The underlying files system shall support file https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/FileOwnerAttributeView.html[owner] attribute view. |fileGroup |String a| File group to define whenever the file is created. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -2593,14 +2499,11 @@ file attribute view. === Composite Triggering Policy -The `CompositeTriggeringPolicy` combines multiple triggering policies -and returns true if any of the configured policies return true. The -`CompositeTriggeringPolicy` is configured simply by wrapping other -policies in a `Policies` element. +The `CompositeTriggeringPolicy` combines multiple triggering policies and returns true if any of the configured policies return true. +The +`CompositeTriggeringPolicy` is configured simply by wrapping other policies in a `Policies` element. -For example, the following XML fragment defines policies that rollover -the log when the JVM starts, when the log size reaches twenty megabytes, -and when the current date no longer matches the log’s start date. +For example, the following XML fragment defines policies that rollover the log when the JVM starts when the log size reaches twenty megabytes, and when the current date no longer matches the log's start date. [source,xml] ---- @@ -2613,11 +2516,9 @@ and when the current date no longer matches the log’s start date. === Cron Triggering Policy -The `CronTriggeringPolicy` triggers rollover based on a cron expression. This policy -is controlled by a timer and is asynchronous to processing log events, so it is possible that log events -from the previous or next time period may appear at the beginning or end of the log file. -The filePattern attribute of the Appender should contain a timestamp otherwise the target file will be -overwritten on each rollover. +The `CronTriggeringPolicy` triggers rollover based on a cron expression. +This policy is controlled by a timer and is asynchronous in processing log events, so it is possible that log events from the previous or next period may appear at the beginning or end of the log file. +The `filePattern` attribute of the Appender should contain a timestamp otherwise the target file will be overwritten on each rollover. .CronTriggeringPolicy Parameters [cols="20%,20%,60%",options="header",] @@ -2636,44 +2537,39 @@ and the current time the file will be immediately rolled over. === OnStartup Triggering Policy -The `OnStartupTriggeringPolicy` policy causes a rollover if the log file -is older than the current JVM's start time and the minimum file size is -met or exceeded. +The `OnStartupTriggeringPolicy` policy causes a rollover if the log file is older than the current JVM's start time and the minimum file size is met or exceeded. .OnStartupTriggeringPolicy Parameters [cols="20%,20%,60%",options="header",] |======================================================================= |Parameter Name |Type |Description |minSize |long |The minimum size the file must have to roll over. A size -of zero will cause a roll over no matter what the file size is. The +of zero will cause a rollover no matter what the file size is. The default value is 1, which will prevent rolling over an empty file. |======================================================================= _Google App Engine note:_ + -When running in Google App Engine, the OnStartup policy causes a -rollover if the log file is older than _the time when Log4J -initialized_. (Google App Engine restricts access to certain classes so -Log4J cannot determine JVM start time with +When running in Google App Engine, the OnStartup policy causes a rollover if the log file is older than _the time when Log4J initialized_. +(Google App Engine restricts access to certain classes so Log4J cannot determine JVM start time with `java.lang.management.ManagementFactory.getRuntimeMXBean().getStartTime()` and falls back to Log4J initialization time instead.) === SizeBased Triggering Policy -The `SizeBasedTriggeringPolicy` causes a rollover once the file has reached the specified size. The size can be -specified in bytes, with the suffix KB, MB, GB, or TB for example `20MB`. -size.The size may also contain a fractional value such as `1.5 MB`. The size is evaluated -using the Java root Locale so a period must always be used for the fractional unit. -When combined with a time based triggering policy the file pattern must contain a `%i` -otherwise the target file will be overwritten on every rollover as the SizeBased Triggering Policy -will not cause the timestamp value in the file name to change. When used without a time based -triggering policy the SizeBased Triggering Policy will cause the timestamp value to change. +The `SizeBasedTriggeringPolicy` causes a rollover once the file has reached the specified size. +The size can be specified in bytes, with the suffix KB, MB, GB, or TB for example `20MB`. +size. +The size may also contain a fractional value such as `1.5 MB`. +The size is evaluated using the Java root Locale so a period must always be used for the fractional unit. +When combined with a time-based triggering policy the file pattern must contain a `%i`. +Otherwise, the target file will be overwritten on every rollover as the SizeBased Triggering Policy will not cause the timestamp value in the file name to change. +When used without a time-based triggering policy the SizeBased Triggering Policy will cause the timestamp value to change. === TimeBased Triggering Policy -The `TimeBasedTriggeringPolicy` causes a rollover once the date/time -pattern no longer applies to the active file. This policy accepts an -`interval` attribute which indicates how frequently the rollover should -occur based on the time pattern and a `modulate` boolean attribute. +The `TimeBasedTriggeringPolicy` causes a rollover once the date/time pattern no longer applies to the active file. +This policy accepts an +`interval` attribute which indicates how frequently the rollover should occur based on the time pattern and a `modulate` boolean attribute. .TimeBasedTriggeringPolicy Parameters [cols="20%,20%,60%",options="header",] @@ -2681,19 +2577,19 @@ occur based on the time pattern and a `modulate` boolean attribute. |Parameter Name |Type |Description |interval |integer |How often a rollover should occur based on the most specific time unit in the date pattern. For example, with a date pattern -with hours as the most specific item and and increment of 4 rollovers +with hours as the most specific item, an increment of 4 rollovers would occur every 4 hours. The default value is 1. |modulate |boolean |Indicates whether the interval should be adjusted to cause the next rollover to occur on the interval boundary. For example, if the item is hours, the current hour is 3 am and the interval is 4 -then the first rollover will occur at 4 am and then next ones will occur -at 8 am, noon, 4pm, etc. The default value is false. +then the first rollover will occur at 4 am and then the next ones will occur +at 8 am, noon, 4 pm, etc. The default value is false. |maxRandomDelay |integer |Indicates the maximum number of seconds to randomly delay a rollover. By default, this is 0 which indicates no delay. This setting is useful on servers where multiple applications are -configured to rollover log files at the same time and can spread the +configured to roll over logfiles at the same time and can spread the load of doing so across time. |======================================================================= @@ -2705,26 +2601,20 @@ load of doing so across time. Default Rollover Strategy -The default rollover strategy accepts both a date/time pattern and an -integer from the filePattern attribute specified on the -RollingFileAppender itself. If the date/time pattern is present it will -be replaced with the current date and time values. If the pattern -contains an integer it will be incremented on each rollover. If the -pattern contains both a date/time and integer in the pattern the integer -will be incremented until the result of the date/time pattern changes. -If the file pattern ends with ".gz", ".zip", ".bz2", ".deflate", -".pack200", or ".xz" the resulting archive will be compressed using the -compression scheme that matches the suffix. The formats bzip2, Deflate, -Pack200 and XZ require +The default rollover strategy accepts both a date/time pattern and an integer from the `filePattern` attribute specified on the RollingFileAppender itself. +If the date/time pattern is present it will be replaced with the current date and time values. +If the pattern contains an integer it will be incremented on each rollover. +If the pattern contains both a date/time and integer in the pattern the integer will be incremented until the result of the date/time pattern changes. +If the file pattern ends with ".gz", ".zip", ".bz2", ".deflate", ".pack200", or ".xz" the resulting archive will be compressed using the compression scheme that matches the suffix. +The formats bzip2, Deflate, Pack200 and XZ require http://commons.apache.org/proper/commons-compress/[Apache Commons -Compress]. In addition, XZ requires http://tukaani.org/xz/java.html[XZ -for Java]. The pattern may also contain lookup references that can be -resolved at runtime such as is shown in the example below. +Compress]. +In addition, XZ requires http://tukaani.org/xz/java.html[XZ +for Java]. +The pattern may also contain lookup references that can be resolved at runtime such as shown in the example below. -The default rollover strategy supports three variations for incrementing -the counter. To illustrate how it works, suppose that the min attribute -is set to 1, the max attribute is set to 3, the file name is "foo.log", -and the file name pattern is "foo-%i.log". +The default rollover strategy supports three variations for incrementing the counter. +To illustrate how it works, suppose that the min attribute is set to 1, the max attribute is set to 3, the file name is "foo.log", and the file name pattern is "foo-%i.log". [cols="15%,15%,15%,55%",options="header",] |======================================================================= @@ -2749,9 +2639,7 @@ foo-1.log, foo-3.log is renamed to foo-2.log and foo.log is renamed to foo-3.log. A new foo.log file is created and starts being written to. |======================================================================= -By way of contrast, when the fileIndex attribute is set to "min" but all -the other settings are the same the "fixed window" strategy will be -performed. +By way of contrast, when the `fileIndex` attribute is set to "min" all the other settings are the same the "fixed window" strategy will be performed. [cols="15%,15%,15%,55%",options="header",] |======================================================================= @@ -2777,10 +2665,8 @@ foo-3.log, foo-1.log is renamed to foo-2.log and foo.log is renamed to foo-1.log. A new foo.log file is created and starts being written to. |======================================================================= -Finally, as of release 2.8, if the fileIndex attribute is set to "nomax" -then the min and max values will be ignored and file numbering will -increment by 1 and each rollover will have an incrementally higher value -with no maximum number of files. +Finally, as of release 2.8, if the `fileIndex` attribute is set to `nomax` +then the min and max values will be ignored and file numbering will increment by 1 and each rollover will have an incrementally higher value with no maximum number of files. .DefaultRolloverStrategy Parameters [cols="20%,20%,60%",options="header",] @@ -2793,7 +2679,7 @@ described above. |min |integer |The minimum value of the counter. The default value is 1. -|max |integer |The maximum value of the counter. Once this values is +|max |integer |The maximum value of the counter. Once this value is reached older archives will be deleted on subsequent rollovers. The default value is 7. @@ -2810,25 +2696,19 @@ archived log file during compression. DirectWrite Rollover Strategy -The DirectWriteRolloverStrategy causes log events to be written directly -to files represented by the file pattern. With this strategy file -renames are not performed. If the size-based triggering policy causes -multiple files to be written during the specified time period they will -be numbered starting at one and continually incremented until a -time-based rollover occurs. +The DirectWriteRolloverStrategy causes log events to be written directly to files represented by the file pattern. +With this strategy file renames are not performed. +If the size-based triggering policy causes multiple files to be written during the specified period they will be numbered starting at one and continually incremented until a time-based rollover occurs. -Warning: If the file pattern has a suffix indicating compression should -take place the current file will not be compressed when the application -is shut down. Furthermore, if the time changes such that the file -pattern no longer matches the current file it will not be compressed at -startup either. +Warning: If the file pattern has a suffix indicating compression should take place the current file will not be compressed when the application is shut down. +Furthermore, if the time changes such that the file pattern no longer matches the current file it will not be compressed at startup either. .DirectWriteRolloverStrategy Parameters [cols="20%,20%,60%",options="header",] |======================================================================= |Parameter Name |Type |Description -|maxFiles |String |The maximum number of files to allow in the time -period matching the file pattern. If the number of files is exceeded the +|maxFiles |String |The maximum number of files to allow in the period matching +the file pattern. If the number of files is exceeded the oldest file will be deleted. If specified, the value must be greater than 1. If the value is less than zero or omitted then the number of files will not be limited. @@ -2841,10 +2721,7 @@ ZIP files. archived log file during compression. |======================================================================= -Below is a sample configuration that uses a RollingFileAppender with -both the time and size based triggering policies, will create up to 7 -archives on the same day (1-7) that are stored in a directory based on -the current year and month, and will compress each archive using gzip: +Below is a sample configuration that uses a RollingFileAppender with both the time and size-based triggering policies will create up to 7 archives on the same day (1-7) that are stored in a directory based on the current year and month, and will compress each archive using gzip: [source,xml] ---- @@ -2870,8 +2747,7 @@ the current year and month, and will compress each archive using gzip: ---- -This second example shows a rollover strategy that will keep up to 20 -files before removing them. +This second example shows a rollover strategy that will keep up to 20 files before removing them. [source,xml] ---- @@ -2898,11 +2774,7 @@ files before removing them. ---- -Below is a sample configuration that uses a RollingFileAppender with -both the time and size based triggering policies, will create up to 7 -archives on the same day (1-7) that are stored in a directory based on -the current year and month, and will compress each archive using gzip -and will roll every 6 hours when the hour is divisible by 6: +Below is a sample configuration that uses a RollingFileAppender with both the time and size-based triggering policies will create up to 7 archives on the same day (1-7) that are stored in a directory based on the current year and month, and will compress each archive using gzip and will roll every 6 hours when the hour is divisible by 6: [source,xml] ---- @@ -2928,10 +2800,8 @@ and will roll every 6 hours when the hour is divisible by 6: ---- -This sample configuration uses a RollingFileAppender with both the cron -and size based triggering policies, and writes directly to an unlimited -number of archive files. The cron trigger causes a rollover every hour -while the file size is limited to 250MB: +This sample configuration uses a RollingFileAppender with both the cron and size-based triggering policies, and writes directly to an unlimited number of archive files. +The cron trigger causes a rollover every hour while the file size is limited to 250MB: [source,xml] ---- @@ -2956,8 +2826,7 @@ while the file size is limited to 250MB: ---- -This sample configuration is the same as the previous but limits the -number of files saved each hour to 10: +This sample configuration is the same as the previous one but limits the number of files saved each hour to 10: [source,xml] ---- @@ -2988,16 +2857,11 @@ number of files saved each hour to 10: Log Archive Retention Policy: Delete on Rollover -Log4j-2.5 introduces a `Delete` action that gives users more control -over what files are deleted at rollover time than what was possible with -the DefaultRolloverStrategy `max` attribute. The Delete action lets -users configure one or more conditions that select the files to delete -relative to a base directory. +Log4j-2.5 introduces a `Delete` action that gives users more control over what files are deleted at rollover time than what was possible with the DefaultRolloverStrategy `max` attribute. +The Delete action lets users configure one or more conditions that select the files to delete relative to a base directory. -Note that it is possible to delete any file, not just rolled over log -files, so use this action with care! With the `testMode` parameter you -can test your configuration without accidentally deleting the wrong -files. +Note that it is possible to delete any file, not just rolled-over log files, so use this action with care! +With the `testMode` parameter you can test your configuration without accidentally deleting the wrong files. .Delete Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -3008,7 +2872,7 @@ for files to delete. |maxDepth |int |The maximum number of levels of directories to visit. A value of 0 means that only the starting file (the base path itself) is -visited, unless denied by the security manager. A value of +visited unless denied by the security manager. A value of Integer.MAX_VALUE indicates that all levels should be visited. The default is 1, meaning only the files in the specified base directory. @@ -3018,12 +2882,12 @@ false. |testMode |boolean |If true, files are not deleted but instead a message is printed to the xref:manual/configuration.adoc#StatusMessages[status logger] at INFO level. Use this to do a dry run to test if the configuration -works as expected. Default is false. +works as expected. The default is false. |pathSorter |PathSorter |A plugin implementing the link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/rolling/action/PathSorter.html[PathSorter] interface to sort the files before selecting the files to delete. The -default is to sort most recently modified files first. +default is to sort the most recently modified files first. |pathConditions [[DeletePathCondition]] |PathCondition[] a| _Required if no ScriptCondition is specified._ One or more PathCondition @@ -3054,7 +2918,7 @@ paths after the accumulated file size threshold is exceeded during the file tree walk. * IfAll - accepts a path if all nested conditions accept it (logical AND). Nested conditions may be evaluated in any order. -* IfAny - accepts a path if one of the nested conditions accept it +* IfAny - accepts a path if one of the nested conditions accepts it (logical OR). Nested conditions may be evaluated in any order. * IfNot - accepts a path if the nested condition does not accept it (logical NOT). @@ -3069,7 +2933,7 @@ executed. (See also the xref:manual/filters.adoc#Script[ScriptFilter] documentation for more examples of configuring ScriptFiles and ScriptRefs.) -The script is passed a number of link:#ScriptParameters[parameters], +The script is passed several link:#ScriptParameters[parameters], including a list of paths found under the base path (up to `maxDepth`) and must return a list with the paths to delete. @@ -3082,7 +2946,7 @@ and must return a list with the paths to delete. [cols="20%,20%,60%",options="header",] |======================================================================= |Parameter Name |Type |Description -|glob |String |_Required if regex not specified._ Matches the relative +|glob |String |_Required if regex is not specified._ Matches the relative path (relative to the base path) using a limited pattern language that resembles regular expressions but with a https://docs.oracle.com/javase/7/docs/api/java/nio/file/FileSystem.html#getPathMatcher(java.lang.String)[simpler @@ -3155,11 +3019,9 @@ conditions are only evaluated if the outer condition accepts a file (if the threshold accumulated file size has been exceeded). |======================================================================= -Below is a sample configuration that uses a RollingFileAppender with the -cron triggering policy configured to trigger every day at midnight. +Below is a sample configuration that uses a RollingFileAppender with the cron triggering policy configured to trigger every day at midnight. Archives are stored in a directory based on the current year and month. -All files under the base directory that match the "*/app-*.log.gz" glob -and are 60 days old or older are deleted at rollover time. +All files under the base directory that match the "*/app-*.log.gz" glob and are 60 days old or older are deleted at rollover time. [source,xml] ---- @@ -3189,14 +3051,8 @@ and are 60 days old or older are deleted at rollover time. ---- -Below is a sample configuration that uses a RollingFileAppender with -both the time and size based triggering policies, will create up to 100 -archives on the same day (1-100) that are stored in a directory based on -the current year and month, and will compress each archive using gzip -and will roll every hour. During every rollover, this configuration will -delete files that match "*/app-*.log.gz" and are 30 days old or older, -but keep the most recent 100 GB or the most recent 10 files, whichever -comes first. +Below is a sample configuration that uses a RollingFileAppender with both the time and size-based triggering policies will create up to 100 archives on the same day (1-100) that are stored in a directory based on the current year and month, and will compress each archive using gzip and will roll every hour. +During every rollover, this configuration will delete files that match "*/app-*.log.gz" and are 30 days old or older, but keep the most recent 100 GB or the most recent 10 files, whichever comes first. [source,xml] ---- @@ -3247,7 +3103,7 @@ comes first. |======================================================================= |Parameter Name |Type |Description |script |Script, ScriptFile or ScriptRef |The Script element that -specifies the logic to be executed. The script is passed a list of paths +specifies the logic to be executed. The script passes a list of paths found under the base path and must return the paths to delete as a `java.util.List`. See also the xref:manual/filters.adoc#Script[ScriptFilter] documentation for an example of @@ -3263,7 +3119,7 @@ how ScriptFiles and ScriptRefs can be configured. |Parameter Name |Type |Description |basePath |`java.nio.file.Path` |The directory from where the Delete action started scanning for files to delete. Can be used to relativize -the paths in the pathList. +the paths in the `pathList`. |pathList |`java.util.List` |The list of paths found under the base path up to the specified max depth, sorted most recently @@ -3281,12 +3137,10 @@ variables. |? |String |Any properties declared in the configuration. |======================================================================= -Below is a sample configuration that uses a RollingFileAppender with the -cron triggering policy configured to trigger every day at midnight. +Below is a sample configuration that uses a RollingFileAppender with the cron triggering policy configured to trigger every day at midnight. Archives are stored in a directory based on the current year and month. -The script returns a list of rolled over files under the base directory -dated Friday the 13th. The Delete action will delete all files returned -by the script. +The script returns a list of rolled-over files under the base directory dated Friday the 13th. +The Delete action will delete all files returned by the script. [source,xml] ---- @@ -3331,7 +3185,7 @@ by the script. } statusLogger.trace 'SCRIPT: returning ' + result; result; - ]] > + ]]> @@ -3349,13 +3203,10 @@ by the script. [#CustomPosixViewAttributeOnRollover] == CustomPosixViewAttributeOnRollover -Log Archive File Attribute View Policy: Custom file attribute on -Rollover +Log Archive File Attribute View Policy: Custom file attribute on Rollover -Log4j-2.9 introduces a `PosixViewAttribute` action that gives users more -control over which file attribute permissions, owner and group should be -applied. The PosixViewAttribute action lets users configure one or more -conditions that select the eligible files relative to a base directory. +Log4j-2.9 introduces a `PosixViewAttribute` action that gives users more control over which file attribute permissions, owner and group should be applied. +The PosixViewAttribute action lets users configure one or more conditions that select the eligible files relative to a base directory. .PosixViewAttribute Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -3366,7 +3217,7 @@ for files to apply attributes. |maxDepth |int |The maximum number of levels of directories to visit. A value of 0 means that only the starting file (the base path itself) is -visited, unless denied by the security manager. A value of +visited unless denied by the security manager. A value of Integer.MAX_VALUE indicates that all levels should be visited. The default is 1, meaning only the files in the specified base directory. @@ -3380,7 +3231,7 @@ link:#DeletePathCondition[DeletePathCondition] File attribute permissions in POSIX format to apply when action is executed. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -3389,29 +3240,27 @@ Examples: rw------- or rw-rw-rw- etc... |fileOwner |String a| File owner to define when action is executed. -Changing file's owner may be restricted for security reason and +Changing the file's owner may be restricted for security reasons and Operation not permitted IOException thrown. Only processes with an effective user ID equal to the user ID of the file or with appropriate privileges may change the ownership of a file if http://www.gnu.org/software/libc/manual/html_node/Options-for-Files.html[_POSIX_CHOWN_RESTRICTED] is in effect for path. -Underlying files system shall support file +The underlying files system shall support file https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/FileOwnerAttributeView.html[owner] attribute view. |fileGroup |String a| File group to define when action is executed. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. |======================================================================= -Below is a sample configuration that uses a RollingFileAppender and -defines different POSIX file attribute view for current and rolled log -files. +Below is a sample configuration that uses a RollingFileAppender and defines different POSIX file attribute views for current and rolled log files. [source,xml] ---- @@ -3447,32 +3296,24 @@ files. == RollingRandomAccessFileAppender The RollingRandomAccessFileAppender is similar to the standard -link:#RollingFileAppender[RollingFileAppender] except it is always -buffered (this cannot be switched off) and internally it uses a -`ByteBuffer + RandomAccessFile` instead of a `BufferedOutputStream`. We -saw a 20-200% performance improvement compared to RollingFileAppender -with "bufferedIO=true" in our -xref:manual/performance.adoc#whichAppender[measurements]. The -RollingRandomAccessFileAppender writes to the File named in the fileName -parameter and rolls the file over according the TriggeringPolicy and the -RolloverPolicy. Similar to the RollingFileAppender, -RollingRandomAccessFileAppender uses a RollingRandomAccessFileManager to -actually perform the file I/O and perform the rollover. While -RollingRandomAccessFileAppender from different Configurations cannot be -shared, the RollingRandomAccessFileManagers can be if the Manager is -accessible. For example, two web applications in a servlet container can -have their own configuration and safely write to the same file if Log4j -is in a ClassLoader that is common to both of them. +link:#RollingFileAppender[RollingFileAppender] except it is always buffered (this cannot be switched off) and internally it uses a +`ByteBuffer + RandomAccessFile` instead of a `BufferedOutputStream`. +We saw a 20-200% performance improvement compared to RollingFileAppender with "bufferedIO=true" in our +xref:manual/performance.adoc#whichAppender[measurements]. +The +`RollingRandomAccessFileAppender` writes to the file named in the fileName parameter and rolls the file over according to the TriggeringPolicy and the RolloverPolicy. +Similar to the RollingFileAppender, RollingRandomAccessFileAppender uses a RollingRandomAccessFileManager to perform the file I/O and perform the rollover. +While RollingRandomAccessFileAppender from different Configurations cannot be shared, the RollingRandomAccessFileManagers can be if the Manager is accessible. +For example, two web applications in a servlet container can have their configuration and safely write to the same file if Log4j is in a ClassLoader that is common to both of them. A RollingRandomAccessFileAppender requires a link:#TriggeringPolicies[TriggeringPolicy] and a -link:#RolloverStrategies[RolloverStrategy]. The triggering policy -determines if a rollover should be performed while the RolloverStrategy -defines how the rollover should be done. If no RolloverStrategy is -configured, RollingRandomAccessFileAppender will use the -link:#DefaultRolloverStrategy[DefaultRolloverStrategy]. Since log4j-2.5, -a link:#CustomDeleteOnRollover[custom delete action] can be configured -in the DefaultRolloverStrategy to run at rollover. +link:#RolloverStrategies[RolloverStrategy]. +The triggering policy determines if a rollover should be performed while the `RolloverStrategy` +defines how the rollover should be done. +If no RolloverStrategy is configured, RollingRandomAccessFileAppender will use the +link:#DefaultRolloverStrategy[DefaultRolloverStrategy]. +Since log4j-2.5, a link:#CustomDeleteOnRollover[custom delete action] can be configured in the DefaultRolloverStrategy to run at rollover. File locking is not supported by the RollingRandomAccessFileAppender. @@ -3524,7 +3365,7 @@ is supplied the default pattern layout of "%m%n" will be used. should occur. |strategy |RolloverStrategy |The strategy to use to determine the name -and location of the archive file. +and the location of the archive file. |ignoreExceptions |boolean |The default is `true`, causing exceptions encountered while appending events to be internally logged and then @@ -3536,7 +3377,7 @@ Appender in a link:#FailoverAppender[FailoverAppender]. File attribute permissions in POSIX format to apply whenever the file is created. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -3545,21 +3386,21 @@ Examples: `rw-------` or `rw-rw-rw-` etc... |fileOwner |String a| File owner to define whenever the file is created. -Changing file's owner may be restricted for security reason and +Changing the file's owner may be restricted for security reasons and Operation not permitted IOException thrown. Only processes with an effective user ID equal to the user ID of the file or with appropriate privileges may change the ownership of a file if http://www.gnu.org/software/libc/manual/html_node/Options-for-Files.html[_POSIX_CHOWN_RESTRICTED] is in effect for path. -Underlying files system shall support file +The underlying file system shall support file https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/FileOwnerAttributeView.html[owner] attribute view. |fileGroup |String a| File group to define whenever the file is created. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -3573,11 +3414,7 @@ See xref:#TriggeringPolicies[RollingFileAppender Triggering Policies]. See link:#RolloverStrategies[RollingFileAppender Rollover Strategies]. -Below is a sample configuration that uses a -RollingRandomAccessFileAppender with both the time and size based -triggering policies, will create up to 7 archives on the same day (1-7) -that are stored in a directory based on the current year and month, and -will compress each archive using gzip: +Below is a sample configuration that uses a RollingRandomAccessFileAppender with both the time and size-based triggering policies will create up to 7 archives on the same day (1-7) that are stored in a directory based on the current year and month, and will compress each archive using gzip: [source,xml] ---- @@ -3603,8 +3440,7 @@ will compress each archive using gzip: ---- -This second example shows a rollover strategy that will keep up to 20 -files before removing them. +This second example shows a rollover strategy that will keep up to 20 files before removing them. [source,xml] ---- @@ -3631,12 +3467,7 @@ files before removing them. ---- -Below is a sample configuration that uses a -RollingRandomAccessFileAppender with both the time and size based -triggering policies, will create up to 7 archives on the same day (1-7) -that are stored in a directory based on the current year and month, and -will compress each archive using gzip and will roll every 6 hours when -the hour is divisible by 6: +Below is a sample configuration that uses a RollingRandomAccessFileAppender with both the time and size-based triggering policies will create up to 7 archives on the same day (1-7) that are stored in a directory based on the current year and month, and will compress each archive using gzip and will roll every 6 hours when the hour is divisible by 6: [source,xml] ---- @@ -3665,15 +3496,11 @@ the hour is divisible by 6: [#RoutingAppender] == RoutingAppender -The RoutingAppender evaluates LogEvents and then routes them to a -subordinate Appender. The target Appender may be an appender previously -configured and may be referenced by its name or the Appender can be -dynamically created as needed. The RoutingAppender should be configured -after any Appenders it references to allow it to shut down properly. +The `RoutingAppender` evaluates LogEvents and then routes them to a subordinate Appender. +The target Appender may be an appender previously configured and may be referenced by its name or the Appender can be dynamically created as needed. +The `RoutingAppender` should be configured after any Appenders it references to allow it to shut down properly. -You can also configure a RoutingAppender with scripts: you can run a -script when the appender starts and when a route is chosen for an log -event. +You can also configure a `RoutingAppender` with scripts: you can run a script when the appender starts and when a route is chosen for an log event. .RoutingAppender Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -3700,12 +3527,12 @@ This script is passed the following variables: .RoutingAppender Script Parameters [cols="20%,20%,60%",options="header",] |======================================================================= -|Parameter Name |Type |Description -|configuration |Configuration |The active Configuration. -|staticVariables |Map |A Map shared between all script invocations for -this appender instance. This is the same map passed to the Routes -Script. +|Parameter Name |Type |Description |configuration |Configuration |The active Configuration. + +|staticVariables |Map |A Map shared between all script invocations for this appender instance. +This is the same map passed to the Routes Script. + |======================================================================= |ignoreExceptions |boolean |The default is `true`, causing exceptions @@ -3715,10 +3542,8 @@ caller, instead. You must set this to `false` when wrapping this Appender in a link:#FailoverAppender[FailoverAppender]. |======================================================================= -In this example, the script causes the "ServiceWindows" route to be the -default route on Windows and "ServiceOther" on all other operating -systems. Note that the List Appender is one of our test appenders, any -appender can be used, it is only used as a shorthand. +In this example, the script causes the "ServiceWindows" route to be the default route on Windows and "ServiceOther" on all other operating systems. +Note that the List Appender is one of our test appenders, any appender can be used, it is only used as a shorthand. [source,xml] ---- @@ -3750,26 +3575,24 @@ appender can be used, it is only used as a shorthand. [#Routes] === Routes -The Routes element accepts a single attribute named "pattern". The -pattern is evaluated against all the registered Lookups and the result -is used to select a Route. Each Route may be configured with a key. If -the key matches the result of evaluating the pattern then that Route -will be selected. If no key is specified on a Route then that Route is -the default. Only one Route can be configured as the default. +The `Routes` element accepts a single attribute named "pattern". +The pattern is evaluated against all the registered Lookups and the result is used to select a `Route`. +Each `Route` may be configured with a key. +If the key matches the result of evaluating the pattern then that `Route` +will be selected. +If no key is specified on a `Route` then that `Route` is the default. +Only one `Route` can be configured as the default. -The Routes element may contain a Script child element. If specified, the -Script is run for each log event and returns the String Route key to -use. +The `Routes` element may contain a `Script` child element. +If specified, the +`Script` is run for each log event and returns the String Route key to use. -You must specify either the pattern attribute or the Script element, but -not both. +You must specify either the pattern attribute or the `Script` element, but not both. -Each Route must reference an Appender. If the Route contains a ref -attribute then the Route will reference an Appender that was defined in -the configuration. If the Route contains an Appender definition then an -Appender will be created within the context of the RoutingAppender and -will be reused each time a matching Appender name is referenced through -a Route. +Each `Route` must reference an `Appender`. +If the `Route` contains a ref attribute then the `Route` will reference an `Appender` that was defined in the configuration. +If the `Route` contains an `Appender` definition then an +`Appender` will be created within the context of the `RoutingAppender` and will be reused each time a matching `Appender` name is referenced through a `Route`. This script is passed the following variables: @@ -3786,8 +3609,7 @@ Script. |logEvent |LogEvent |The log event. |======================================================================= -In this example, the script runs for each log event and picks a route -based on the presence of a Marker named "AUDIT". +In this example, the script runs for each log event and picks a route based on the presence of a Marker named "AUDIT". [source,xml] ---- @@ -3838,21 +3660,12 @@ based on the presence of a Marker named "AUDIT". [#Purge] === Purge Policy -The RoutingAppender can be configured with a PurgePolicy whose purpose -is to stop and remove dormant Appenders that have been dynamically -created by the RoutingAppender. Log4j currently provides the -IdlePurgePolicy as the only PurgePolicy available for cleaning up the -Appenders. The IdlePurgePolicy accepts 2 attributes; timeToLive, which -is the number of timeUnits the Appender should survive without having -any events sent to it, and timeUnit, the String representation of -java.util.concurrent.TimeUnit which is used with the timeToLive -attribute. +The RoutingAppender can be configured with a PurgePolicy whose purpose is to stop and remove dormant Appenders that have been dynamically created by the RoutingAppender. +Log4j currently provides the IdlePurgePolicy is the only PurgePolicy available for cleaning up the Appenders. +The IdlePurgePolicy accepts 2 attributes; timeToLive, which is the number of timeUnits the Appender should survive without having any events sent to it, and timeUnit, the String representation of java.util.concurrent.TimeUnit which is used with the timeToLive attribute. -Below is a sample configuration that uses a RoutingAppender to route all -Audit events to a FlumeAppender and all other events will be routed to a -RollingFileAppender that captures only the specific event type. Note -that the AuditAppender was predefined while the RollingFileAppenders are -created as needed. +Below is a sample configuration that uses a RoutingAppender to route all Audit events to a FlumeAppender and all other events will be routed to a RollingFileAppender captures only the specific event type. +Note that the AuditAppender was predefined while the RollingFileAppenders are created as needed. [source,xml] ---- @@ -3893,9 +3706,15 @@ created as needed. Sends an e-mail when a specific logging event occurs, typically on errors or fatal errors. -The number of logging events delivered in this e-mail depend on the value of *BufferSize* option. The `SMTPAppender` keeps only the last `BufferSize` logging events in its cyclic buffer. This keeps memory requirements at a reasonable level while still delivering useful application context. All events in the buffer are included in the email. The buffer will contain the most recent events of level TRACE to WARN preceding the event that triggered the email. +The number of logging events delivered in this e-mail depends on the value of the `BufferSize` option. +The `SMTPAppender` keeps only the last `BufferSize` logging events in its cyclic buffer. +This keeps memory requirements at a reasonable level while still delivering useful application context. +All events in the buffer are included in the email. +The buffer will contain the most recent events of level TRACE to WARN preceding the event that triggered the email. -The default behavior is to trigger sending an email whenever an ERROR or higher severity event is logged and to format it as HTML. The circumstances on when the email is sent can be controlled by setting one or more filters on the Appender. As with other Appenders, the formatting can be controlled by specifying a Layout for the Appender. +The default behavior is to trigger sending an email whenever an ERROR or higher severity event is logged and to format it as HTML. +The circumstances of when the email is sent can be controlled by setting one or more filters on the Appender. +As with other Appenders, the formatting can be controlled by specifying a Layout for the Appender. [width="100%",options="header"] |=== @@ -3943,7 +3762,7 @@ The default behavior is to trigger sending an email whenever an ERROR or higher |smtpDebug |boolean -|When set to true enables session debugging on STDOUT. Defaults to false. +|When set to true turns on the session debugging on STDOUT. Defaults to false. |smtpHost |String @@ -3991,22 +3810,19 @@ The default behavior is to trigger sending an email whenever an ERROR or higher ---- - [#ScriptAppenderSelector] == ScriptAppenderSelector -When the configuration is built, the `ScriptAppenderSelector` appender -calls a `ScriptPlugin` to compute an appender name. Log4j then creates one of -the appender named listed under `AppenderSet` using the name of the -`ScriptAppenderSelector`. After configuration, Log4j ignores the -`ScriptAppenderSelector`. Log4j only builds the one selected appender -from the configuration tree, and ignores other `AppenderSet` child -nodes. +When the configuration is built, the `ScriptAppenderSelector` appender calls a `ScriptPlugin` to compute an appender name. +Log4j then creates one of the appender named listed under `AppenderSet` using the name of the +`ScriptAppenderSelector`. +After configuration, Log4j ignores the +`ScriptAppenderSelector`. +Log4j only builds the one selected appender from the configuration tree and ignores other `AppenderSet` child nodes. -In the following example, the script returns the name "List2". The -appender name is recorded under the name of the -`ScriptAppenderSelector`, not the name of the selected appender, in this -example, "SelectIt". +In the following example, the script returns the name "List2". +The appender name is recorded under the name of the +`ScriptAppenderSelector`, not the name of the selected appender, in this example, "SelectIt". [source,xml] ---- @@ -4033,16 +3849,12 @@ example, "SelectIt". [#SocketAppender] == SocketAppender -The `SocketAppender` is an OutputStreamAppender that writes its output -to a remote destination specified by a host and port. The data can be -sent over either TCP or UDP and can be sent in any format. You can -optionally secure communication with link:#SSL[SSL]. Note that the TCP and SSL -variants write to the socket as a stream and do not expect response from -the target destination. Due to limitations in the TCP protocol that -means that when the target server closes its connection some log events -may continue to appear to succeed until a closed connection exception -is raised, causing those events to be lost. If guaranteed delivery is -required a protocol that requires acknowledgements must be used. +The `SocketAppender` is an OutputStreamAppender that writes its output to a remote destination specified by a host and port. +The data can be sent over either TCP or UDP and can be sent in any format. +You can optionally secure communication with link:#SSL[SSL]. +Note that the TCP and SSL variants write to the socket as a stream and do not expect a response from the target destination. +Due to limitations in the TCP protocol that means that when the target server closes its connection some log events may continue to appear to succeed until a closed connection exception is raised, causing those events to be lost. +If guaranteed delivery is required a protocol that requires acknowledgments must be used. .`SocketAppender` Parameters [cols="20%,20%,60%",options="header",] @@ -4054,7 +3866,7 @@ required a protocol that requires acknowledgements must be used. log events. This parameter is required. |port |integer |The port on the host that is listening for log events. -This parameter must be specified.If the host name resolves to multiple +This parameter must be specified. If the hostname resolves to multiple IP addresses the TCP and SSL variations will fail over to the next IP address when a connection is lost. @@ -4077,23 +3889,23 @@ disk but could impact performance. |bufferedIO |boolean |When true - the default, events are written to a buffer and the data will be written to the socket when the buffer is -full or, if immediateFlush is set, when the record is written. +full or, if immediateFlush is set when the record is written. |bufferSize |int |When bufferedIO is true, this is the buffer size, the default is 8192 bytes. |layout |Layout |The Layout to use to format the LogEvent. Required, there is no default. _New since 2.9, in previous versions -SerializedLayout was default._ +SerializedLayout was the default._ |reconnectionDelayMillis |integer |If set to a value greater than 0, -after an error the SocketManager will attempt to reconnect to the server -after waiting the specified number of milliseconds. If the reconnect +after an error, the SocketManager will attempt to reconnect to the server +after waiting for the specified number of milliseconds. If the reconnect fails then an exception will be thrown (which can be caught by the application if `ignoreExceptions` is set to `false`). |connectTimeoutMillis |integer |The connect timeout in milliseconds. The -default is 0 (infinite timeout, like Socket.connect() methods). +default is 0 (infinite timeout, like `Socket.connect()` methods). |ignoreExceptions |boolean |The default is `true`, causing exceptions encountered while appending events to be internally logged and then @@ -4131,8 +3943,8 @@ This is a secured link:#SSL[SSL] configuration: - - + + @@ -4147,16 +3959,15 @@ This is a secured link:#SSL[SSL] configuration: [#SSL] == SSL -Several appenders can be configured to use either a plain network -connection or a Secure Socket Layer (SSL) connection. This section -documents the parameters available for SSL configuration. +Several appenders can be configured to use either a plain network connection or a Secure Socket Layer (SSL) connection. +This section documents the parameters available for SSL configuration. .SSL Configuration Parameters [cols="20%,20%,60%",options="header",] |======================================================================= |Parameter Name |Type |Description |protocol |String |The SSL protocol to use, `TLS` if omitted. A single value -may enable multiple protocoles, see the +may enable multiple protocols, see the https://docs.oracle.com/en/java/javase/11/docs/specs/security/standard-names.html#sslcontext-algorithms[JVM documentation] for details. @@ -4171,8 +3982,7 @@ counterparty. Determines whether the remote authentication credentials [#KeyStore] === KeyStore -The keystore is meant to contain your private keys and certificates, and -determines which authentication credentials to send to the remote host. +The Keystore is meant to contain your private keys and certificates, and determines which authentication credentials to send to the remote host. .KeyStore Configuration Parameters [cols="20%,20%,60%",options="header",] @@ -4205,14 +4015,10 @@ algorithms]. [#TrustStore] === TrustStore -The trust store is meant to contain the CA certificates you are willing -to trust when a remote party presents its certificate. Determines -whether the remote authentication credentials (and thus the connection) -should be trusted. +The trust store is meant to contain the CA certificates you are willing to trust when a remote party presents its certificate. +Determines whether the remote authentication credentials (and thus the connection) should be trusted. -In some cases, they can be one and the same store, although it is often -better practice to use distinct stores (especially when they are -file-based). +In some cases, they can be the same store, although it is often better practice to use distinct stores (especially when they are file-based). .TrustStore Configuration Parameters [cols="20%,20%,60%",options="header",] @@ -4256,10 +4062,8 @@ algorithms]. [#SyslogAppender] == SyslogAppender -The `SyslogAppender` is a `SocketAppender` that writes its output to a -remote destination specified by a host and port in a format that -conforms with either the BSD Syslog format or the RFC 5424 format. The -data can be sent over either TCP or UDP. +The `SyslogAppender` is a `SocketAppender` that writes its output to a remote destination specified by a host and port in a format that conforms with either the BSD Syslog format or the RFC 5424 format. +The data can be sent over either TCP or UDP. .`SyslogAppender` Parameters [cols="20%,20%,60%",options="header",] @@ -4271,13 +4075,13 @@ advertised. |appName |String |The value to use as the APP-NAME in the RFC 5424 syslog record. -|charset |String |The character set to use when converting the syslog +|charset |String |The character set to use when converting the Syslog String to a byte array. The String must be a valid https://download.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html[`Charset`]. If not specified, the default system Charset will be used. |connectTimeoutMillis |integer |The connect timeout in milliseconds. The -default is 0 (infinite timeout, like Socket.connect() methods). +default is 0 (infinite timeout, like `Socket.connect()` methods). |enterpriseNumber |integer |The IANA enterprise number as described in http://tools.ietf.org/html/rfc5424#section-7.2.2[RFC 5424] @@ -4291,20 +4095,19 @@ The facility option must be set to one of "KERN", "USER", "MAIL", "DAEMON", "AUTH", "SYSLOG", "LPR", "NEWS", "UUCP", "CRON", "AUTHPRIV", "FTP", "NTP", "AUDIT", "ALERT", "CLOCK", "LOCAL0", "LOCAL1", "LOCAL2", "LOCAL3", "LOCAL4", "LOCAL5", "LOCAL6", or "LOCAL7". These values may be -specified as upper or lower case characters. +specified as upper or lowercase characters. -|format |String |If set to "RFC5424" the data will be formatted in -accordance with RFC 5424. Otherwise, it will be formatted as a BSD +|format |String |If set to "RFC5424" the data will be formatted by RFC 5424. +Otherwise, it will be formatted as a BSD Syslog record. Note that although BSD Syslog records are required to be 1024 bytes or shorter the SyslogLayout does not truncate them. The RFC5424Layout also does not truncate records since the receiver must -accept records of up to 2048 bytes and may accept records that are -longer. +accept records of up to 2048 bytes and may accept longer records. |host |String |The name or address of the system that is listening for log events. This parameter is required. -|id |String |The default structured data id to use when formatting +|id |String |The default structured data-id to use when formatting according to RFC 5424. If the LogEvent contains a StructuredDataMessage the id from the Message will be used instead of this value. @@ -4325,33 +4128,33 @@ disk but could impact performance. |includeMDC |boolean |Indicates whether data from the ThreadContextMap will be included in the RFC 5424 Syslog record. Defaults to true. -|Layout |Layout |A custom layout which overrides the `format` setting. +|Layout |Layout |A custom layout that overrides the `format` setting. |loggerFields |List of KeyValuePairs |Allows arbitrary PatternLayout patterns to be included as specified ThreadContext fields; no default -specified. To use, include a >LoggerFields< nested element, containing -one or more >KeyValuePair< elements. Each >KeyValuePair< must have a key -attribute, which specifies the key name which will be used to identify +specified. To use, include a `LoggerFields` nested element, containing +one or more `KeyValuePair` elements. Each `KeyValuePair` must have a key +attribute, which specifies the key name that will be used to identify the field within the MDC Structured Data element, and a value attribute, which specifies the PatternLayout pattern to use as the value. -|mdcExcludes |String |A comma separated list of mdc keys that should be +|mdcExcludes |String |A comma-separated list of mdc keys that should be excluded from the LogEvent. This is mutually exclusive with the mdcIncludes attribute. This attribute only applies to RFC 5424 syslog records. -|mdcIncludes |String |A comma separated list of mdc keys that should be +|mdcIncludes |String |A comma-separated list of mdc keys that should be included in the FlumeEvent. Any keys in the MDC not found in the list will be excluded. This option is mutually exclusive with the mdcExcludes attribute. This attribute only applies to RFC 5424 syslog records. -|mdcRequired |String |A comma separated list of mdc keys that must be +|mdcRequired |String |A comma-separated list of `mdc` keys that must be present in the MDC. If a key is not present a LoggingException will be thrown. This attribute only applies to RFC 5424 syslog records. -|mdcPrefix |String |A string that should be prepended to each MDC key in -order to distinguish it from event attributes. The default string is -"mdc:". This attribute only applies to RFC 5424 syslog records. +|mdcPrefix |String |A string that should be prepended to each MDC key +to distinguish it from event attributes. The default string is +`mdc:`. This attribute only applies to RFC 5424 syslog records. |messageId |String |The default value to be used in the MSGID field of RFC 5424 syslog records. @@ -4370,14 +4173,13 @@ This parameter must be specified. TrustStore. See link:#SSL[SSL]. |reconnectionDelayMillis |integer |If set to a value greater than 0, -after an error the SocketManager will attempt to reconnect to the server -after waiting the specified number of milliseconds. If the reconnect +after an error, the SocketManager will attempt to reconnect to the server +after waiting for the specified number of milliseconds. If the reconnect fails then an exception will be thrown (which can be caught by the application if `ignoreExceptions` is set to `false`). |======================================================================= -A sample syslogAppender configuration that is configured with two -`SyslogAppender`s, one using the BSD format and one using RFC 5424. +A sample syslogAppender configuration that is configured with two `SyslogAppender`s, one using the BSD format and one using RFC 5424. [source,xml] ---- @@ -4401,9 +4203,7 @@ A sample syslogAppender configuration that is configured with two ---- -For link:#SSL[SSL] this appender writes its output to a remote -destination specified by a host and port over SSL in a format that -conforms with either the BSD Syslog format or the RFC 5424 format. +For link:#SSL[SSL] this appender writes its output to a remote destination specified by a host and port over SSL in a format that conforms with either the BSD Syslog format or the RFC 5424 format. [source,xml] ---- @@ -4450,7 +4250,8 @@ This is a simple JeroMQ configuration: ---- -The table below describes all options. Please consult the JeroMQ and ZeroMQ documentation for details. +The table below describes all options. +Please consult the JeroMQ and ZeroMQ documentation for details. [width="100%",options="header"] |=== diff --git a/src/site/antora/modules/ROOT/pages/manual/architecture.adoc b/src/site/antora/modules/ROOT/pages/manual/architecture.adoc index 02b4d24c97d..622b193943c 100644 --- a/src/site/antora/modules/ROOT/pages/manual/architecture.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/architecture.adoc @@ -30,12 +30,13 @@ created it will be associated with the LoggerConfig that contains either a) the same name as the Logger, b) the name of a parent package, or c) the root LoggerConfig. LoggerConfig objects are created from Logger declarations in the configuration. The LoggerConfig is associated with -the Appenders that actually deliver the LogEvents. +the Appenders that deliver the LogEvents. +[id=logger-hierarchy] === Logger Hierarchy The first and foremost advantage of any logging API over plain -`System.out.println` resides in its ability to disable certain log +`System.out.println()` resides in its ability to disable certain log statements while allowing others to print unhindered. This capability assumes that the logging space, that is, the space of all possible logging statements, is categorized according to some developer-chosen @@ -98,8 +99,8 @@ xref:manual/logsep.adoc[Log Separation] section. Every LoggerContext has an active link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration.html[`Configuration`]. The Configuration contains all the Appenders, context-wide Filters, -LoggerConfigs and contains the reference to the StrSubstitutor. During -reconfiguration two Configuration objects will exist. Once all Loggers +LoggerConfigs and contains the reference to the StrSubstitutor. +During reconfiguration, two Configuration objects will exist. Once all Loggers have been redirected to the new Configuration, the old Configuration will be stopped and discarded. @@ -117,7 +118,7 @@ causing their behavior to be modified. Retrieving Loggers Calling the `LogManager.getLogger` method with the same name will always -return a reference to the exact same Logger object. +return a reference to the same Logger object. For example, in @@ -151,6 +152,7 @@ Logger name. Nevertheless, naming loggers after the class where they are located seems to be the best strategy known so far. +[#loggerconfig] === LoggerConfig link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/LoggerConfig.html[`LoggerConfig`] @@ -229,7 +231,7 @@ In example 3, the loggers`root`, `X` and `X.Y.Z` each have a configured LoggerConfig with the same name. The Logger `X.Y` does not have a configured LoggerConfig with a matching name so uses the configuration of LoggerConfig `X` since that is the LoggerConfig whose name has the -longest match to the start of the Logger's name. +the longest match to the start of the Logger's name. .Example 4 [cols=",,,",options="header",] @@ -244,7 +246,7 @@ longest match to the start of the Logger's name. In example 4, the loggers `root` and `X` each have a Configured LoggerConfig with the same name. The loggers `X.Y` and `X.Y.Z` do not have configured LoggerConfigs and so get their Level from the -LoggerConfig assigned to them,`X`, since it is the LoggerConfig whose +LoggerConfig assigned to them, `X`, since it is the LoggerConfig whose name has the longest match to the start of the Logger's name. .Example 5 @@ -257,10 +259,10 @@ name has the longest match to the start of the Logger's name. |X.YZ |X |ERROR |ERROR |============================================================= -In example 5, the loggers`root`.`X`, and `X.Y` each have a Configured +In example 5, the loggers `root`.`X`, and `X.Y` each has a configured LoggerConfig with the same name. The logger `X.YZ` does not have configured LoggerConfig and so gets its Level from the LoggerConfig -assigned to it,`X`, since it is the LoggerConfig whose name has the +assigned to it, `X`, since it is the LoggerConfig whose name has the longest match to the start of the Logger's name. It is not associated with LoggerConfig `X.Y` since tokens after periods must match exactly. @@ -274,13 +276,13 @@ with LoggerConfig `X.Y` since tokens after periods must match exactly. |X.Y.Z |X.Y | |ERROR |=== -In example 6, LoggerConfig X.Y it has no configured level so it inherits +In example 6, LoggerConfig X.Y has no configured level so it inherits its level from LoggerConfig X. Logger X.Y.Z uses LoggerConfig X.Y since it doesn't have a LoggerConfig with a name that exactly matches. It too inherits its logging level from LoggerConfig X. -The table below illustrates how Level filtering works. In the table, the -vertical header shows the Level of the LogEvent, while the horizontal +The table below illustrates how Level filtering works. In the table, +the vertical header shows the Level of the LogEvent, while the horizontal header shows the Level associated with the appropriate LoggerConfig. The intersection identifies whether the LogEvent would be allowed to pass for further processing (Yes) or discarded (No). @@ -347,7 +349,7 @@ be attached to a Logger. An Appender can be added to a Logger by calling the link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration.html#addLoggerAppender(org.apache.logging.log4j.core.Logger,%20org.apache.logging.log4j.core.Appender)[`addLoggerAppender`] method of the current Configuration. If a LoggerConfig matching the name -of the Logger does not exist, one will be created, the Appender will be +of the Logger does not exist, one will be created, and the Appender will be attached to it and then all Loggers will be notified to update their LoggerConfig references. @@ -433,7 +435,7 @@ sending the formatted output to its destination. The link:../javadoc/log4j-core/org/apache/logging/log4j/core/layout/PatternLayout.html[`PatternLayout`], part of the standard log4j distribution, lets the user specify the output format according to conversion patterns similar to the C language -`printf` function. +`printf()` function. For example, the PatternLayout with the conversion pattern "%r [%t] %-5p %c - %m%n" will output something akin to: @@ -454,7 +456,7 @@ use cases such as JSON, XML, HTML, and Syslog (including the new RFC specified fields instead of a particular textual layout. Just as importantly, log4j will render the content of the log message -according to user specified criteria. For example, if you frequently +according to user-specified criteria. For example, if you frequently need to log `Oranges`, an object type used in your current project, then you can create an OrangeMessage that accepts an Orange instance and pass that to Log4j so that the Orange object can be formatted into an @@ -466,16 +468,16 @@ The link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrSubstitutor.html[`StrSubstitutor`] class and link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html[`StrLookup`] -interface were borrowed from +interface was borrowed from https://commons.apache.org/proper/commons-lang/[Apache Commons Lang] and then modified to support evaluating LogEvents. In addition the link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/Interpolator.html[`Interpolator`] class was borrowed from Apache Commons Configuration to allow the -StrSubstitutor to evaluate variables that from multiple StrLookups. It +StrSubstitutor to evaluate variables from multiple StrLookups. It too was modified to support evaluating LogEvents. Together these provide a mechanism to allow the configuration to reference variables coming from System Properties, the configuration file, the ThreadContext Map, StructuredData in the LogEvent. The variables can either be resolved -when the configuration is processed or as each event is processed, if +when the configuration is processed or as each event is processed if the component is capable of handling it. See xref:manual/lookups.adoc[Lookups] for more information. diff --git a/src/site/antora/modules/ROOT/pages/manual/async.adoc b/src/site/antora/modules/ROOT/pages/manual/async.adoc index a727e64fb5e..0f576da2671 100644 --- a/src/site/antora/modules/ROOT/pages/manual/async.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/async.adoc @@ -18,11 +18,11 @@ Remko Popma Asynchronous logging can improve your application's performance by -executing the I/O operations in a separate thread. Log4j 2 makes a -number of improvements in this area. +executing the I/O operations in a separate thread. +Log4j 2 makes several improvements in this area. -* *Asynchronous Loggers* are a new addition in Log4j 2. Their aim is to -return from the call to Logger.log to the application as soon as +* *Asynchronous Loggers* are a new addition in Log4j 2. They aim to +return the call to Logger.log to the application as soon as possible. You can choose between making all Loggers asynchronous or using a mixture of synchronous and asynchronous Loggers. Making all Loggers asynchronous will give the best performance, while mixing gives @@ -35,8 +35,8 @@ latency. been enhanced to flush to disk at the end of a batch (when the queue is empty). This produces the same result as configuring "immediateFlush=true", that is, all received log events are always -available on disk, but is more efficient because it does not need to -touch the disk on each and every log event. (Async Appenders use +available on disk but are more efficient because it does not need to +touch the disk on every log event. (Async Appenders use ArrayBlockingQueue internally and do not need the disruptor jar on the classpath.) @@ -58,7 +58,7 @@ to log bursts of messages. Async logging can help prevent or dampen latency spikes by shortening the wait time until the next message can be logged. If the queue size is configured large enough to handle the burst, asynchronous logging will help prevent your application from -falling behind (as much) during a sudden increase of activity. +falling behind (as much) during a sudden increase in activity. * Lower logging response time link:#Latency[latency]. Response time latency is the time it takes for a call to Logger.log to return under a given workload. Asynchronous Loggers have consistently lower latency @@ -71,8 +71,8 @@ exception is thrown, it is less easy for an asynchronous logger or appender to signal this problem to the application. This can partly be alleviated by configuring an `ExceptionHandler`, but this may still not cover all cases. For this reason, if logging is part of your business -logic, for example if you are using Log4j as an audit logging framework, -we would recommend to synchronously log those audit messages. (Note that +logic, for example, if you are using Log4j as an audit logging framework, +we would recommend synchronously logging those audit messages. (Note that you can still link:#MixedSync-Async[combine] them and use asynchronous logging for debug/trace logging in addition to synchronous logging for the audit trail.) @@ -85,7 +85,7 @@ modified later. It is safe to asynchronously log mutable objects because most link:../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html[`Message`] implementations built-in to Log4j take a snapshot of the parameters. -There are some exceptions however: +There are some exceptions, however: link:../javadoc/log4j-api/org/apache/logging/log4j/message/MapMessage.html[`MapMessage`] and link:../javadoc/log4j-api/org/apache/logging/log4j/message/StructuredDataMessage.html[`StructuredDataMessage`] @@ -98,6 +98,7 @@ link:../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html[`Message implementations should be designed with asynchronous use in mind, and either take a snapshot of their parameters at construction time, or document their thread-safety characteristics. + * If your application is running in an environment where CPU resources are scarce, like a machine with one CPU with a single core, starting another thread is not likely to give better performance. @@ -105,7 +106,7 @@ another thread is not likely to give better performance. is faster than the maximum sustained throughput of the underlying appender, the queue will fill up and the application will end up logging at the speed of the slowest appender. If this happens, consider -selecting a xref:manual/performance.adoc#whichAppender[faster appender], or +selecting an xref:manual/performance.adoc#whichAppender[faster appender], or logging less. If neither of these is an option, you may get better throughput and fewer latency spikes by logging synchronously. @@ -116,8 +117,8 @@ NOTE: _Log4j-2.9 and higher require disruptor-3.3.4.jar or higher on the classpath. Prior to Log4j-2.9, disruptor-3.0.0.jar or higher was required._ -This is simplest to configure and gives the best performance. -To make all loggers asynchronous, add the disruptor jar to the classpath and set the system property xref:manual/configuration.adoc#log4j2.contextSelector[log4j2.contextSelector] to `org.apache.logging.log4j.core.async.AsyncLoggerContextSelector` or `org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector`. +This is the simplest to configure and gives the best performance. +To make all loggers asynchronous, add the disruptor jar to the classpath and set the system property xref:manual/systemproperties.adoc#log4j2.contextSelector[log4j2.contextSelector] to `org.apache.logging.log4j.core.async.AsyncLoggerContextSelector` or `org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector`. By default, link:#Location[location] is not passed to the I/O thread by asynchronous loggers. If one of your layouts or custom filters needs @@ -183,24 +184,24 @@ There are also a few system properties that can be used to maintain application throughput even when the underlying appender cannot keep up with the logging rate and the queue is filling up. See the details for system properties -xref:manual/configuration.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy` +xref:manual/systemproperties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy` and `log4j2.discardThreshold`]. [#MixedSync-Async] == Mixing Synchronous and Asynchronous Loggers NOTE: _Log4j-2.9 and higher require disruptor-3.3.4.jar or higher on the -classpath. Prior to Log4j-2.9, disruptor-3.0.0.jar or higher was -required. There is no need to set system property "Log4jContextSelector" +classpath. Before Log4j-2.9, disruptor-3.0.0.jar or higher was +required. There is no need to set the system property "Log4jContextSelector" to any value._ Synchronous and asynchronous loggers can be combined in configuration. This gives you more flexibility at the cost of a slight loss in performance (compared to making all loggers asynchronous). Use the -`` or `` configuration elements to specify the +`` or `` configuration elements specify the loggers that need to be asynchronous. A configuration can contain only one root logger (either a `` or an `` element), but -otherwise async and non-async loggers may be combined. For example, a +otherwise, async and non-async loggers may be combined. For example, a configuration file containing `` elements can also contain `` and `` elements for the synchronous loggers. @@ -257,7 +258,7 @@ There are also a few system properties that can be used to maintain application throughput even when the underlying appender cannot keep up with the logging rate and the queue is filling up. See the details for system properties -xref:manual/configuration.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy` +xref:manual/systemproperties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy` and `log4j2.discardThreshold`]. [#custom-waitstrategy] @@ -308,7 +309,7 @@ public interface AsyncWaitStrategyFactory { The specified class must also have a public no-argument constructor; Log4j will instantiate an instance of the specified factory class and use this factory to create the WaitStrategy used by all Async Loggers. -WaitStrategy-related system properties are ignored if a `AsyncWaitStrategyFactory` is configured. +WaitStrategy-related system properties are ignored if an `AsyncWaitStrategyFactory` is configured. [#Location] @@ -338,7 +339,7 @@ logging with location is 30-100 times slower than without location. For this reason, asynchronous loggers and asynchronous appenders do not include location information by default. -You can override the default behaviour in your logger or asynchronous +You can override the default behavior in your logger or asynchronous appender configuration by specifying `includeLocation="true"`. [#Performance] @@ -378,10 +379,10 @@ higher throughput than sync loggers.] === Asynchronous Throughput Comparison with Other Logging Packages -We also compared peak throughput of asynchronous loggers to the +We also compared the peak throughput of asynchronous loggers to the synchronous loggers and asynchronous appenders available in other logging packages, specifically log4j-1.2.17 and logback-1.0.10, with -similar results. For asynchronous appenders, total logging throughput of +similar results. For asynchronous appenders, the total logging throughput of all threads together remains roughly constant when adding more threads. Asynchronous loggers make more effective use of the multiple cores available on the machine in multi-threaded scenarios. @@ -457,14 +458,13 @@ threads This section has been rewritten with the Log4j 2.6 release. The previous version only reported _service time_ instead of _response -time_. See the xref:manual/performance.adoc#responseTime[response time] side -bar on the performance page on why this is too optimistic. Furthermore -the previous version reported average latency, which does not make sense +time_. See the xref:manual/performance.adoc#responseTime[response time] sidebar on the performance page on why this is too optimistic. +Furthermore, the previous version reported average latency, which does not make sense since latency is not a normal distribution. Finally, the previous version of this section only reported the maximum latency of up to 99.99% of the measurements, which does not tell you how bad the worst 0.01% were. This is unfortunate because often the "outliers" are all -that matter when it comes to response time. From this release we will +that matter when it comes to response time. From this release, we will try to do better and report response time latency across the full range of percentages, including all the outliers. Our thanks to Gil Tene for his http://www.infoq.com/presentations/latency-response-time[How NOT to @@ -473,11 +473,11 @@ the "Oh s#@t!" presentation.) xref:manual/performance.adoc#responseTime[Response time] is how long it takes to log a message under a certain load. What is often reported as -latency is actually _service time_: how long it took to perform the -operation. This hides the fact that a single spike in service time adds -queueing delay for many of the subsequent operations. Service time is +latency is _service time_: how long it took to operate. +This hides the fact that a single spike in service time adds +a queueing delay for many of the subsequent operations. Service time is easy to measure (and often looks good on paper) but is irrelevant for -users since it omits the time spent waiting for service. For this reason +users since it omits the time spent waiting for service. For this reason, we report response time: service time plus wait time. The response time test results below were all derived from running the @@ -494,9 +494,9 @@ wait strategy reduces some jitter.) * -XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle * -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationConcurrentTime --XX:+PrintGCApplicationStoppedTime (to eyeball GC and safepoint pauses) +-XX:+PrintGCApplicationStoppedTime (to eyeball GC and savepoint pauses) -The graph below compares response time latency of the +The graph below compares the response time latency of the ArrayBlockingQueue-based asynchronous appenders in Logback 1.1.7, Log4j 1.2.17 to the various options for asynchronous logging that Log4j 2.6 offers. Under a workload of 128,000 messages per second, using 16 @@ -506,14 +506,14 @@ orders of magnitude larger than Log4j 2. image:ResponseTimeAsyncLogging16Threads_8kEach.png[When 16 threads generate a total workload of 128,000 msg/sec, Logback 1.1.7 and -Log4j 1.2.17 experience latency spikes that are orders of magnitude +Log4j 1.2.17 experiences latency spikes that are orders of magnitude larger than Log4j 2] The graph below zooms in on the Log4j 2 results for the same test. We see that the worst-case response time is highest for the ArrayBlockingQueue-based Async Appender. xref:manual/garbagefree.adoc[Garbage-free] async loggers have the best response -time behaviour. +time behavior. image:ResponseTimeAsyncLogging16Threads_8kEachLog4j2Only-labeled.png[image] @@ -522,14 +522,14 @@ image:ResponseTimeAsyncLogging16Threads_8kEachLog4j2Only-labeled.png[image] Asynchronous Loggers are implemented using the https://lmax-exchange.github.io/disruptor/[LMAX Disruptor] inter-thread -messaging library. From the LMAX web site: +messaging library. From the LMAX website: ____ ...using queues to pass data between stages of the system was -introducing latency, so we focused on optimising this area. The +introducing latency, so we focused on optimizing this area. The Disruptor is the result of our research and testing. We found that cache -misses at the CPU-level, and locks requiring kernel arbitration are both -extremely costly, so we created a framework which has "mechanical +misses at the CPU level, and locks requiring kernel arbitration are both +extremely costly, so we created a framework that has "mechanical sympathy" for the hardware it's running on, and that's lock-free. ____ diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index 66a6b516881..63dc17b9b13 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -14,1856 +14,1220 @@ See the License for the specific language governing permissions and limitations under the License. //// -[#configuration] +[id=configuration] = Configuration -Ralph Goers - -Inserting log requests into the application code requires a fair amount -of planning and effort. Observation shows that approximately 4 percent -of code is dedicated to logging. Consequently, even moderately sized -applications will have thousands of logging statements embedded within -their code. Given their number, it becomes imperative to manage these -log statements without the need to modify them manually. - -Configuration of Log4j 2 can be accomplished in 1 of 4 ways: - -1. Through a configuration file written in XML, JSON, YAML, or -properties format. -2. Programmatically, by creating a ConfigurationFactory and -Configuration implementation. -3. Programmatically, by calling the APIs exposed in the Configuration -interface to add components to the default configuration. -4. Programmatically, by calling methods on the internal Logger class. - -This page focuses primarily on configuring Log4j through a configuration -file. Information on programmatically configuring Log4j can be found at -xref:manual/extending.adoc[Extending Log4j 2] and -xref:manual/customconfig.adoc[Programmatic Log4j Configuration]. - -All available formats are functionally equivalent. For example, a -configuration file in XML can be rewritten using the properties format -(and the opposite) without any loss of functionality. However, the -hierarchical nature of a Log4j configuration can be captured better in -formats which naturally support nesting so XML, JSON, and YAML files, -are usually easier to use. - -Note that unlike Log4j 1.x, the public Log4j 2 API does not expose -methods to add, modify or remove appenders and filters or manipulate the -configuration in any way. - -[#Architecture] -== Architecture - -In part because support for XML was added first, Log4j's configuration is reflected as a tree structure. -In fact every configuration dialect, including the ConfigurationBuilder, generates a Node for every -configuration element. A node is a fairly simple structure that contains a set of attributes, a set of -child nodes and a PluginType. It is important to note that every Node must have a corresponding plugn, -as the plugin is the component that actually performs the work represented by the node. - -Every document type supported by Log4j has a ConfigurationFactory. The factory itself is a Log4j plugin -that declares what file extensions it supports and what its priority is. Properties have the highest -precedence with a value of 8, followed by yaml, json and xml. When autoconfiguration is performed Log4j -will call each of these factories in order to determine which, if any, support the specified configuration -file format. If one is found that factory will create the corresponding Configuratoin object and pass the -reference to the configuration data to it. - -Every configuration implementation, such as XMLConfiguration, YamlConfiguration, JsonConfiguration, etc. -has the primary task of converting the configuration text into the Node tree, typically by parsing the -text with whatever tool is available for that document type. It should be noted that while most of the -supported document types are inherintly tree structured, the Java properties syntax is not. Because of the -need to convert the syntax into a Node tree the Java properties syntax used by Log4j required all properties -follow a naming pattern that made the tree structure clear. As a consequence, the Java Properties format -tends to be more verbose than using a different document type. - -Once the Node tree is created control is delegated to AbstractConfiguration, which convertes the Nodes into -their respective Java objects using Log4j's Plugin system and provides all the common functionality. - -[#Arbiters] -== Arbiters - -In some situations it is desirable to have a single logging configuration that can be used in any -deployment environment. For example, it may be necessary to have a different default logging level in -production then in development. Another case might be where one type of appender is used when running -natively but another is used when deployed to a docker container. One way to handle that is to use -a tool such as Spring Cloud Config Server that can be environment aware and serve a different file for -each environment. Another option is to include Arbiters in the configuration. - -An Arbiter is a Log4j plugin that has the job of determining whether other configured elements should be -included in the generated configuration. While all other "Core" plugins are designed to execute as part of -Log4j's runtime logic Arbiters execute after the Node tree has been constructed but before the tree is -converted to a configuration. An Arbiter is a Node itself which is always removed from the Node tree -before it the tree is processed. All an arbiter really does is provide a method that returns a boolean -result that determines whether the child nodes of the arbiter should remain in the configuration or be -pruned. - -Arbiters may occur anywhere an element is allowed in the configuration. So an Aribiter could encapsulate -something as simple as a single property declaration or a whole set of Appenders or Loggers. Arbiters -may also be nested although Arbiters that are the descendant of another arbiter will only be evalued if the -ancestor returned true. The child elements of an Arbiter must be valid elements for whatever element is -the parent of the Arbiter. - -This example shows two Arbiters configured that will include either a Console Appender or a List Appender -depending on whether the value of the env System Property is "dev" or "prod". -[source,xml] ----- - - - - - - - - - - - - - - - - - - - - - - - ----- - -Normally Arbiters act in isolation from other Arbiters. That is, the outcome of one Arbiter will not -impact any other Arbiters. This can be cumbersome when you simply want to use one of a set of choices. A -special plugin named "Select" can be used in this case. Each element under the Select is required to be -an Arbiter. The first Arbiter that returns a true value will be the one used while others are ignored. -If no Arbiter returns true a DefaultAtrbiter may be configured with the default configuration elements. -The DefaultArbiter is an Arbiter that always returns true, so using it outside of a Select would result in -its configured elements always being included just as if it hadn't been present. - -This example shows an Arbiter that uses Javascript residing in a separate file to determine whether to -include the Console Appender. If the result is false then a List Appender will be included. +Logging is a standard method for monitoring the health of an application and diagnosing problems that may arise within it. +Even moderately sized applications can contain thousands of logging statements. -[source,xml] ----- - - - - - - - - - - - - - ----- - -Natively Log4j contains the SystemProperty Arbiter that can evaluate whether to include elements based on -whether a SystemProperty is non-null or has a specific value, a ClassArbiter that makes its decision -based on whether the specified class is present, and a ScriptArbiter that makes its decision based -on the result of the script configured with it. - -For Spring Boot users an Arbiter named SpringProfile has been provided. The specified profiles -are evaluated by Spring's Environment.acceptsProfiles() method, so any expressions it supports -may be used as the name attribute. - -This example will use a Console Appender when the Spring profile is "dev" or "staging" and a List -Appender when the active profile is "prod". +To decide which of these statements will be logged and where, users need to configure Log4j Core in one of two ways: -[source,xml] +* through a <>. +Since version 2.0, the configuration file format has been considered part of the public API and has remained stable across significant version upgrades. + +* through xref:manual/customconfig.adoc[Programmatic Configuration], which provides a larger spectrum of possible customizations but might require code changes during version upgrades. + +[NOTE] +==== +To prevent a chicken-and-egg problem, users can only supply some configuration options (e.g., the configuration file location) through xref:manual/systemproperties.adoc[configuration properties]. +==== + +[#configuration-file] +== Configuration file + +Users can configure Log4j Core using different file formats. +The `log4j-core` artifact includes XML, JSON, YAML, and Java properties formats factories. + +As detailed in the table below, some configuration formats require additional dependencies on the classpath. + +include::partial$configuration-file-format-deps.adoc[] + +[WARNING] +==== +The format of the configuration file changed between Log4j{nbsp}1 and Log4j{nbsp}2. +Files in the Log4j{nbsp}1 format are ignored by default. + +To enable partial support for old configuration formats, see xref:manual/migration.adoc#enabling-the-log4j-1-x-bridge[Enabling the Log4j{nbsp}1 bridge]. +==== + +[id=automatic-configuration] +=== [[AutomaticConfiguration]] Configuration file location + +Upon initialization of a new logger context, Log4j assigns it a context name and scans the following **classpath** locations for a configuration file: + +. Files named `log4j2-test.` +. Files named `log4j2-test.`, +. Files named `log4j2.` +. Files named `log4j2.`, +. If no configuration file is found, Log4j uses the link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/DefaultConfiguration[DefaultConfiguration], and the status logger prints a warning. +The default configuration prints all messages less specific than +xref:manual/systemproperties.adoc#log4j2.level[log4j2.level] +to the console. + +[CAUTION] +==== +The configuration files prefixed by `log4j2-test` should only be used on the test classpath. + +If multiple configuration files in the same category are found, Log4j uses a deterministic order to choose one of them (see link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Order[@Order]). + +Nevertheless: + +* If you're developing an app, don't use config files with different extensions. +* If you're developing a library, only add config files to your test classpath. +==== + +The `` and `` placeholders above have the following meaning + +:: depends on the runtime environment in which Log4j runs: + +* for standalone Java SE applications, it is a random identifier, +* for web applications, it is derived from the application descriptor. +See xref:manual/webapp.adoc#configuration[Log4j + Web application configuration] for more details. + +:: must be one of the file extensions assigned to a configuration file format: ++ +[cols="1,1"] +|=== +| Configuration file format | Extension + +| XML +| `xml` + +| JSON +| `json` or `jsn` + +| YAML +| `yaml` or `yml` + +|Java properties +| `properties` +|=== + +[NOTE] +==== +It is also possible to override the location of the configuration file using the +xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurationFile] +configuration property. +In this case, Log4j will guess the configuration file format from the provided configuration file extension or use the default configuration factory if the extension is unknown. + +See xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurationFile] for details. +==== + +[id=configuration-syntax] +=== [[ConfigurationSyntax]] Syntax + +The Log4j runtime is composed of xref:manual/plugins.adoc[plugins], which are like beans in the Spring Framework and Java EE. +Appenders, layouts, filters, configuration loaders, and similar components are all accessed as plugins. + +All configuration files are represented internally as a tree of +link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node[Node]s, which is translated into a tree of Log4j plugins. +The tree's root creates a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration[Configuration] object. + +A node is a relatively simple structure representing a single Log4j plugin (see xref:plugin-reference.adoc[] for a complete list), such as an appender, layout, or logger configuration. + +Each node has: + +* a set of simple string key-value pairs called **attributes**. +Attributes are **matched by name** against the list of available configuration options of a Log4j plugin. + +* The **plugin type** attribute specifies the kind of Log4j plugin we want to instantiate. + +* A set of child nodes called **nested elements**. +They are **matched by type** against the list of nested components a plugin accepts. + +Log4j maps the concepts above to the specifics of the configuration format as follows: + +[tabs] +===== +XML:: ++ +Since XML was the original configuration format developed, the mapping from configuration nodes and XML elements is trivial: ++ +* Each configuration node is represented by an XML element. +* Each configuration attribute is represented by an XML attribute. +* The **plugin type** of a node is equal to the name of the XML tag. +* Each configuration nested element is represented by a nested XML element. ++ +[NOTE] +==== +There is an alternative XML configuration format called "XML strict format" that is activated +by setting the `strict` attribute of the main `` element to `true`. +It allows users to use any tag names as long as they provide the plugin type using a `type` property. + +The _XML strict format_ was conceived as a simplified XML format that can be validated by an XML schema but has fallen into disuse: nowadays, the automatically generated schemas published at https://logging.apache.org/xml/ns/ +offer a better alternative and allow users to use a more concise syntax. +==== + +JSON:: ++ +In the JSON configuration format: ++ +[id=configuration-with-json] +==== +* Each configuration node is represented by a JSON object, +* JSON properties of type string, number, or boolean are mapped to node attributes. +* JSON properties of type object or array represent nested configuration elements. +* The **plugin type** of a JSON object is given by: +** the value of the `type` key, if present, +** or the key associated with the JSON object otherwise. +** If the JSON object representing the node is part of an array, the key associated with the JSON array is used. +==== ++ +[TIP] +==== +If you need to specify multiple plugins of the same type, you can use JSON arrays. +The snippet below represents two plugins of type `File`. + +[source,json] ---- - - - - - - - - - - - - - - - - - - - - - - - ----- - -[#AutomaticConfiguration] -== Automatic Configuration - -Log4j has the ability to automatically configure itself during -initialization. When Log4j starts it will locate all the -ConfigurationFactory plugins and arrange them in weighted order from -highest to lowest. As delivered, Log4j contains four -ConfigurationFactory implementations: one for JSON, one for YAML, one -for properties, and one for XML. - -1. Log4j will inspect the <> system property and, if set, will attempt to load the configuration using the `ConfigurationFactory` that matches the file extension. -Note that this is not restricted to a location on the local file system and may contain a URL. -2. If no system property is set the properties ConfigurationFactory -will look for `log4j2-test.properties` in the classpath. -3. If no such file is found the YAML ConfigurationFactory will look for -`log4j2-test.yaml` or `log4j2-test.yml` in the classpath. -4. If no such file is found the JSON ConfigurationFactory will look for -`log4j2-test.json` or `log4j2-test.jsn` in the classpath. -5. If no such file is found the XML ConfigurationFactory will look for -`log4j2-test.xml` in the classpath. -6. If a test file cannot be located the properties ConfigurationFactory -will look for `log4j2.properties` on the classpath. -7. If a properties file cannot be located the YAML ConfigurationFactory -will look for `log4j2.yaml` or `log4j2.yml` on the classpath. -8. If a YAML file cannot be located the JSON ConfigurationFactory will -look for `log4j2.json` or `log4j2.jsn` on the classpath. -9. If a JSON file cannot be located the XML ConfigurationFactory will -try to locate `log4j2.xml` on the classpath. -10. If no configuration file could be located the `DefaultConfiguration` -will be used. This will cause logging output to go to the console. - -An example application named `MyApp` that uses log4j can be used to -illustrate how this is done. - -[source,java] ----- -import com.foo.Bar; - -// Import log4j classes. -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -public class MyApp { - - // Define a static logger variable so that it references the - // Logger instance named "MyApp". - private static final Logger logger = LogManager.getLogger(MyApp.class); - - public static void main(final String... args) { - - // Set up a simple configuration that logs on the console. - - logger.trace("Entering application."); - Bar bar = new Bar(); - if (!bar.doIt()) { - logger.error("Didn't do it."); - } - logger.trace("Exiting application."); +{ + "File": [ + { + "name": "file1" + }, + { + "name": "file2" } + ] } ---- +==== + +YAML:: ++ +In the YAML configuration format: ++ +[id=configuration-with-yaml] +==== +* A YAML mapping represents each configuration node, +* YAML properties of scalar type are mapped to node attributes. +* YAML properties of collection type are used to represent nested configuration elements. +* The **plugin type** of a YAML mapping is given by: +** the value of the `type` key, if present, +** or the key associated with the YAML mapping otherwise. +** If the YAML mapping representing the node is part of a YAML block sequence, the key associated with the YAML sequence is used. +==== ++ +[TIP] +==== +If you need to specify multiple plugins of the same type, you can use YAML block sequences. +The snippet below represents two plugins of type `File`. + +[source,yaml] +---- +File: + - name: file1 + - name: file2 +---- +==== + +Java properties:: ++ +In the Java properties configuration format: ++ +[id=configuration-with-properties] +==== +* Properties that share a common prefix (e.g., `appender.foo`) are mapped to a subtree of the configuration node tree. +* Configuration attributes are specified by appending the property's name (e.g., `name`) to the prefix of the node, separated by a dot (e.g., `appender.foo.name`). +* The **plugin type** must be specified as an attribute named `type`. +* Nested elements are created by: +** Choosing an arbitrary id for the nested component (e.g., `<0>`) +** Appending the id to the prefix of the parent component (e.g., `appender.foo.<0>`) +** Specifying the type of the nested plugin by assigning a `type` attribute (e.g., `appender.foo.<0>.type`) +==== ++ +[NOTE] +==== +Nested components use the assigned ID for sorting purposes only. +==== +===== + +See also <> for exceptions to the rules above. + +[id=main-configuration-elements] +=== Main configuration elements + +Log4j Core's logging pipeline is quite complex (see xref:manual/architecture.adoc[Architecture]), but most users only require these elements: + +Loggers:: ++ +Loggers are the entry point of the logging pipeline, which is directly used in the code. +Their configuration must specify which level of messages they log and to which appenders they send the messages. ++ +See <> for details. + +[id=configuring-appenders] +[[Appenders]] Appenders:: ++ +Appenders are the exit point of the logging pipeline. +They decide which resource (console, file, database, or similar) the log event is sent to. +In the examples of this chapter, we will only use the xref:manual/appenders.adoc#consoleappender[console appender] and the xref:manual/appenders.adoc#fileappender[file appender]. ++ +See xref:manual/appenders.adoc[Appender configuration] for details. + +Layouts:: ++ +Layouts tell appenders how to format the log event: text, JSON, XML, or similar. +In the examples of this chapter, we will only use the xref:manual/layouts.adoc#pattern-layout[textual pattern layout] +and +xref:manual/json-template-layout.adoc[JSON template layout]. ++ +See xref:manual/layouts.adoc[Layout configuration] for details. -`MyApp` begins by importing log4j related classes. It then defines a -static logger variable with the name `MyApp` which happens to be the -fully qualified name of the class. +A moderately complex configuration might look like this: -`MyApp` uses the `Bar` class defined in the package`com.foo`. +[tabs] +==== +XML:: ++ +[source,xml] +---- +include::example$manual/configuration/main-elements.xml[lines=1;18..-1] +---- -[source,java] +JSON:: ++ +[source,json] +---- +include::example$manual/configuration/main-elements.json[] ---- -package com.foo; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; -public class Bar { - static final Logger logger = LogManager.getLogger(Bar.class.getName()); +YAML:: ++ +[source,yaml] +---- +include::example$manual/configuration/main-elements.yaml[lines=17..-1] +---- - public boolean doIt() { - logger.entry(); - logger.error("Did it again!"); - return logger.exit(false); - } -} +Java properties:: ++ +[source,properties] +---- +include::example$manual/configuration/main-elements.properties[lines=17..-1] ---- +==== -Log4j will provide a default configuration if it cannot locate a -configuration file. The default configuration, provided in the -DefaultConfiguration class, will set up: +<1> Configures a console appender named `CONSOLE` with a pattern layout. +<2> Configures a file appender named `MAIN` with a JSON template layout. +<3> Configures a file appender named `DEBUG_LOG` with a pattern layout. +<4> Configures the root logger at level `INFO` and connects it to the `CONSOLE` and `MAIN` appenders. +The `CONSOLE` appender will only log messages less specific than `WARN`. +<5> Configures a logger named `"org.example"` at level `DEBUG` and connects it to the `DEBUG_LOG` appender. +The logger is configured to forward messages to its parent (the root appender). -* A -link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/ConsoleAppender.html[`ConsoleAppender`] -attached to the root logger. -* A -link:../javadoc/log4j-core/org/apache/logging/log4j/core/layout/PatternLayout.html[`PatternLayout`] -set to the pattern "%d\{HH:mm:ss.SSS} [%t] %-5level %logger\{36} - -%msg%n" attached to the ConsoleAppender +Using the above configuration, the list of appenders that will be used for each log event depends only on the level of the event and the name of the logger, as in the table below: -Note that by default Log4j assigns the root logger to `Level.ERROR`. +[cols="2m,2m,5"] +|=== +| Logger name | Log event level | Appenders -The output of MyApp would be similar to: +| org.example.foo +| WARN +| `CONSOLE`, `MAIN`, `DEBUG_LOG` -.... -17:13:01.540 [main] ERROR com.foo.Bar - Did it again! -17:13:01.540 [main] ERROR MyApp - Didn't do it. -.... +| org.example.foo +| DEBUG +| `MAIN`, `DEBUG_LOG` -As was described previously, Log4j will first attempt to configure -itself from configuration files. A configuration equivalent to the -default would look like: +| org.example.foo +| TRACE +| _none_ -[source,xml] ----- - - - - - - - - - - - - - ----- - -Once the file above is placed into the classpath as log4j2.xml you will -get results identical to those listed above. Changing the root level to -trace will result in results similar to: - -.... -17:13:01.540 [main] TRACE MyApp - Entering application. -17:13:01.540 [main] TRACE com.foo.Bar - entry -17:13:01.540 [main] ERROR com.foo.Bar - Did it again! -17:13:01.540 [main] TRACE com.foo.Bar - exit with (false) -17:13:01.540 [main] ERROR MyApp - Didn't do it. -17:13:01.540 [main] TRACE MyApp - Exiting application. -.... - -Note that status logging is disabled when the default configuration is -used. - -[#Configuration_From_a_URI] -== Configuration From a URI - -When `log4j2.configurationFile` references a URL, Log4j will first determine if the URL reference -a file using the file protocol. If it does Log4j will validate that the file URL is valid and continue -processing as previously described. If it contains a protocol other than file then Log4j will inspect -the value of the <> system property. If the provided list -contains the protocol specified then Log4j will use the URI to locate the specified configuration file. If -not an exception will be thrown and an error message will be logged. If no value is provided for the -system property it will default to "https". Use of any protocol other than "file" can be prevented by -setting the system property value to "_none". This value would be an invalid protocol so cannot conflict -with any custom protocols that may be present. - -Log4j supports access to remote URLs that require authentication. Log4j supports basic authentication -out of the box. If the `log4j2.Configuration.username` and `log4j2.Configuration.password` -are specified those values will be used to perform the authentication. If the password is encrypted a custom -password decryptor may be supplied by specifying the fully qualified class name in the -<> system property. A custom -`AuthenticationProvider` may be used by setting the -`<> system property to the fully qualified class name -of the provider. - -[#Additivity] -== Additivity - -Perhaps it is desired to eliminate all the TRACE output from everything -except `com.foo.Bar`. Simply changing the log level would not accomplish -the task. Instead, the solution is to add a new logger definition to the -configuration: +| com.example +| WARN +| `CONSOLE`, `MAIN` -[source,xml] ----- - - - - - - - ----- +| com.example +| INFO +| `MAIN` + +| com.example +| DEBUG +| _none_ + +|=== + +[id=additional-configuration-elements] +=== Additional configuration elements + +A Log4j Core configuration file can also contain these configuration elements: + +CustomLevels:: ++ +Log4j allows the configuration of custom log-level names. ++ +See xref:manual/customloglevels.adoc[Custom log level configuration] for details. + +Filters:: ++ +Users can add Components to loggers, appender references, appenders, or the global configuration object to provide additional filtering of log events. ++ +See xref:manual/filters.adoc[Filter configuration] for details. + +Properties:: ++ +Represent a set of reusable configuration values for property substitution. ++ +See <> for details. + +Scripts:: ++ +Scripts are a container for JSR 223 scripts that users can use in other Log4j components. ++ +For details, see xref:manual/scripts.adoc[Scripts configuration]. + +[id=global-configuration-attributes] +=== Global configuration attributes + +The main `Configuration` element has a set of attributes that can be used to tune how the configuration file is used. +The principal attributes are listed below. +See xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-Configuration[Plugin reference] for a complete list. + +[id=configuration-attribute-monitorInterval] +==== [[AutomaticReconfiguration]] `monitorInterval` + +[cols="1h,5"] +|=== +| Type | `int` +| Default value | `0` +|=== + +Determines the polling interval used by Log4j to check for changes to the configuration file. +If a change in the configuration file is detected, Log4j automatically reconfigures the logger context. +If set to `0`, polling is disabled. + +[CAUTION] +==== +Log4j Core is designed with reliability in mind, unlike other logging backends. + +During a reconfiguration process, no messages are lost. + +Unless the new configuration file removes an appender, the old ones work without interruption. -With this configuration all log events from `com.foo.Bar` will be -recorded while only error events will be recorded from all other -components. +Some changed appender options will be **ignored** during reconfiguration. +For example, appenders that need to close resources, like the append mode used to open a file, will ignore such options. -In the previous example all the events from `com.foo.Bar` were still -written to the Console. This is because the logger for `com.foo.Bar` did -not have any appenders configured while its parent did. In fact, the -following configuration +To modify these options during a reconfiguration, you also need to change the resource used by the appender (e.g., the file name used by a file appender). +==== +[id=configuration-attribute-status] +==== `status` + +[cols="1h,5"] +|=== +| Type | link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[LEVEL] +| Status | **DEPRECATED** +| Default value (since 2.24.0) | xref:manual/systemproperties.adoc#log4j2.statusLoggerLevel[log4j2.statusLoggerLevel] +| Default value (before 2.24.0) | value of `log4j2.defaultStatusLevel` +|=== + +Overrides the logging level of the status logger. + +WARNING: Since 2.24.0 this attribute is deprecated and should be replaced with the +xref:manual/systemproperties.adoc#log4j2.statusLoggerLevel[log4j2.statusLoggerLevel] +configuration property. + +[id=configuration-elements-filters] +==== Filters + +See xref:manual/filters.adoc#filters[Filters] for additional filtering capabilities that can be applied to the global configuration object. + +[id=configuring-loggers] +=== [[Loggers]] Loggers + +Log4j 2 contains multiple types of logger configurations that can be added to the `Loggers` element of the configuration: + +`Root`:: is the logger that receives all events that do not have a more specific logger defined. ++ +See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-LoggerConfig-RootLogger[Plugin reference]. + +`AsyncRoot`:: is an alternative implementation of the root logger used in the xref:manual/async.adoc#MixedSync-Async[mixed synchronous and asynchronous mode]. ++ +See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-AsyncLoggerConfig-RootLogger[Plugin reference]. + +`Logger`:: the most common logger kind, which collects log events from itself and all the children loggers, which do not have an explicit configuration (see xref:manual/architecture.adoc#logger-hierarchy[logger hierarchy]). ++ +See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-LoggerConfig[Plugin Reference]. + +`AsyncLogger`:: the equivalent of `Logger`, used in the xref:manual/async.adoc#MixedSync-Async[mixed synchronous and asynchronous mode]. ++ +See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-AsyncLoggerConfig[Plugin Reference]. + +There **must** be at least a `Root` or `AsyncRoot` element in every configuration file. +Other logger configurations are optional. + +Every +link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html[Logger] +in your application is assigned to one of these logger configurations (see +xref:manual/architecture.adoc#loggerconfig[architecture]), which determines the events that will be logged and those that won't. + +Let's start with an example of logger configuration: + +[tabs] +==== +XML:: ++ [source,xml] ---- - - - - - - - - - - - - - - - - ----- - -would result in - -.... -17:13:01.540 [main] TRACE com.foo.Bar - entry -17:13:01.540 [main] TRACE com.foo.Bar - entry -17:13:01.540 [main] ERROR com.foo.Bar - Did it again! -17:13:01.540 [main] TRACE com.foo.Bar - exit (false) -17:13:01.540 [main] TRACE com.foo.Bar - exit (false) -17:13:01.540 [main] ERROR MyApp - Didn't do it. -.... - -Notice that the trace messages from `com.foo.Bar` appear twice. This is -because the appender associated with logger `com.foo.Bar` is first used, -which writes the first instance to the Console. Next, the parent of -`com.foo.Bar`, which in this case is the root logger, is referenced. The -event is then passed to its appender, which is also writes to the -Console, resulting in the second instance. This is known as additivity. -While additivity can be quite a convenient feature (as in the first -previous example where no appender reference needed to be configured), -in many cases this behavior is considered undesirable and so it is -possible to disable it by setting the additivity attribute on the logger -to false: +include::example$manual/configuration/loggers.xml[tag=loggers] +---- -[source,xml] +JSON:: ++ +[source,json] +---- +include::example$manual/configuration/loggers.json[tag=loggers] ---- - - - - - - - - - - - - - - - - ----- - -Once an event reaches a logger with its additivity set to false the -event will not be passed to any of its parent loggers, regardless of -their additivity setting. - -[#AutomaticReconfiguration] -== Automatic Reconfiguration - -When configured from a File, Log4j has the ability to automatically -detect changes to the configuration file and reconfigure itself. If the -`monitorInterval` attribute is specified on the configuration element -and is set to a non-zero value then the file will be checked the next -time a log event is evaluated and/or logged and the monitorInterval has -elapsed since the last check. The example below shows how to configure -the attribute so that the configuration file will be checked for changes -only after at least 30 seconds have elapsed. The minimum interval is 5 -seconds. -[source,xml] +YAML:: ++ +[source,yaml] +---- +include::example$manual/configuration/loggers.yaml[tag=loggers] ---- - - -... - ----- - -[#ChainsawSupport] -== Chainsaw can automatically process your log files (Advertising appender configurations) - -Log4j provides the ability to 'advertise' appender configuration details -for all file-based appenders as well as socket-based appenders. For -example, for file-based appenders, the file location and the pattern -layout in the file are included in the advertisement. Chainsaw and other -external systems can discover these advertisements and use that -information to intelligently process the log file. - -The mechanism by which an advertisement is exposed, as well as the -advertisement format, is specific to each Advertiser implementation. An -external system which would like to work with a specific Advertiser -implementation must understand how to locate the advertised -configuration as well as the format of the advertisement. For example, a -'database' Advertiser may store configuration details in a database -table. An external system can read that database table in order to -discover the file location and the file format. - -Log4j provides one Advertiser implementation, a 'multicastdns' -Advertiser, which advertises appender configuration details via IP -multicast using the http://jmdns.sourceforge.net library. - -Chainsaw automatically discovers log4j's multicastdns-generated -advertisements and displays those discovered advertisements in -Chainsaw's Zeroconf tab (if the jmdns library is in Chainsaw's -classpath). To begin parsing and tailing a log file provided in an -advertisement, just double-click the advertised entry in Chainsaw's -Zeroconf tab. Currently, Chainsaw only supports FileAppender -advertisements. - -To advertise an appender configuration: - -* Add the JmDns library from http://jmdns.sourceforge.net to the -application classpath -* Set the 'advertiser' attribute of the configuration element to -'multicastdns' -* Set the 'advertise' attribute on the appender element to 'true' -* If advertising a FileAppender-based configuration, set the -'advertiseURI' attribute on the appender element to an appropriate URI - -FileAppender-based configurations require an additional 'advertiseURI' -attribute to be specified on the appender. The 'advertiseURI' attribute -provides Chainsaw with information on how the file can be accessed. For -example, the file may be remotely accessible to Chainsaw via ssh/sftp by -specifying a Commons VFS (http://commons.apache.org/proper/commons-vfs/) -sftp:// URI, an http:// URI may be used if the file is accessible -through a web server, or a file:// URI can be specified if accessing the -file from a locally-running instance of Chainsaw. - -Here is an example advertisement-enabled appender configuration which -can be used by a locally-running Chainsaw to automatically tail the log -file (notice the file:// advertiseURI): - -*Please note, you must add the JmDNS library mentioned above.* -[source,xml] +Java properties:: ++ +[source,properties] ---- - - - ... - - - ... - - - +include::example$manual/configuration/loggers.properties[tags=loggers] ---- +==== + +In the example above, we have four logger configurations. +They differ from each other regarding the level of log messages that they allow, whether +xref:manual/layouts.adoc#location-information[location information] +will be printed, and which appenders will be used. +The table below summarizes the effects of each logger configuration: + +.Logger configurations +[cols="1,2,2,2,2,5"] +|=== +| +| <> +| <> +| <> +| <> +h| Appenders used + +| 1 +| _empty_ +| `INFO` +| N/A +| _default_ +| `APPENDER1` + +| 2 +| `org.example.no_additivity` +| `INFO` + +(inherited) +| `false` +| _default_ +| `APPENDER2` + +| 3 +| `org.example.no_location` +| `INFO` + +(inherited) +| `true` +| `false` +| `APPENDER1` and `APPENDER3` + +| 4 +| `org.example.level` +| `DEBUG` +| `true` +| _default_ +| `APPENDER1` and `APPENDER4` +|=== -[#ConfigurationSyntax] -== Configuration Syntax +In the following part of this section, we explain in detail all the available options for logger configurations: -As of version 2.9, for security reasons, Log4j does not process DTD in -XML files. If you want to split the configuration in multiple files, use -link:#XInclude[XInclude] or link:#CompositeConfiguration[Composite -Configuration]. +[id=logger-attributes-name] +==== `name` -As the previous examples have shown as well as those to follow, Log4j -allows you to easily redefine logging behavior without needing to modify -your application. It is possible to disable logging for certain parts of -the application, log only when specific criteria are met such as the -action being performed for a specific user, route output to Flume or a -log reporting system, etc. Being able to do this requires understanding -the syntax of the configuration files. +[cols="1h,5"] +|=== +| Type +| `String` + +| Applies to +| `Logger` and `AsyncLogger` +|=== -The configuration element in the XML file accepts several attributes: +Specifies the name of the logger configuration. -[cols="1m,5a"] +Since loggers are usually named using fully qualified class names, this value usually contains the fully qualified name of a class or a package. + +[id=logger-attributes-additivity] +==== [[Additivity]] `additivity` + +[cols="1h,5"] |=== -|Attribute Name |Description - -|advertiser -|(Optional) The Advertiser plugin name which will be used to -advertise individual FileAppender or SocketAppender configurations. The -only Advertiser plugin provided is "multicastdns". - -|dest -|Either "err" for stderr, "out" for stdout, a file path, or a URL. - -|monitorInterval -|The minimum amount of time, in seconds, that must -elapse before the file configuration is checked for changes. - -|name -|The name of the configuration. - -|schema -|Identifies the location for the classloader to located the XML -Schema to use to validate the configuration. Only valid when strict is -set to true. If not set no schema validation will take place. - -|shutdownHook -|Specifies whether or not Log4j should automatically -shutdown when the JVM shuts down. The shutdown hook is enabled by -default but may be disabled by setting this attribute to "disable" - -|shutdownTimeout -|Specifies how many milliseconds appenders and -background tasks will get to shutdown when the JVM shuts down. Default -is zero which mean that each appender uses its default timeout, and -don't wait for background tasks. Not all appenders will honor this, it -is a hint and not an absolute guarantee that the shutdown procedure will -not take longer. Setting this too low increase the risk of losing -outstanding log events not yet written to the final destination. See -link:../javadoc/log4j-core/org/apache/logging/log4j/core/LoggerContext.html$%7Besc.hash%7Dstop(long,%20java.util.concurrent.TimeUnit)[LoggerContext.stop(long, -java.util.concurrent.TimeUnit)]. (Not used if `shutdownHook` is set to -"disable".) - -|status -|The level of internal Log4j events that should be logged to the console. -Valid values for this attribute are "off", "trace", "debug", "info", "warn", -"error", "fatal", and "all". Log4j will log details about initialization, -rollover and other internal actions to the status logger. Setting -`status="trace"` is one of the first tools available to you if you need -to troubleshoot log4j. - -(Alternatively, setting system property <> will also print -internal Log4j2 logging to the console, including internal logging that -took place before the configuration file was found.) - -|strict -|Enables the use of the strict XML format. Not supported in JSON -configurations. - -|verbose -|Enables diagnostic information while loading plugins. +| Type | `boolean` +| Default value | `true` +| Applies to | `Logger` and `AsyncLogger` |=== -[[XML]] -=== Configuration with XML +If `true` (default), all the messages this logger receives will also be transmitted to its +xref:manual/architecture.adoc#logger-hierarchy[parent logger]). -Log4j can be configured using two XML flavors; concise and strict. +[id=logger-attributes-level] +==== `level` -=== Concise Syntax +[cols="1h,5"] +|=== +| Type +| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[Level] + +| Default value +a| +* xref:manual/systemproperties.adoc#log4j2.level[log4j2.level], +for `Root` and `AsyncRoot`, +* inherited from the +xref:manual/architecture.adoc#logger-hierarchy[parent logger], +for `Logger` and `AsyncLogger`. +|=== -The concise format makes configuration very easy as the element names match -the components they represent however it cannot be validated with an XML -schema. For example, the ConsoleAppender is configured by declaring an -XML element named Console under its parent appenders element. However, -element and attribute names are not case sensitive. In addition, -attributes can either be specified as an XML attribute or as an XML -element that has no attributes and has a text value. So +Specifies the level threshold that a log event must have to be logged. +Log events that are more specific than this setting will be filtered out. +See also xref:manual/filters.adoc#filters[Filters] if you require additional filtering. + +[id=logger-attributes-includeLocation] +==== `includeLocation` + +[cols="1h,5"] +|=== +| Type +| `boolean` + +| Default value +a| +* `false`, if an asynchronous `ContextSelector` is used. +* Otherwise, +** `true` for `Root` and `Logger`, +** `false` for `AsyncRoot` and `AsyncLogger`. + +See +xref:manual/systemproperties.adoc#log4j2.contextSelector[log4j2.contextSelector] +for more details. +|=== + +Specifies whether Log4j is allowed to compute location information. +If set to `false`, Log4j will not attempt to infer the location of the logging call unless said location was provided explicitly using one of the available +https://logging.apache.org/log4j/2.x/javadoc/log4j-api/org/apache/logging/log4j/LogBuilder.html[LogBuilder +.withLocation()] +methods. + +See xref:manual/layouts.adoc#location-information[Location information] for more details. + +[id=logger-elements-appenderrefs] +==== Appender references + +Loggers use appender references to list the appenders to deliver log events. + +See <> below for more details. + +[id=logger-elements-properties] +==== Additional context properties + +Loggers can emit additional context data that will be integrated with other context data sources such as xref:manual/thread-context.adoc[ThreadContext]. + +[CAUTION] +==== +The `value` of each property is subject to <> twice: + +* when the configuration is loaded, +* each time a log event is generated. + +Therefore, if you wish to insert a value that changes in time, you must double the `$` sign, as shown in the example below. +==== + +[tabs] +==== +XML:: ++ [source,xml] ---- - +include::example$manual/configuration/logger-properties.xml[tag=loggers] ---- -and +JSON:: ++ +[source,json] +---- +include::example$manual/configuration/logger-properties.json[tag=loggers] +---- -[source,xml] +YAML:: ++ +[source,yaml] ---- - - %m%n - +include::example$manual/configuration/logger-properties.yaml[tag=loggers] ---- -are equivalent. +Java properties:: ++ +[source,properties] +---- +include::example$manual/configuration/logger-properties.properties[tag=loggers] +---- +==== + +[id=logger-elements-filters] +==== Filters + +See xref:manual/filters.adoc#filters[Filters] for additional filtering capabilities that can be applied to a logger configuration. + +[id=configuring-appenderrefs] +=== Appender references + +Many Log4j components, such as loggers, use appender references to designate which appenders will be used to deliver their events. + +Unlike in Log4j 1, where appender references were simple pointers, in Log4j 2, they have additional filtering capabilities. + +Appender references can have the following configuration attributes and elements: + +[id=appenderref-attributes-name] +==== `ref` + +[cols="1h,5"] +|=== +| Type | `String` +|=== + +Specifies the name of the appender to use. + +[id=appenderref-attributes-level] +==== `level` -The file below represents the structure of an XML configuration, but -note that the elements in italics below represent the concise element -names that would appear in their place. +[cols="1h,5"] +|=== +| Type | link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[Level] +|=== + +Specifies the level threshold that a log event must have to be logged. +Log events that are more specific than this setting will be filtered out. + +[id=appenderrefs-elements-filters] +==== Filters + +See xref:manual/filters.adoc#filters[Filters] for additional filtering capabilities that can be applied to a logger configuration. +[id=property-substitution] +=== Property substitution + +Log4j provides a simple and extensible mechanism to reuse values in the configuration file using `$\{name}` expressions, such as those used in Bash, Ant or Maven. + +Reusable configuration values can be added directly to a configuration file by using a xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-PropertiesPlugin[Properties] component. + +[tabs] +==== +XML:: ++ [source,xml] ---- -; - - - value - - - - - - - - ... - - - - - - ... - - - - - ----- - -See the many examples on this page for sample appender, filter and -logger declarations. - -=== Strict XML - -In addition to the concise XML format above, Log4j allows configurations -to be specified in a more "normal" XML manner that can be validated -using an XML Schema. This is accomplished by replacing the friendly -element names above with their object type as shown below. For example, -instead of the ConsoleAppender being configured using an element named -Console it is instead configured as an appender element with a type -attribute containing "Console". +include::example$manual/configuration/properties.xml[lines=1;18..24;26] +---- -[source,xml] +JSON:: ++ +[source,json] +---- +include::example$manual/configuration/properties.json[] ---- - - - - value - - - - - - - - ... - - - - - - ... - - - - - ----- - -Below is a sample configuration using the strict format. +YAML:: ++ +[source,yaml] +---- +include::example$manual/configuration/properties.yaml[lines=17..-1] +---- + +Java properties:: ++ +[source,properties] +---- +include::example$manual/configuration/properties.properties[lines=17..-1] +---- +==== + +An extensible lookup mechanism can also provide reusable configuration values. +See xref:manual/lookups.adoc[Lookup]s for more information. + +Configuration values defined this way can be used in **any** configuration attribute by using the following expansion rules: + +`$\{name}`:: ++ +If the `Properties` element of the configuration file has a property named `name`, its value is substituted. +Otherwise, the placeholder is not expanded. ++ +[WARNING] +==== +If `name` contains a `:` character, it is expanded as in the rule below. +==== + +`${lookup:name}`:: +If both these conditions hold: ++ +-- +* `lookup` is a prefix assigned to a xref:manual/lookups.adoc[Lookup], +* the lookup has a value assigned to `name`, +-- ++ +the value for the lookup is substituted. +Otherwise, the expansion of `$\{name}` is substituted. ++ +If `name` starts with a hyphen `-` (e.g. `-variable`), it must be escaped with a backslash `\` (e.g. `\-variable`). ++ +The most common lookup prefixes are: ++ +* `sys` for Java system properties (see xref:manual/lookups.adoc#system-properties-lookup[System Properties lookup]), +* `env` for environment variables (see xref:manual/lookups.adoc#environment-lookup[Environment lookup]). + +The above expansions have a version with an additional `default` value that is **expanded** if the lookup fails: + +`${name:-default}`:: ++ +If the `Properties` element of the configuration file has a property named `name,` its value is substituted. +Otherwise, the **expansion** of `default` is substituted. ++ +[WARNING] +==== +If `name` contains a `:` character, it is expanded as in the rule below. +==== + +`${lookup:name:-default}`:: ++ +If both these conditions hold: ++ +-- +* `lookup` is a prefix assigned to a xref:manual/lookups.adoc[Lookup], +* the lookup has a value assigned to `name,` +-- ++ +the value for the lookup is substituted. +Otherwise, the expansion of `${name:-default}` is substituted. + +[NOTE] +==== +To prevent the expansion of one of the expressions above, the initial `$` must be doubled as `$$`. + +The same rule applies to the `name` parameter: if it contains a `${` sequence, it must be escaped as `$${`. +==== + +.Property substitution example +===== + +If your configuration file contains the following definitions: +[tabs] +==== +XML:: ++ [source,xml] ---- - - - - target/test.log - - - - - - - - - - - - - - - - - - - - - %d %p %C{1.} [%t] %m%n - - - - - - - - - - - - - - - - - - - - - - ----- - -[#JSON] -=== Configuration with JSON - -In addition to XML, Log4j can be configured using JSON. The JSON format -is very similar to the concise XML format. Each key represents the name -of a plugin and the key/value pairs associated with it are its -attributes. Where a key contains more than a simple value it itself will -be a subordinate plugin. In the example below, ThresholdFilter, Console, -and PatternLayout are all plugins while the Console plugin will be -assigned a value of STDOUT for its name attribute and the -ThresholdFilter will be assigned a level of debug. +include::example$manual/configuration/properties-example.xml[lines=18..-1] +---- +JSON:: ++ [source,json] ---- -{ "configuration": { "status": "error", "name": "RoutingTest", - "packages": "org.apache.logging.log4j.test", - "properties": { - "property": { "name": "filename", - "value" : "target/rolling1/rollingtest-$${sd:type}.log" } - }, - "ThresholdFilter": { "level": "debug" }, - "appenders": { - "Console": { "name": "STDOUT", - "PatternLayout": { "pattern": "%m%n" }, - "ThresholdFilter": { "level": "debug" } - }, - "Routing": { "name": "Routing", - "Routes": { "pattern": "$${sd:type}", - "Route": [ - { - "RollingFile": { - "name": "Rolling-${sd:type}", "fileName": "${filename}", - "filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz", - "PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"}, - "SizeBasedTriggeringPolicy": { "size": "500" } - } - }, - { "AppenderRef": "STDOUT", "key": "Audit"} - ] - } - } - }, - "loggers": { - "logger": { "name": "EventLogger", "level": "info", "additivity": "false", - "AppenderRef": { "ref": "Routing" }}, - "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }} - } - } -} +include::example$manual/configuration/properties-example.json[] ---- -Note that in the RoutingAppender the Route element has been declared as -an array. This is valid because each array element will be a Route -component. This won't work for elements such as appenders and filters, -where each element has a different name in the concise format. Appenders -and filters can be defined as array elements if each appender or filter -declares an attribute named "type" that contains the type of the -appender. The following example illustrates this as well as how to -declare multiple loggers as an array. +YAML:: ++ +[source,yaml] +---- +include::example$manual/configuration/properties-example.yaml[lines=17..-1] +---- -[source,json] +Java properties:: ++ +[source,properties] ---- -{ "configuration": { "status": "debug", "name": "RoutingTest", - "packages": "org.apache.logging.log4j.test", - "properties": { - "property": { "name": "filename", - "value" : "target/rolling1/rollingtest-$${sd:type}.log" } - }, - "ThresholdFilter": { "level": "debug" }, - "appenders": { - "appender": [ - { "type": "Console", "name": "STDOUT", "PatternLayout": { "pattern": "%m%n" }, "ThresholdFilter": { "level": "debug" }}, - { "type": "Routing", "name": "Routing", - "Routes": { "pattern": "$${sd:type}", - "Route": [ - { - "RollingFile": { - "name": "Rolling-${sd:type}", "fileName": "${filename}", - "filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz", - "PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"}, - "SizeBasedTriggeringPolicy": { "size": "500" } - } - }, - { "AppenderRef": "STDOUT", "key": "Audit"} - ] - } - } - ] - }, - "loggers": { - "logger": [ - { "name": "EventLogger", "level": "info", "additivity": "false", - "AppenderRef": { "ref": "Routing" }}, - { "name": "com.foo.bar", "level": "error", "additivity": "false", - "AppenderRef": { "ref": "STDOUT" }} - ], - "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }} - } - } -} +include::example$manual/configuration/properties-example.properties[lines=17..-1] ---- +==== -Additional xref:runtime-dependencies.adoc[runtime dependencies] are -required for using JSON configuration files. +and the OS environment variable `FOO` has a value of `environment`, Log4j will evaluate the expression as follows -[#YAML] -=== Configuration with YAML +[cols="1m,1m"] +|=== +| Expression | Value + +| $\{FOO} | foo +| $\{BAZ} | $\{BAZ} +| ${BAR:-$\{FOO}} | bar +| ${BAZ:-$\{FOO}} | foo +| ${env:FOO} | environment +| ${env:BAR} | bar +| ${env:BAZ} | $\{BAZ} +| ${env:BAR:-$\{FOO}} | bar +| ${env:BAZ:-$\{FOO}} | foo +|=== +===== -Log4j also supports using YAML for configuration files. The structure -follows the same pattern as both the XML and YAML configuration formats. -For example: +[CAUTION] +===== +For security reasons, if the **expansion** of a `${...}` expression contains other expressions, these will **not** be expanded. +The only exception to this rule is the expansion of properties in the `Properties` container. -[source,yaml] +Properties defined in the `Properties` container can depend on each other. +If your configuration contains, for example: + +[tabs] +==== +XML:: ++ +[source,xml] +---- +include::example$manual/configuration/properties-recursion.xml[lines=18..-1] ---- -Configuration: - status: warn - name: YAMLConfigTest - properties: - property: - name: filename - value: target/test-yaml.log - thresholdFilter: - level: debug - appenders: - Console: - name: STDOUT - target: SYSTEM_OUT - PatternLayout: - Pattern: "%m%n" - File: - name: File - fileName: ${filename} - PatternLayout: - Pattern: "%d %p %C{1.} [%t] %m%n" - Filters: - ThresholdFilter: - level: error - - Loggers: - logger: - - - name: org.apache.logging.log4j.test1 - level: debug - additivity: false - ThreadContextMapFilter: - KeyValuePair: - key: test - value: 123 - AppenderRef: - ref: STDOUT - - - name: org.apache.logging.log4j.test2 - level: debug - additivity: false - AppenderRef: - ref: File - Root: - level: error - AppenderRef: - ref: STDOUT - ----- - -Additional xref:runtime-dependencies.adoc[runtime dependencies] are -required for using YAML configuration files. - -[#Properties] -=== Configuration with Properties - -As of version 2.4, Log4j now supports configuration via properties -files. Note that the property syntax is NOT the same as the syntax used -in Log4j 1. Like the XML and JSON configurations, properties -configurations define the configuration in terms of plugins and -attributes to the plugins. - -Prior to version 2.6, the properties configuration requires that you -list the identifiers of the appenders, filters and loggers, in a comma -separated list in properties with those names. Each of those components -will then be expected to be defined in sets of properties that begin -with _component.<.identifier>._. The identifier does not have to match -the name of the component being defined but must uniquely identify all -the attributes and subcomponents that are part of the component. If the -list of identifiers is not present the identifier must not contain a '.'. -Each individual component MUST have a "type" attribute specified that -identifies the component's Plugin type. - -As of version 2.6, this list of identifiers is no longer required as -names are inferred upon first usage, however if you wish to use more -complex identifies you must still use the list. If the list is present -it will be used. - -Unlike the base components, when creating subcomponents you cannot -specify an element containing a list of identifiers. Instead, you must -define the wrapper element with its type as is shown in the policies -definition in the rolling file appender below. You then define each of -the subcomponents below that wrapper element, as the -TimeBasedTriggeringPolicy and SizeBasedTriggeringPolicy are defined -below. - -As of version 2.17.2, `rootLogger` and `logger._key_` properties can be specified to set the -level and zero or more appender refs to create for that logger. The level and appender refs are -separated by comma `,` characters with optional whitespace surrounding the comma. The -following example demonstrates how the shorthand is expanded when reading properties configurations. -[source,properties] +JSON:: ++ +[source,json] +---- +include::example$manual/configuration/properties-recursion.json[] ---- -appender.stdout.type = Console -# ... other appender properties -appender.file.type = File -# ... other appender properties -logger.app = INFO, stdout, file -logger.app.name = com.example.app - -# is equivalent to: -# appender.stdout.type = Console -# appender.stdout.name = stdout -# ... -appender.file.type = File -appender.file.name = file -# ... -logger.app.name = com.example.app -logger.app.level = INFO -logger.app.appenderRef.$1.ref = stdout -logger.app.appenderRef.$2.ref = file ----- - -Properties configuration files support the advertiser, monitorInterval, -name, packages, shutdownHook, shutdownTimeout, status, verbose, and dest -attributes. See link:#ConfigurationSyntax[Configuration Syntax] for the -definitions of these attributes. -[source,properties] +YAML:: ++ +[source,yaml] +---- +include::example$manual/configuration/properties-recursion.yaml[lines=17..-1] ---- -status = error -dest = err -name = PropertiesConfig - -property.filename = target/rolling/rollingtest.log - -filter.threshold.type = ThresholdFilter -filter.threshold.level = debug - -appender.console.type = Console -appender.console.name = STDOUT -appender.console.layout.type = PatternLayout -appender.console.layout.pattern = %m%n -appender.console.filter.threshold.type = ThresholdFilter -appender.console.filter.threshold.level = error - -appender.rolling.type = RollingFile -appender.rolling.name = RollingFile -appender.rolling.fileName = ${filename} -appender.rolling.filePattern = target/rolling2/test1-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz -appender.rolling.layout.type = PatternLayout -appender.rolling.layout.pattern = %d %p %C{1.} [%t] %m%n -appender.rolling.policies.type = Policies -appender.rolling.policies.time.type = TimeBasedTriggeringPolicy -appender.rolling.policies.time.interval = 2 -appender.rolling.policies.time.modulate = true -appender.rolling.policies.size.type = SizeBasedTriggeringPolicy -appender.rolling.policies.size.size=100MB -appender.rolling.strategy.type = DefaultRolloverStrategy -appender.rolling.strategy.max = 5 - -logger.rolling.name = com.example.my.app -logger.rolling.level = debug -logger.rolling.additivity = false -logger.rolling.appenderRef.rolling.ref = RollingFile - -rootLogger.level = info -rootLogger.appenderRef.stdout.ref = STDOUT - ----- - - -[#Loggers] -=== Configuring Loggers - -An understanding of how loggers work in Log4j is critical before trying -to configure them. Please reference the Log4j -xref:manual/architecture.adoc[architecture] if more information is required. -Trying to configure Log4j without understanding those concepts will lead -to frustration. - -A LoggerConfig is configured using the `logger` element. The `logger` -element must have a name attribute specified, will usually have a level -attribute specified and may also have an additivity attribute specified. -The level may be configured with one of TRACE, DEBUG, INFO, WARN, ERROR, -ALL or OFF. If no level is specified it will default to ERROR. The -additivity attribute may be assigned a value of true or false. If the -attribute is omitted the default value of true will be used. - -Capturing location information (the class name, file name, method name, and line number of the caller) -can be slow. Log4j tries to optimize this by reducing the size of the stack that must be traversed -to find the caller of the logging method. It does this by determining if any component that might -be accessed requires location information. This can cause performance issues if a logger is configured -at a level like trace or debug with the expectation that most logs will be filtered on an Appender -reference or Appender as Log4j will calculate the location information even though the log event -is going to be discarded. To disable this behavior the `includeLocation` attribute -can be set to false on the LoggerConfig. This will cause Log4j to defer calculating the location -information until absolutely necessary. - -A LoggerConfig (including the root LoggerConfig) can be configured with -properties that will be added to the properties copied from the -ThreadContextMap. These properties can be referenced from Appenders, -Filters, Layouts, etc just as if they were part of the ThreadContext -Map. The properties can contain variables that will be resolved either -when the configuration is parsed or dynamically when each event is -logged. See link:#PropertySubstitution[Property Substitution] for more -information on using variables. - -The LoggerConfig may also be configured with one or more AppenderRef -elements. Each appender referenced will become associated with the -specified LoggerConfig. If multiple appenders are configured on the -LoggerConfig each of them be called when processing logging events. - -*_Every configuration must have a root logger_*. If one is not -configured the default root LoggerConfig, which has a level of ERROR and -has a Console appender attached, will be used. The main differences -between the root logger and other loggers are - -1. The root logger does not have a name attribute. -2. The root logger does not support the additivity attribute since it -has no parent. - -[#Appenders] -=== Configuring Appenders - -An appender is configured either using the specific appender plugin's -name or with an appender element and the type attribute containing the -appender plugin's name. In addition each appender must have a name -attribute specified with a value that is unique within the set of -appenders. The name will be used by loggers to reference the appender as -described in the previous section. - -Most appenders also support a layout to be configured (which again may -be specified either using the specific Layout plugin's name as the -element or with "layout" as the element name along with a type attribute -that contains the layout plugin's name. The various appenders will -contain other attributes or elements that are required for them to -function properly. - -[#Filters] -=== Configuring Filters - -Log4j allows a filter to be specified in any of 4 places: - -1. At the same level as the appenders, loggers and properties elements. -These filters can accept or reject events before they have been passed -to a LoggerConfig. -2. In a logger element. These filters can accept or reject events for -specific loggers. -3. In an appender element. These filters can prevent or cause events to -be processed by the appender. -4. In an appender reference element. These filters are used to -determine if a Logger should route the event to an appender. - -Although only a single `filter` element can be configured, that element -may be the `filters` element which represents the CompositeFilter. The -`filters` element allows any number of `filter` elements to be -configured within it. The following example shows how multiple filters -can be configured on the ConsoleAppender. -[source,xml] +Java properties:: ++ +[source,properties] ---- - - - - target/test.log - - - - - - - - - - - - - - - - - - %d %p %C{1.} [%t] %m%n - - - - - - - - - - - - - - ${sys:user.name} - - - - - - - - - - - - - - ----- - -[#PropertySubstitution] -== Property Substitution - -Log4j 2 supports the ability to specify tokens in the configuration as -references to properties defined elsewhere. Some of these properties -will be resolved when the configuration file is interpreted while others -may be passed to components where they will be evaluated at runtime. To -accomplish this, Log4j uses variations of -https://commons.apache.org/proper/commons-lang/[Apache Commons Lang]'s -link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrSubstitutor.html[`StrSubstitutor`] -and -link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html[`StrLookup`] -classes. In a manner similar to Ant or Maven, this allows variables -declared as `$\{name}` to be resolved using properties declared in the -configuration itself. For example, the following example shows the -filename for the rolling file appender being declared as a property. +include::example$manual/configuration/properties-recursion.properties[lines=17..-1] +---- +==== + +the `logging.dir` property will be expanded **before** the `logging.file` property, and the expanded value will be substituted in `${logging.dir}/app.log`. +Therefore, the value of the `logging.file` property will be: +* `./logs/app.log` if the environment variable `APP_BASE` is not defined, +* `/var/lib/app/logs/app.log` if the environment variable `APP_BASE` has a value of `/var/lib/app`. + + +===== + +[id=lazy-property-substitution] +==== Lazy property substitution + +For most attributes, property substitution is performed only once at **configuration time**, but there are two categories of exceptions to this rule: + +* Some attributes are **also** evaluated when a component-specific event occurs. +For example +<> +and the `pattern` attribute of the example below are evaluated at each log event, while the `filePattern` attribute of a +xref:manual/appenders.adoc#rollingfileappender[rolling file appender] +is evaluated at each rollover. ++ +In this case: + +** If you want property substitution to happen only once, use one dollar sign, e.g., `${date:HH:mm:ss}`. +** If you want property substitution to happen at each cyclic event, you use two dollar signs, e.g., `$${date:HH:mm:ss}` + +* Other components defer the evaluation of their child components. +In this case, you only need one dollar `$` sign. ++ +This case happens for the children of the `Route` element below: + +[tabs] +==== +XML:: ++ [source,xml] ---- - - - - target/rolling1/rollingtest-$${sd:type}.log - - - - - - - - - - - - - - %d %p %c{1.} [%t] %m%n - - - - - - - - - - - - - - - - - - - - ----- - -While this is useful, there are many more places properties can -originate from. To accommodate this, Log4j also supports the syntax -`${prefix:name}` where the prefix identifies tells Log4j that variable -name should be evaluated in a specific context. See the -xref:manual/lookups.adoc[Lookups] manual page for more details. The contexts -that are built in to Log4j are: - -[cols="1m,5"] -|=== -|Prefix |Context - - - base64 - - Base64 encoded data. The format is ${base64:Base64_encoded_data}. - For example: - ${base64:SGVsbG8gV29ybGQhCg==} yields Hello World!. - - - -|base64 -|Base64 encoded data. The format is `${base64:Base64_encoded_data}`. -For example: `${base64:SGVsbG8gV29ybGQhCg==}` yields `Hello World!`. - -|bundle -|Resource bundle. The format is `${bundle:BundleName:BundleKey}`. -The bundle name follows package naming conventions, for example: -`${bundle:com.domain.Messages:MyKey}`. - -|ctx -|Thread Context Map (MDC) - -|date -|Inserts the current date and/or time using the specified format - -|docker -| Returns attributes from the Docker container the application is running in. The format is ${docker:some.attribute}. See xref:log4j-docker.adoc[Docker documentation] for requirements and a list of available attributes. - -|env -|System environment variables. The formats are `${env:ENV_NAME}` and `${env:ENV_NAME:-default_value}`. - -| event -| Retrieves values from fields within the log event. The format is ${event:some.field}. See the Lookups manual page for a list of available fields. -| java -| Retrieves information about the Java environment the application is running in. The format is ${java:some.property}. See the Lookups manual page for a list of available properties. - -|jndi -|A value set in the default JNDI Context. - -|jvmrunargs -|A JVM input argument accessed through JMX, but not a main argument; see -https://docs.oracle.com/javase/6/docs/api/java/lang/management/RuntimeMXBean.html#getInputArguments--[RuntimeMXBean.getInputArguments()]. -Not available on Android. - -| k8s -| Returns attributes from the Kubernetes environment the application is running in. The format is ${k8s:some.attribute}. See the Lookups manual page for a list of available attributes. - -|log4j -|Log4j configuration properties. The expressions -`${log4j:configLocation}` and `${log4j:configParentLocation}` -respectively provide the absolute path to the log4j configuration file -and its parent folder. - -| lower -| Converts the passed in argument to lower case (usually used with nested lookups). The format is ${lower:argument}. - -|main -|A value set with -../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/MapLookup.html#setMainArguments-java.lang.String:A-[MapLookup.setMainArguments(String[])] - -|map -|A value from a MapMessage - -| marker -| Allows use of markers in configurations. The formats are ${marker:} and ${marker:some.name}. See the Lookups manual page for further details. - -|sd -|A value from a StructuredDataMessage. The key "id" will return the -name of the StructuredDataId without the enterprise number. The key -"type" will return the message type. Other keys will retrieve individual -elements from the Map. - -| spring -| Returns values of Spring properties from the Spring configuration. The format is ${spring:some.property}. See the Lookups manual page for requirements and details. - -|sys -|System properties. The formats are `${sys:some.property}` and -`${sys:some.property:-default_value}`. - -| upper -| Converts the passed in argument to upper case (usually used with nested lookups). The format is ${upper:argument}. -| web -| Returns values of variables associated with the Servlet Context. The format is ${spring:some.key}. See the Lookups manual page for a list of available keys. -|=== +include::example$manual/configuration/routing.xml[tag=appender] +---- -[#DefaultProperties] -== Default Properties -A default property map can be declared in the configuration file by placing a Properties -element directly after the Configuration element and before any Loggers, Filters, -Appenders, etc. are declared. If the value cannot be located in the specified lookup the -value in the default property map will be used. The default map is pre-populated with a value -for "hostName" that is the current system's host name or IP address and -the "contextName" with is the value of the current logging context. See many places -a Properties element is used in this section for examples. - -Default properties may also be specified in the Lookup by using the syntax `${lookupName:key:-defaultValue}`. -In some cases the key might contain a leading '-'. When this is the case an escape character must be -included, such as ``${main:\--file:-app.properties}`. This would use the -`MainMapLookup` for a key named `--file`. If the key is not found then -app.properties would be used as the default value. - -[#EnablingMessagePatternLookups] -== Enabling Message Pattern Lookups -A message is processed (by default) without using lookups, for example if you defined -`FOO_BAR`, then `logger.info("${foo.bar}")` will output `${foo.bar}` instead of `FOO_BAR`. -You could enable message pattern lookups by defining the message pattern using `%m\{lookups}`. - -[#RuntimeLookup] -== Lookup Variables with Multiple Leading '$' Characters - -An interesting feature of StrLookup processing is that when a variable -reference is declared with multiple leading '$' characters each time the -variable is resolved the leading '$' is simply removed. In the previous -example the "Routes" element is capable of resolving the variable at -runtime. To allow this the prefix value is specified as a variable with -two leading '$' characters. When the configuration file is first -processed the first '$' character is simply removed. Thus, when the -Routes element is evaluated at runtime it is the variable declaration -"$\{sd:type}" which causes the event to be inspected for a -StructuredDataMessage and if one is present the value of its type -attribute to be used as the routing key. Not all elements support -resolving variables at runtime. Components that do will specifically -call that out in their documentation. - -If no value is found for the key in the Lookup associated with the -prefix then the value associated with the key in the properties -declaration in the configuration file will be used. If no value is found -the variable declaration will be returned as the value. Default values -may be declared in the configuration by doing: +JSON:: ++ +[source,json] +---- +include::example$manual/configuration/routing.json[tag=appender] +---- -[source,xml] +YAML:: ++ +[source,yaml] +---- +include::example$manual/configuration/routing.yaml[tag=appender] ---- - - - - Audit - - ... - ----- - -_As a footnote, it is worth pointing out that the variables in the -RollingFile appender declaration will also not be evaluated when the -configuration is processed. This is simply because the resolution of the -whole RollingFile element is deferred until a match occurs. See -xref:manual/appenders.adoc#RoutingAppender[RoutingAppender] for more -information._ - -[#Scripts] -== Scripts - -Log4j provides support for -https://docs.oracle.com/javase/6/docs/technotes/guides/scripting/[JSR -223] scripting languages to be used in some of its components. Any -language that provides support for the JSR 223 scripting engine may be -used. A list of the languages and bindings for them can be found at the -https://java.net/projects/scripting/sources/svn/show/trunk/engines[Scripting -Engine] web site. However, some of the languages listed there, such as -JavaScript, Groovy and Beanshell, directly support the JSR 223 scripting -framework and only require that the jars for that language be installed. - -As of Log4j 2.17.2 the languages to be supported must be specified as a comma separated list in the -`log4j2.Script.enableLanguages` system property. - -The components that support using scripts do so by allowing a ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ----- - -If the status attribute on the Configuration element is set to DEBUG the -list of script engines currently installed and their attributes will be -listed. Although some engines may say they are not thread safe, Log4j -takes steps to insure that the scripts will run in a thread-safe manner -if the engine advertises that it is not thread safe. - -.... -2015-09-27 16:13:22,925 main DEBUG Installed script engines -2015-09-27 16:13:22,963 main DEBUG AppleScriptEngine Version: 1.1, Language: AppleScript, Threading: Not Thread Safe, - Compile: false, Names: {AppleScriptEngine, AppleScript, OSA} -2015-09-27 16:13:22,983 main DEBUG Groovy Scripting Engine Version: 2.0, Language: Groovy, Threading: MULTITHREADED, - Compile: true, Names: {groovy, Groovy} -2015-09-27 16:13:23,030 main DEBUG BeanShell Engine Version: 1.0, Language: BeanShell, Threading: MULTITHREADED, - Compile: true, Names: {beanshell, bsh, java} -2015-09-27 16:13:23,039 main DEBUG Mozilla Rhino Version: 1.7 release 3 PRERELEASE, Language: ECMAScript, Threading: MULTITHREADED, - Compile: true, Names: {js, rhino, JavaScript, javascript, ECMAScript, ecmascript} -.... - -When the scripts are executed they will be provided with a set of -variables that should allow them to accomplish whatever task they are -expected to perform. See the documentation for the individual components -for the list of variables that are available to the script. - -The components that support scripting expect a return value to be passed -back to the calling Java code. This is not a problem for several of the -scripting languages, but Javascript does not allow a return statement -unless it is within a function. However, Javascript will return the -value of the last statement executed in the script. As a consequence, -code such as that shown below will result in the desired behavior. - -[source,javascript] ----- -var result; -if (logEvent.getLoggerName().equals("JavascriptNoLocation")) { - result = "NoLocation"; -} else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) { - result = "Flow"; -} -result; +include::example$manual/configuration/routing.properties[tag=appender] ---- +==== -=== A special note on Beanshell +<1> The `pattern` attribute is evaluated at configuration time and also each time a log event is routed. +Therefore, the dollar `$` sign needs to be escaped. +<2> All the attributes inside the `File` element have a **deferred** evaluation, therefore they need only one `$` sign. -JSR 223 scripting engines are supposed to identify that they support the -Compilable interface if they support compiling their scripts. Beanshell -does this. However, whenever the compile method is called it throws an -Error (not an Exception). Log4j catches this but will log the warning -shown below for each Beanshell script when it tries to compile them. All -Beanshell scripts will then be interpreted on each execution. +[id=arbiters] +=== [[Arbiters]] Arbiters -.... -2015-09-27 16:13:23,095 main DEBUG Script BeanShellSelector is compilable -2015-09-27 16:13:23,096 main WARN Error compiling script java.lang.Error: unimplemented - at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:175) - at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:154) - at org.apache.logging.log4j.core.script.ScriptManager$MainScriptRunner.(ScriptManager.java:125) - at org.apache.logging.log4j.core.script.ScriptManager.addScript(ScriptManager.java:94) - -.... +While property substitution allows using the same configuration file in multiple deployment environments, sometimes changing the values of configuration attributes is not enough. -[#XInclude] -== XInclude +Arbiters are to configuration elements what property substitution is for configuration attributes: they allow to conditionally add a subtree of configuration elements to a configuration file. -XML configuration files can include other files with -http://www.xml.com/lpt/a/1009[XInclude]. Here is an example log4j2.xml -file that includes two other files: +Arbiters may occur anywhere an element is allowed in the configuration and can be nested. +So, an Arbiter could encapsulate something as simple as a single property declaration or a whole set of appenders, loggers, or other arbiters. +The child elements of an arbiter must be valid elements for whatever element is the parent of the arbiter. -.log4j2.xml +For a complete list of available arbiters, see +xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-Arbiter[plugin reference]. +In the examples below, we'll use the +xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-DefaultArbiter[DefaultArbiter], +xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-SelectArbiter[Select] +and +xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-SystemPropertyArbiter[SystemPropertyArbiter]. + +For example, you might want to use a different layout in a production and development environment: + +[tabs] +==== +XML:: ++ [source,xml] ---- - - - - xinclude-demo.log - - - - - +include::example$manual/configuration/arbiters.xml[lines=1;18..-1] ---- -.log4j-xinclude-appenders.xml -[source,xml] +JSON:: ++ +[source,json] ---- - - - - - - - - %d %p %C{1.} [%t] %m%n - - - +include::example$manual/configuration/arbiters.json[] ---- -.log4j-xinclude-loggers.xml +YAML:: ++ +[source,yaml] +---- +include::example$manual/configuration/arbiters.yaml[lines=17..-1] +---- + +Java properties:: ++ +[source,properties] +---- +include::example$manual/configuration/arbiters.properties[lines=17..-1] +---- +==== + +<1> If the Java system property `env` has a value of `dev`, a pattern layout will be used. +<2> If the Java system property `env` has a value of `prod`, a JSON template layout will be used. + +The above example has a problem: if the Java system property `env` has a value different from `dev` or `prod`, the appender will have no layout. + +This is a case when the `Select` plugin is useful: this configuration element contains a list of arbiters and a +`DefaultArbiter` element. +If none of the arbiters match, the configuration from the `DefaultArbiter` element will be used: + +[tabs] +==== +XML:: ++ [source,xml] ---- - - - - - - - - +include::example$manual/configuration/arbiters-select.xml[tag=select] +---- - - - +JSON:: ++ +[source,json] +---- +include::example$manual/configuration/arbiters-select.json[tag=select] +---- - - - - +YAML:: ++ +[source,yaml] +---- +include::example$manual/configuration/arbiters-select.yaml[tag=select] ---- +Java properties:: ++ +[source,properties] +---- +include::example$manual/configuration/arbiters-select.properties[tag=select] +---- +==== + +<1> If the Java system property `env` has a value of `dev`, a pattern layout will be used. +<2> Otherwise, a JSON template layout will be used. + [#CompositeConfiguration] -== Composite Configuration - -Log4j allows multiple configuration files to be used by specifying them -as a list of comma separated file paths on log4j2.configurationFile or, -when using URLs, by adding secondary configuration locations as query -parameters named "override". The merge logic can be controlled by specifying -a class that implements the MergeStrategy interface on the log4j.mergeStrategy -property. The default merge strategy will merge the files using the following rules: - -1. The global configuration attributes are aggregated with those in -later configurations replacing those in previous configurations, with -the exception that the highest status level and the lowest -monitorInterval greater than 0 will be used. -2. Properties from all configurations are aggregated. Duplicate -properties replace those in previous configurations. -3. Filters are aggregated under a CompositeFilter if more than one -Filter is defined. Since Filters are not named duplicates may be -present. -4. Scripts and ScriptFile references are aggregated. Duplicate -definitions replace those in previous configurations. -5. Appenders are aggregated. Appenders with the same name are replaced -by those in later configurations, including all of the Appender's -subcomponents. -6. Loggers are all aggregated. Logger attributes are individually -merged with duplicates being replaced by those in later configurations. -Appender references on a Logger are aggregated with duplicates being -replaced by those in later configurations. Filters on a Logger are -aggregated under a CompositeFilter if more than one Filter is defined. -Since Filters are not named duplicates may be present. Filters under -Appender references included or discarded depending on whether their -parent Appender reference is kept or discarded. - -[#StatusMessages] -== Status Messages - -**** -*Troubleshooting tip for the impatient:* - -From log4j-2.9 onward, log4j2 will print all internal logging to the -console if system property `log4j2.debug` is either defined empty or its value -equals to `true` (ignoring case). - -Prior to log4j-2.9, there are two places where internal logging can be -controlled: - -* Before a configuration is found, status logger level can be controlled -with system property -`org.apache.logging.log4j.simplelog.StatusLogger.level`. -* After a configuration is found, status logger level can be controlled -in the configuration file with the "status" attribute, for example: -``. -**** - -Just as it is desirable to be able to diagnose problems in applications, -it is frequently necessary to be able to diagnose problems in the -logging configuration or in the configured components. Since logging has -not been configured, "normal" logging cannot be used during -initialization. In addition, normal logging within appenders could -create infinite recursion which Log4j will detect and cause the -recursive events to be ignored. To accomodate this need, the Log4j 2 API -includes a -link:../javadoc/log4j-api/org/apache/logging/log4j/status/StatusLogger.html[`StatusLogger`]. -Components declare an instance of the StatusLogger similar to: - -[source,java] ----- -protected final static Logger logger = StatusLogger.getLogger(); ----- - -Since StatusLogger implements the Log4j 2 API's Logger interface, all -the normal Logger methods may be used. - -When configuring Log4j it is sometimes necessary to view the generated status events. -This can be accomplished by adding the status attribute to the configuration element or a default value can be provided by setting the xref:statusLoggerLevel["log4j2.statusLoggerLevel"] system property. -Valid values of the status attribute are "trace", "debug", "info", "warn", "error" and "fatal". -The following configuration has the status attribute set to debug. +=== Composite Configuration + +Log4j allows multiple configuration files to be used at the same time by specifying them as a list of comma-separated file paths or URLs in the +xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurationFile] +configuration property. + +These configuration files are merged into a single configuration file using +link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/composite/MergeStrategy.html[MergeStrategy] +service that can be customized using the +xref:manual/systemproperties.adoc#log4j2.mergeStrategy[log4j2.mergeStrategy] +configuration property. + +The default merge strategy will merge the files using the following rules: + +. <> in later configurations replace those in previous configurations. ++ +The exception is the `monitorInterval` attribute: the lowest positive value from all the configuration files will be used. + +. <> from all configurations are aggregated. +Duplicate properties replace those in previous configurations. + +. xref:manual/filters.adoc[Filters] are aggregated under +xref:manual/filters.adoc#CompositeFilter[CompositeFilter], if more than one filter is defined. +. xref:manual/scripts.adoc[] are aggregated. +Duplicate definitions replace those in previous configurations. + +. xref:manual/appenders.adoc[Appenders] are aggregated. +Appenders with the same name are **replaced** by those in later configurations, including all their elements. + +. <> are all aggregated. +Logger attributes are individually merged, and those in later configurations replace duplicates. +Appender references on a logger are aggregated, and those in later configurations replace duplicates. +The strategy merges filters on loggers using the rule above. + +[id=format-specific-notes] +=== Format specific notes + +[id=xml-features] +==== XML format + +[id=xml-global-configuration-attributes] +===== Global configuration attributes + +The XML format supports the following additional attributes on the `Configuration` element. + +[id=configuration-attribute-schema] +====== `schema` + +[cols="1h,5"] +|=== +| Type | classpath resource +| Default value | `null` +|=== + +Specifies the path to a classpath resource containing an XML schema. + +[id=configuration-attribute-strict] +====== `strict` + +[cols="1h,5"] +|=== +| Type | `boolean` +| Default value | `false` +|=== + +If set to `true,` all configuration files will be checked against the XML schema provided by the +<>. + +This setting also enables "XML strict mode" and allows one to specify an element's **plugin type** through a `type` attribute instead of the tag name. + +[id=xinclude] +===== [[XInlcude]] XInclude + +XML configuration files can include other files with +https://www.w3.org/TR/xinclude/[XInclude]. + +NOTE: The list of `XInclude` and `XPath` features supported depends upon your +https://docs.oracle.com/javase/{java-target-version}/docs/technotes/guides/xml/jaxp/index.html[JAXP implementation]. + +Here is an example log4j2.xml file that includes two other files: + +.log4j2.xml [source,xml] ---- - - - - target/rolling1/rollingtest-$${sd:type}.log - - - - - - - - - - - - - - %d %p %c{1.} [%t] %m%n - - - - - - - - - - - - - - - - - - - - ----- - -During startup this configuration produces: - -.... -2011-11-23 17:08:00,769 DEBUG Generated plugins in 0.003374000 seconds -2011-11-23 17:08:00,789 DEBUG Calling createProperty on class org.apache.logging.log4j.core.config.Property for element property with params(name="filename", value="target/rolling1/rollingtest-${sd:type}.log") -2011-11-23 17:08:00,792 DEBUG Calling configureSubstitutor on class org.apache.logging.log4j.core.config.PropertiesPlugin for element properties with params(properties={filename=target/rolling1/rollingtest-${sd:type}.log}) -2011-11-23 17:08:00,794 DEBUG Generated plugins in 0.001362000 seconds -2011-11-23 17:08:00,797 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null") -2011-11-23 17:08:00,800 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%m%n", Configuration(RoutingTest), null, charset="null") -2011-11-23 17:08:00,802 DEBUG Generated plugins in 0.001349000 seconds -2011-11-23 17:08:00,804 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.ConsoleAppender for element Console with params(PatternLayout(%m%n), null, target="null", name="STDOUT", ignoreExceptions="null") -2011-11-23 17:08:00,804 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null") -2011-11-23 17:08:00,813 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="null", key="null", Node=Route) -2011-11-23 17:08:00,823 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="STDOUT", key="Audit", Node=Route) -2011-11-23 17:08:00,825 DEBUG Calling createRoutes on class org.apache.logging.log4j.core.appender.routing.Routes for element Routes with params(pattern="${sd:type}", routes={Route(type=dynamic default), Route(type=static Reference=STDOUT key='Audit')}) -2011-11-23 17:08:00,827 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.routing.RoutingAppender for element Routing with params(name="Routing", ignoreExceptions="null", Routes({Route(type=dynamic default),Route(type=static Reference=STDOUT key='Audit')}), Configuration(RoutingTest), null, null) -2011-11-23 17:08:00,827 DEBUG Calling createAppenders on class org.apache.logging.log4j.core.config.AppendersPlugin for element appenders with params(appenders={STDOUT, Routing}) -2011-11-23 17:08:00,828 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="Routing") -2011-11-23 17:08:00,829 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig for element logger with params(additivity="false", level="info", name="EventLogger", AppenderRef={Routing}, null) -2011-11-23 17:08:00,830 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="STDOUT") -2011-11-23 17:08:00,831 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig$RootLogger for element root with params(additivity="null", level="error", AppenderRef={STDOUT}, null) -2011-11-23 17:08:00,833 DEBUG Calling createLoggers on class org.apache.logging.log4j.core.config.LoggersPlugin for element loggers with params(loggers={EventLogger, root}) -2011-11-23 17:08:00,834 DEBUG Reconfiguration completed -2011-11-23 17:08:00,846 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%d %p %c{1.} [%t] %m%n", Configuration(RoutingTest), null, charset="null") -2011-11-23 17:08:00,849 DEBUG Calling createPolicy on class org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy for element SizeBasedTriggeringPolicy with params(size="500") -2011-11-23 17:08:00,851 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile with params(fileName="target/rolling1/rollingtest-Unknown.log", filePattern="target/rolling1/test1-Unknown.%i.log.gz", append="null", name="Rolling-Unknown", bufferedIO="null", immediateFlush="null", SizeBasedTriggeringPolicy(SizeBasedTriggeringPolicy(size=500)), null, PatternLayout(%d %p %c{1.} [%t] %m%n), null, ignoreExceptions="null") -2011-11-23 17:08:00,858 DEBUG Generated plugins in 0.002014000 seconds -2011-11-23 17:08:00,889 DEBUG Reconfiguration started for context sun.misc.Launcher$AppClassLoader@37b90b39 -2011-11-23 17:08:00,890 DEBUG Generated plugins in 0.001355000 seconds -2011-11-23 17:08:00,959 DEBUG Generated plugins in 0.001239000 seconds -2011-11-23 17:08:00,961 DEBUG Generated plugins in 0.001197000 seconds -2011-11-23 17:08:00,965 WARN No Loggers were configured, using default -2011-11-23 17:08:00,976 DEBUG Reconfiguration completed -.... - -If the status attribute is set to error then only error messages will be -written to the console. This makes troubleshooting configuration errors -possible. As an example, if the configuration above is changed to have -the status set to error and the logger declaration is: +include::example$manual/configuration/xinclude-main.xml[lines=1;18..-1] +---- +.xinclude-appenders.xml [source,xml] ---- - - - +include::example$manual/configuration/xinclude-appenders.xml[lines=1;18..-1] ---- -the following error message will be produced. - -.... -2011-11-24 23:21:25,517 ERROR Unable to locate appender Routng for logger EventLogger -.... - -Applications may wish to direct the status output to some other -destination. This can be accomplished by setting the dest attribute to -either "err" to send the output to stderr or to a file location or URL. -This can also be done by insuring the configured status is set to OFF -and then configuring the application programmatically such as: - -[source,java] +.xinclude-loggers.xml +[source,xml] ---- -StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR); -StatusLogger.getLogger().registerListener(listener); +include::example$manual/configuration/xinclude-loggers.xml[lines=1;18..-1] ---- -[#UnitTestingInMaven] -== Testing in Maven +[id=java-properties-features] +==== Java properties format + +[TIP] +==== +The Java properties format is not well suited to represent hierarchical structures. -Maven can run unit and functional tests during the build cycle. By -default, any files placed in `src/test/resources` are automatically -copied to target/test-classes and are included in the classpath during -execution of any tests. As such, placing a log4j2-test.xml into this -directory will cause it to be used instead of a log4j2.xml or -log4j2.json that might be present. Thus a different log configuration -can be used during testing than what is used in production. +Switch to XML to avoid additional dependencies, or choose YAML for a format similar to Java properties but less verbose. +==== -A second approach, which is extensively used by Log4j 2, is to set the -log4j2.configurationFile property in the method annotated with -@BeforeClass in the junit test class. This will allow an arbitrarily -named file to be used during the test. +The Java properties configuration format is the most verbose of the available formats. +To make it more usable, a series of exceptions to the rules in <> have been introduced over time: -A third approach, also used extensively by Log4j 2, is to use the -`LoggerContextRule` JUnit test rule which provides additional -convenience methods for testing. This requires adding the `log4j-core` -`test-jar` dependency to your test scope dependencies. For example: +. The following direct children of `Configuration` have predefined prefixes and do not require to specify a `type` attribute: +* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-AppendersPlugin[Appender container] has a predefined `appender` prefix. +* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-CustomLevels[Custom levels container] has a predefined `customLevel` prefix. +* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-LoggersPlugin[Loggers container] has a predefined `logger` prefix. +* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-PropertiesPlugin[Properties container] has a predefined `property` prefix. +* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-ScriptsPlugin[Scripts container] has a predefined `script` prefix. -[source,java] +. Properties that start with `property` are used for <>. +Their syntax is: ++ +[source,properties] +---- +property. = ---- -public class AwesomeTest { - @Rule - public LoggerContextRule init = new LoggerContextRule("MyTestConfig.xml"); - @Test - public void testSomeAwesomeFeature() { - final LoggerContext ctx = init.getLoggerContext(); - final Logger logger = init.getLogger("org.apache.logging.log4j.my.awesome.test.logger"); - final Configuration cfg = init.getConfiguration(); - final ListAppender app = init.getListAppender("List"); - logger.warn("Test message"); - final List events = app.getEvents(); - // etc. - } -} +. Properties that start with `customLevel` are used to define custom levels. Their syntax is: ++ +[source,properties] +---- +customLevel. = ---- ++ +where `` is the name of the level and `` its numerical value. + +. The root logger can be configured using properties that start with `rootLogger`. + +. A shorthand notation is available that allows users to write: ++ +[source,properties] +---- +rootLogger = INFO, APPENDER +---- ++ +instead of: ++ +[source,properties] +---- +rootLogger.level = INFO +rootLogger.appenderRef.0.ref = APPENDER +---- + +. All the keys of the form `logger..appenderRef.`, where `` and `` are arbitrary, are considered appender references. -include::_properties.adoc[leveloffset=+1] +. To add a filter to a component use a `filter.` prefix instead of just ``. diff --git a/src/site/antora/modules/ROOT/pages/manual/filters.adoc b/src/site/antora/modules/ROOT/pages/manual/filters.adoc index 1a616f5baf1..d841e27a6b9 100644 --- a/src/site/antora/modules/ROOT/pages/manual/filters.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/filters.adoc @@ -14,39 +14,83 @@ See the License for the specific language governing permissions and limitations under the License. //// +[id=filters] = Filters -Ralph Goers -Volkan Yazıcı - -Filters allow Log Events to be evaluated to determine if or how they -should be published. A Filter will be called on one of its `filter` -methods and will return a `Result`, which is an Enum that has one of 3 -values - `ACCEPT`, `DENY` or `NEUTRAL`. - -Filters may be configured in one of four locations: - -1. Context-wide Filters are configured directly in the configuration. -Events that are rejected by these filters will not be passed to loggers -for further processing. Once an event has been accepted by a -Context-wide filter it will not be evaluated by any other Context-wide -Filters nor will the Logger's Level be used to filter the event. The -event will be evaluated by Logger and Appender Filters however. -2. Logger Filters are configured on a specified Logger. These are -evaluated after the Context-wide Filters and the Log Level for the -Logger. Events that are rejected by these filters will be discarded and -the event will not be passed to a parent Logger regardless of the -additivity setting. -3. Appender Filters are used to determine if a specific Appender should -handle the formatting and publication of the event. -4. Appender Reference Filters are used to determine if a Logger should -route the event to an appender. + +Ralph Goers Volkan Yazıcı + +Log4j supports filtering of log events at each level of the logging pipeline using two features: + +* the `level` attributes that can be set on loggers and appender references, +* filter components that can be attached to loggers, appenders, appender references or the global configuration object. + +Filters evaluate the parameters of a logging call (context-wide filter) or a log event and return one of three results: + +ACCEPT:: The log event is accepted by the filter and goes to the next stage of the logging pipeline, + +DENY:: The log event is unconditionally dropped, + +NEUTRAL:: Log4j behaves as if the filter was not present. + +To decide whether a log event from a certain logger is delivered to a specific appender, the following procedure is followed: + +[tabs] +==== +XML:: ++ +[source,xml] +---- +include::example$manual/filters/filters.xml[lines=1;18..-1] +---- + +JSON:: ++ +[source,json] +---- +include::example$manual/filters/filters.json[] +---- + +YAML:: ++ +[source,yaml] +---- +include::example$manual/filters/filters.yaml[lines=17..-1] +---- + +Java properties:: ++ +[source,properties] +---- +include::example$manual/filters/filters.properties[lines=17..-1] +---- +==== + +<1> First the context-wide filter is consulted. +If it returns `ACCEPT` the log message goes directly to point 3. +<2> Then Log4j checks the message against the configured logger level. +<3> The filter configured on a logger is applied next. +If the logger is additive, the filter on the parent logger is applied recursively until we end up on the logger that references the given appender. +<4> Next comes the turn of the filter configured on an appender reference, +<5> followed by a level check against the configured level of the reference. +<6> The process ends with the filter attached to an appender. + +[CAUTION] +==== +For performance reasons, log events should be filtered as soon as possible in the logging pipeline. +This reduces the costs (formatting, transfer through an asynchronous barrier) of disabled log events. +==== + +[TIP] +==== +Users migrating from Log4j 1 often replace the `threshold` property of a Log4j 1 appender with a <> on the equivalent Log4j 2 appender. + +Using the `level` property of appender references will give a better performance. +==== [#BurstFilter] == BurstFilter -The BurstFilter provides a mechanism to control the rate at which -LogEvents are processed by silently discarding events after the maximum -limit has been reached. +The BurstFilter provides a mechanism to control the rate at which LogEvents are processed by silently discarding events after the maximum limit has been reached. .Burst Filter Parameters [cols="1m,1,4"] @@ -72,12 +116,12 @@ times the rate. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -108,9 +152,9 @@ A configuration containing the BurstFilter might look like: [#CompositeFilter] == CompositeFilter -The CompositeFilter provides a way to specify more than one filter. It -is added to the configuration as a filters element and contains other -filters to be evaluated. The filters element accepts no parameters. +The CompositeFilter provides a way to specify more than one filter. +It is added to the configuration as a filter element and contains other filters to be evaluated. +The filter element accepts no parameters. A configuration containing the CompositeFilter might look like: @@ -154,11 +198,9 @@ A configuration containing the CompositeFilter might look like: [#DynamicThresholdFilter] == DynamicThresholdFilter -The DynamicThresholdFilter allows filtering by log level based on -specific attributes. For example, if the user's loginId is being -captured in the ThreadContext Map then it is possible to enable debug -logging for only that user. If the log event does not contain the -specified ThreadContext item NEUTRAL will be returned. +The DynamicThresholdFilter allows filtering by log level based on specific attributes. +For example, if the user's loginId is being captured in the ThreadContext Map then it is possible to enable debug logging for only that user. +If the log event does not contain the specified ThreadContext item NEUTRAL will be returned. .Dynamic Threshold Filter Parameters [cols="1m,1,4"] @@ -173,7 +215,7 @@ specified ThreadContext item NEUTRAL will be returned. |String |Level of messages to be filtered. The default threshold only applies if the log event contains the specified -ThreadContext Map item and its value does not match any key in the +ThreadContext Map item and its value do not match any key in the key/value pairs. |keyValuePair @@ -184,12 +226,12 @@ key matches. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -273,8 +315,7 @@ The filter will return `onMismatch` result (i.e., `DENY`, the default) for log e [#MapFilter] == MapFilter -The MapFilter allows filtering against data elements that are in a -MapMessage. +The MapFilter allows filtering against data elements that are in a MapMessage. .Map Filter Parameters [cols="1m,1,4"] @@ -284,7 +325,7 @@ MapMessage. |keyValuePair |KeyValuePair[] |One or more KeyValuePair elements that -define the key in the map and the value to match on. If the same key is +define the key in the map and the value to match. If the same key is specified more than once then the check for that key will automatically be an "or" since a Map can only contain a single value. @@ -296,17 +337,16 @@ key/value pairs must match. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -As in this configuration, the MapFilter can be used to log particular -events: +As in this configuration, the MapFilter can be used to log particular events: [source,xml] ---- @@ -334,8 +374,7 @@ events: ---- -This sample configuration will exhibit the same behavior as the -preceding example since the only logger configured is the root. +This sample configuration will exhibit the same behavior as the preceding example since the only logger configured is the root. [source,xml] ---- @@ -364,9 +403,7 @@ preceding example since the only logger configured is the root. ---- -This third sample configuration will exhibit the same behavior as the -preceding examples since the only logger configured is the root and the -root is only configured with a single appender reference. +This third sample configuration will exhibit the same behavior as the preceding examples since the only logger configured is the root and the root is only configured with a single appender reference. [source,xml] ---- @@ -398,9 +435,8 @@ root is only configured with a single appender reference. [#MarkerFilter] == MarkerFilter -The MarkerFilter compares the configured Marker value against the Marker -that is included in the LogEvent. A match occurs when the Marker name -matches either the Log Event's Marker or one of its parents. +The MarkerFilter compares the configured Marker value against the Marker that is included in the LogEvent. +A match occurs when the Marker name matches either the Log Event's Marker or one of its parents. .Marker Filter Parameters [cols="1m,1,4"] @@ -413,17 +449,16 @@ matches either the Log Event's Marker or one of its parents. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -A sample configuration that only allows the event to be written by the -appender if the Marker matches: +A sample configuration that only allows the event to be written by the appender if the Marker matches: [source,xml] ---- @@ -450,7 +485,9 @@ appender if the Marker matches: [#MutableThreadContextMapFilter] == MutableThreadContextMapFilter -The MutableThreadContextMapFilter or MutableContextMapFilter allows filtering against data elements that are in the current context. By default this is the ThreadContext Map. The values to compare are defined externally and can be periodically polled for changes. +The MutableThreadContextMapFilter or MutableContextMapFilter allows filtering against data elements that are in the current context. +By default, this is the ThreadContext Map. +The values to compare are defined externally and can be periodically polled for changes. .Mutable Context Map Filter Parameters [cols="1m,1,4"] @@ -469,21 +506,20 @@ key/value pairs must match. |pollInterval |int -|The number of seconds to wait before checking to see if the configuration has been modified. When using HTTP or HTTPS the server must support the If-Modified-Since header and return a Last-Modified header containing the date and time the file was last modified. Note that by default only the https, file, and jar protocols are allowed. Support for other protocols can be enabled by specifying them in the log4j2.Configuration.allowedProtocols system property +|The number of seconds to wait before checking to see if the configuration has been modified. When using HTTP or HTTPS the server must support the If-Modified-Since header and return a Last-Modified header containing the date and time the file was last modified. Note that by default only the https, file, and jar protocols are allowed. Support for other protocols can be enabled by specifying them in the `log4j2.Configuration.allowedProtocols` system property |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -A sample configuration that only allows the event to be written by the -appender if the Marker matches: +A sample configuration that only allows the event to be written by the appender if the Marker matches: [source,xml] ---- @@ -509,6 +545,7 @@ appender if the Marker matches: ---- The configuration file supplied to the filter should look similar to: + [source,json] ---- { @@ -522,8 +559,8 @@ The configuration file supplied to the filter should look similar to: [#NoMarkerFilter] == NoMarkerFilter -The NoMarkerFilter checks that there is no marker included in the LogEvent. A match occurs when there is no -marker in the Log Event. +The NoMarkerFilter checks that there is no marker included in the LogEvent. +A match occurs when there is no marker in the Log Event. .No Marker Filter Parameters [cols="1m,1,3"] @@ -532,17 +569,16 @@ marker in the Log Event. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -A sample configuration that only allows the event to be written by the -appender if no marker is there: +A sample configuration that only allows the event to be written by the appender if no marker is there: [source,xml] ---- @@ -569,8 +605,7 @@ appender if no marker is there: [#RegexFilter] == RegexFilter -The RegexFilter allows the formatted or unformatted message to be -compared against a regular expression. +The RegexFilter allows the formatted or unformatted message to be compared against a regular expression. .Regex Filter Parameters [cols="1m,1,4"] @@ -584,22 +619,21 @@ compared against a regular expression. |useRawMsg |boolean |If true the unformatted message will be used, -otherwise the formatted message will be used. The default value is +otherwise, the formatted message will be used. The default value is false. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -A sample configuration that only allows the event to be written by the -appender if it contains the word "test": +A sample configuration that only allows the event to be written by the appender if it contains the word "test": [source,xml] ---- @@ -624,7 +658,6 @@ appender if it contains the word "test": ---- [[Script]] - The ScriptFilter executes a script that returns true or false. .Script Filter Parameters @@ -638,12 +671,12 @@ The ScriptFilter executes a script that returns true or false. |onMatch |String -|Action to take when the script returns true. May be +|Action to take when the script returns true. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter returns false. May +|Action to take when the filter returns false. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -696,14 +729,12 @@ Throwable as part of the Message. |substitutor |StrSubstitutor -|The StrSubstitutor used to replace lookup variables. +|The StrSubstitutor is used to replace lookup variables. |=== -The sample below shows how to declare script fields and then reference -them in specific components. See -xref:manual/appenders.adoc#ScriptCondition[ScriptCondition] for an example of -how the `ScriptPlugin` element can be used to embed script code directly in -the configuration. +The sample below shows how to declare script fields and then reference them in specific components. +See +xref:manual/appenders.adoc#ScriptCondition[ScriptCondition] for an example of how the `ScriptPlugin` element can be used to embed script code directly in the configuration. [source,xml] ---- @@ -744,8 +775,7 @@ the configuration. [#StructuredDataFilter] == StructuredDataFilter -The StructuredDataFilter is a MapFilter that also allows filtering on -the event id, type and message. +The StructuredDataFilter is a MapFilter that also allows filtering on the event id, type and message. .StructuredData Filter Parameters [cols="1m,1,4"] @@ -756,7 +786,7 @@ the event id, type and message. |KeyValuePair[] |One or more KeyValuePair elements that define the key in the map and the value to match on. "id", "id.name", -"type", and "message" should be used to match on the StructuredDataId, +"type", and "message" should be used to match the StructuredDataId, the name portion of the StructuredDataId, the type, and the formatted message respectively. If the same key is specified more than once then the check for that key will automatically be an "or" since a Map can @@ -770,17 +800,16 @@ key/value pairs must match. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -As in this configuration, the StructuredDataFilter can be used to log -particular events: +As in this configuration, the StructuredDataFilter can be used to log particular events: [source,xml] ---- @@ -811,9 +840,8 @@ particular events: [#ThreadContextMapFilter] == ThreadContextMapFilter -The ThreadContextMapFilter or ContextMapFilter allows filtering against -data elements that are in the current context. By default this is the -ThreadContext Map. +The ThreadContextMapFilter or ContextMapFilter allows filtering against data elements that are in the current context. +By default, this is the ThreadContext Map. .Context Map Filter Parameters [cols="1m,1,4"] @@ -823,7 +851,7 @@ ThreadContext Map. |keyValuePair |KeyValuePair[] |One or more KeyValuePair elements that -define the key in the map and the value to match on. If the same key is +define the key in the map and the value to match. If the same key is specified more than once then the check for that key will automatically be an "or" since a Map can only contain a single value. @@ -835,12 +863,12 @@ key/value pairs must match. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -904,10 +932,9 @@ The ContextMapFilter can also be applied to a logger for filtering: [#ThresholdFilter] == ThresholdFilter -This filter returns the onMatch result if the level in the LogEvent is -the same or more specific than the configured level and the onMismatch -value otherwise. For example, if the ThresholdFilter is configured with -Level ERROR and the LogEvent contains Level DEBUG then the onMismatch +This filter returns the onMatch result if the level in the LogEvent is the same or more specific than the configured level and the `onMismatch` +value otherwise. +For example, if the ThresholdFilter is configured with Level ERROR and the LogEvent contains Level DEBUG then the `onMismatch` value will be returned since ERROR events are more specific than DEBUG. .Threshold Filter Parameters @@ -917,21 +944,20 @@ value will be returned since ERROR events are more specific than DEBUG. |level |String -|A valid Level name to match on. +|A valid Level name to match. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -A sample configuration that only allows the event to be written by the -appender if the level matches: +A sample configuration that only allows the event to be written by the appender if the level matches: [source,xml] ---- @@ -958,8 +984,7 @@ appender if the level matches: [#TimeFilter] == TimeFilter -The time filter can be used to restrict filter to only a certain portion -of the day. +The time filter can be used to restrict the filter to only a certain portion of the day. .Time Filter Parameters [cols="1m,1,4"] @@ -982,17 +1007,16 @@ timestamp. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -A sample configuration that only allows the event to be written by the -appender from 5:00 to 5:30 am each day using the default timezone: +A sample configuration that only allows the event to be written by the appender from 5:00 to 5:30 am each day using the default timezone: [source,xml] ---- diff --git a/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc b/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc index 220a49fc4ef..3393c21a3a1 100644 --- a/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc @@ -32,14 +32,14 @@ many systems significant effort is spent on controlling these pauses. Many logging libraries, including previous versions of Log4j, allocate temporary objects like log event objects, Strings, char arrays, byte -arrays and more during steady state logging. This contributes to +arrays and more during steady-state logging. This contributes to pressure on the garbage collector and increases the frequency with which GC pauses occur. -From version 2.6, Log4j runs in "garbage free" mode by default where +From version 2.6, Log4j runs in "garbage-free" mode by default where objects and buffers are reused and no temporary objects are allocated as much as possible. There is also a "low garbage" mode which is not -completely garbage free but does not use ThreadLocal fields. This is the +completely garbage-free but does not use ThreadLocal fields. This is the default mode when Log4j link:#Config[detects] it is running in a web application. Finally, it is possible to switch off all garbage-free logic and run in "classic mode" instead. For details, see the @@ -82,7 +82,7 @@ reference these fields after the web application is undeployed. To avoid causing memory leaks, Log4j will not use these ThreadLocals when it detects that it is used in a web application (when the `javax.servlet.Servlet` class is in the classpath, or when system -property xref:manual/configuration.adoc#log4j2.isWebapp[log4j2.isWebapp] is set to `true`). +property xref:manual/systemproperties.adoc#log4j2.isWebapp[log4j2.isWebapp] is set to `true`). Some garbage-reducing functionality does not rely on ThreadLocals and is enabled by default for all applications: in Log4j 2.6, converting log @@ -112,8 +112,8 @@ you may also configure a xref:manual/async.adoc#WaitStrategy[custom wait strateg There are separate system properties for manually controlling the mechanisms Log4j uses to avoid creating temporary objects: -* xref:manual/configuration.adoc#log4j2.enableThreadlocals[log4j2.enableThreadlocals] - if "true" (the default for non-web applications) objects are stored in ThreadLocal fields and reused, otherwise new objects are created for each log event. -* xref:manual/configuration.adoc#log4j2.enableDirectEncoders[log4j2.enableDirectEncoders] - if "true" (the default) +* xref:manual/systemproperties.adoc#log4j2.enableThreadlocals[log4j2.enableThreadlocals] - if "true" (the default for non-web applications) objects are stored in ThreadLocal fields and reused, otherwise new objects are created for each log event. +* xref:manual/systemproperties.adoc#log4j2.enableDirectEncoders[log4j2.enableDirectEncoders] - if "true" (the default) log events are converted to text and this text is converted to bytes without creating temporary objects. Note: _synchronous_ logging performance may be worse @@ -121,8 +121,8 @@ for multi-threaded applications in this mode due to synchronization on the shared buffer. If your application is multi-threaded and logging performance is important, consider using Async Loggers. * The ThreadContext map is _not_ garbage-free by default, but from Log4j -2.7 it can be configured to be garbage-free by setting system property -xref:manual/configuration.adoc#log4j2.garbagefreeThreadContextMap[log4j2.garbagefreeThreadContextMap] to "true". +2.7 it can be configured to be garbage-free by setting the system property +xref:manual/systemproperties.adoc#log4j2.garbagefreeThreadContextMap[log4j2.garbagefreeThreadContextMap] to "true". Instead of system properties, the above properties can also be specified in a file named `log4j2.component.properties` by including this file in @@ -158,16 +158,16 @@ steady-state logging: * CompositeFilter (adding and removing element filters creates temporary objects for thread safety) * DynamicThresholdFilter -* LevelRangeFilter (garbage free since 2.8) -* MapFilter (garbage free since 2.8) -* MarkerFilter (garbage free since 2.8) -* StructuredDataFilter (garbage free since 2.8) -* ThreadContextMapFilter (garbage free since 2.8) -* ThresholdFilter (garbage free since 2.8) -* TimeFilter (garbage free since 2.8 except when range must be recalculated once per day) +* LevelRangeFilter (garbage-free since 2.8) +* MapFilter (garbage-free since 2.8) +* MarkerFilter (garbage-free since 2.8) +* StructuredDataFilter (garbage-free since 2.8) +* ThreadContextMapFilter (garbage-free since 2.8) +* ThresholdFilter (garbage-free since 2.8) +* TimeFilter (garbage-free since 2.8 except when range must be recalculated once per day) Other filters like BurstFilter, RegexFilter and ScriptFilter are not -trivial to make garbage free, and there is currently no plan to change +trivial to make garbage-free, and there is currently no plan to change them. [#Layouts] @@ -186,7 +186,7 @@ xref:manual/json-template-layout.adoc#faq-garbage-free[a few exceptions]. PatternLayout with the following limited set of conversion patterns is garbage-free. Format modifiers to control such things as field width, -padding, left and right justification will not generate garbage. +padding, and left and right justification will not generate garbage. [cols="1m,2"] |=== @@ -198,7 +198,7 @@ padding, left and right justification will not generate garbage. |%d, %date a| Note: Only the predefined date formats are garbage-free: (millisecond -separator may be either a comma ',' or a period '.') +the separator may be either a comma ',' or a period '.') [cols="1m,1"] !=== @@ -248,11 +248,11 @@ garbage-free since 2.8 %equalsIgnoreCase\{pattern}\{test}\{substitution} |Replaces occurrences of 'test', a string, with its replacement 'substitution' in the string -resulting from evaluation of the pattern - garbage-free since 2.8 +resulting from the evaluation of the pattern - garbage-free since 2.8 |%highlight\{pattern}\{style} |Adds ANSI colors - garbage-free since 2.7 -(unless nested pattern is not garbage free) +(unless the nested pattern is not garbage-free) |%K\{key}, %map\{key}, %MAP\{key} |Outputs the entries in a @@ -272,11 +272,11 @@ since 2.8 parents) |%maxLen, %maxLength -|Truncates another pattern to some max number of +|Truncates another pattern to some maximum number of characters - garbage-free since 2.8 |%n -|The platform dependent line separator +|The platform-dependent line separator |%N, %nano |System.nanoTime() when the event was logged @@ -300,7 +300,7 @@ every event - garbage-free since 2.8 |%style\{pattern}{ANSI style} |Style the message - garbage-free since -2.7 (unless nested pattern is not garbage free) +2.7 (unless the nested pattern is not garbage-free) |%T, %tid, %threadId |The ID of the thread that generated the logging @@ -324,13 +324,13 @@ garbage-free since 2.8 substitution) |=== -Other PatternLayout conversion patterns, and other Layouts may be +Other PatternLayout conversion patterns and other Layouts may be updated to avoid creating temporary objects in future releases. (Patches welcome!) NOTE: Logging exceptions and stack traces will create temporary objects with any layout. (However, Layouts will only create these -temporary objects when an exception actually occurs.) We haven't figured +temporary objects when an exception occurs.) We haven't figured out a way to log exceptions and stack traces without creating temporary objects. That is unfortunate, but you probably still want to log them when they happen. @@ -393,10 +393,10 @@ not possible. When logging primitive values (i.e. int, double, boolean, etc.) the JVM autoboxes these primitive values to their Object wrapper equivalents, creating garbage. -Log4j provides an `Unbox` utility to prevent autoboxing of primitive +Log4j provides an `Unbox` utility to prevent the autoboxing of primitive parameters. This utility contains a thread-local pool of reused `StringBuilder`s. The `Unbox.box(primitive)` methods write directly into -a StringBuilder, and the resulting text will be copied into the final +a `StringBuilder`, and the resulting text will be copied into the final log message text without creating temporary objects. [source,java] @@ -410,16 +410,16 @@ public void garbageFree() { ---- **** -NOTE: not all logging is garbage free. Specifically: +NOTE: not all logging is garbage-free. Specifically: -* The ThreadContext map is not garbage-free by default, but can be -configured to be garbage-free by setting system property +* The ThreadContext map is not garbage-free by default but can be +configured to be garbage-free by setting the system property `log4j2.garbagefreeThreadContextMap` to "true". * The ThreadContext stack is not garbage-free. * Logging more than 10 parameters creates vararg arrays. * Logging very large messages (more than 518 characters) when all loggers are Async Loggers will cause the internal StringBuilder in the -RingBuffer to be trimmed back to their max size. +RingBuffer is to be trimmed back to its max size. * Logging messages containing '${': substituting a `$\{variable}` creates temporary objects. * Logging a lambda _as a parameter_ @@ -428,7 +428,7 @@ creates a vararg array. Logging a lambda expression by itself is garbage-free: `logger.debug(() -> callExpensiveMethod())`. * The `Logger.traceEntry` and `Logger.traceExit` methods create temporary objects. -* Time calculations are not garbage free when log4j2.usePreciseClock is set to true. +* Time calculations are not garbage-free when log4j2.usePreciseClock is set to true. The default is false. **** @@ -439,12 +439,12 @@ The default is false. === Response Time Latency Response time is how long it takes to log a message under a certain -load. What is often reported as latency is actually _service time_: how -long it took to perform the operation. This hides the fact that a single -spike in service time adds queueing delay for many of the subsequent +load. What is often reported as latency is _service time_: how +long it took to operate. This hides the fact that a single +spike in service time adds a queueing delay for many of the subsequent operations. Service time is easy to measure (and often looks good on paper) but is irrelevant for users since it omits the time spent waiting -for service. For this reason we report response time: service time plus +for service. For this reason, we report response time: service time plus wait time. See the xref:manual/performance.adoc#responseTime[response time section] of the performance page for more detail. @@ -462,25 +462,25 @@ wait strategy reduces some jitter.) * -XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle * -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationConcurrentTime --XX:+PrintGCApplicationStoppedTime (to eyeball GC and safepoint pauses) +-XX:+PrintGCApplicationStoppedTime (to eyeball GC and savepoint pauses) === Async Loggers The graph below compares "classic" logging to garbage-free logging -response time behaviour for Log4j's Async Loggers. In the graph, "100k" -means logging at a sustained load of 100,000 messages/second, "800k" is +response time behavior for Log4j's Async Loggers. In the graph, "100k" +means logging at a sustained load of 100,000 messages/second, and "800k" is a sustained load of 800,000 messages/second. image:ResponseTimeAsyncClassicVsGcFree-label.png[image] -In *classic* mode we see numerous minor garbage collections which pause +In *classic* mode we see numerous minor garbage collections that pause the application threads for 3 milliseconds or more. This quickly adds up to response time delays of almost 10 milliseconds. As you can see in the graph, increasing the load shifts the curve to the left (there are more spikes). This makes sense: logging more means more pressure on the garbage collector resulting in more minor GC pauses. We experimented a little with reducing the load to 50,000 or even 5000 messages/second, -but this did not eliminate the 3 millisecond pauses, it just made them +but this did not eliminate the 3-millisecond pauses, it just made them occur less frequently. Note that all GC pauses in this test are minor GC pauses. We did not see any full garbage collections. @@ -488,19 +488,19 @@ In *garbage-free* mode, maximum response time remains well below 1 millisecond under a wide range of loads. (Max 780 us at 800,000 messages/sec, max 407 us at 600,000 messages/sec, with the 99% around 5 us for all loads up to 800,000 messages/sec.) Increasing or decreasing -the load does not change the response time behaviour. We did not +the load does not change the response time behavior. We did not investigate the cause of the 200-300 microsecond pauses we saw in these tests. -When we increased the load further we begin to see larger response time +When we increased the load further we began to see larger response time pauses for both classic and garbage-free logging. At sustained loads of 1 million messages/second or more we start to approach the maximum throughput of the underlying RandomAccessFile Appender (see the -synchronous logging throughput chart below). At these loads the -ringbuffer starts to fill up and backpressure kicks in: attempting to +synchronous logging throughput chart below). At these loads, the +ringbuffer starts to fill up and backpressure kicks in, attempting to add another message when the ringbuffer is full will block until a free slot becomes available. We start to see response times of tens of -milliseconds or more; and attempting to increase the load even more +milliseconds or more, and attempting to increase the load even more results in larger and larger response time spikes. === Synchronous File Logging @@ -509,11 +509,11 @@ With synchronous file logging, garbage-free logging still performs better than classic logging, but the difference is less pronounced. At a workload of 100,000 messages/second, classic logging max response -time was a little over 2 milliseconds where garbage-free logging was a +time was a little over 2 milliseconds whereas garbage-free logging was a little over 1 millisecond. When the workload is increased to 300,000 messages/second, classic logging shows response time pauses of 6 milliseconds where the garbage-free response times were less than 3 -milliseconds. It may be possible to improve on this, we did not +milliseconds. It may be possible to improve on this, but we did not investigate further yet. image:ResponseTimeSyncClassicVsGcFree.png[image] @@ -535,7 +535,7 @@ classic mode and Log4j 2.5. image:garbage-free2.6-SyncThroughputLinux.png[Throughput of Log4j 2.6 in garbage-free mode is slightly worse than in classic mode, -but on par with 2.5 and much better than alternatives logging libraries] +but on par with 2.5 and much better than alternative logging libraries] The results above are obtained with the http://openjdk.java.net/projects/code-tools/jmh/[JMH] Java benchmark @@ -564,12 +564,11 @@ directly write into. `AbstractOutputStreamAppender` has been modified to make the ConsoleAppender, (Rolling)FileAppender, (Rolling)RandomAccessFileAppender and MemoryMappedFileAppender -garbage-free. An effort has been made to minimize impact on custom +garbage-free. An effort has been made to minimize the impact on custom Appenders that extend `AbstractOutputStreamAppender`, but it is -impossible to guarantee that changing the superclass will not impact any -and all subclasses. Custom Appenders that extend +impossible to guarantee that changing the superclass will not impact any subclasses. Custom Appenders that extend `AbstractOutputStreamAppender` should verify that they still function -correctly. In case there is a problem, system property +correctly. In case there is a problem, the system property `log4j2.enable.direct.encoders` can be set to "false" to revert to the pre-Log4j 2.6 behaviour. diff --git a/src/site/antora/modules/ROOT/pages/manual/installation.adoc b/src/site/antora/modules/ROOT/pages/manual/installation.adoc index 5ced130c91a..cf84dac6c76 100644 --- a/src/site/antora/modules/ROOT/pages/manual/installation.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/installation.adoc @@ -33,7 +33,7 @@ Below we share some shortcuts for the impatient. [WARNING] ==== -We strongly advise you to skim through this page to get a grip on fundamental logging concepts and understand which recipe fits to your bill best. +We strongly advise you to skim through this page to get a grip on fundamental logging concepts and understand which recipe fits your bill best. ==== Are you a library developer?:: @@ -262,7 +262,7 @@ implementation 'org.apache.logging.log4j:log4j-api' [#impl] == Installing a logging implementation -Log4j provides several modules to facilitate deployment of different logging implementations: +Log4j provides several modules to facilitate the deployment of different logging implementations: `log4j-core`:: The reference implementation. @@ -280,7 +280,7 @@ https://logback.qos.ch/[Logback] implements SLF4J natively, refer to < While xref:manual/layouts.adoc#PatternLayout[Pattern Layout] is a good first choice and preferable for tests, we recommend using a structured format such as xref:manual/json-template-layout.adoc[] for production deployments. -In order to use these formats, the following additional dependencies are required: +To use these formats, the following additional dependencies are required: -[tabs] -==== - -Maven:: -+ -[tabs] -===== - -log4j2.xml:: -+ -No dependency required. - -log4j2.json:: -+ -[source,xml,subs="+attributes"] ----- - - com.fasterxml.jackson.core - jackson-databind - {jackson-version} - runtime - ----- - -log4j2.yaml:: -+ -[source,xml,subs="+attributes"] ----- - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - {jackson-version} - runtime - ----- - -log4j2.properties:: -+ -No dependency required. - -===== - -Gradle:: -+ -[tabs] -===== - -log4j2.xml:: -+ -No dependency required. - -log4j2.json:: -+ -[source,groovy,subs="+attributes"] ----- -runtimeOnly 'com.fasterxml.jackson.core:jackson-databind:{jackson-version}' ----- - -log4j2.yaml:: -+ -[source,groovy,subs="+attributes"] ----- -runtimeOnly 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:{jackson-version}' ----- - -log4j2.properties:: -+ -No dependency required. - -===== -==== +include::partial$configuration-file-format-deps.adoc[] [#impl-jul] === Installing JUL diff --git a/src/site/antora/modules/ROOT/pages/manual/jmx.adoc b/src/site/antora/modules/ROOT/pages/manual/jmx.adoc index a5439324f61..43dba1504fa 100644 --- a/src/site/antora/modules/ROOT/pages/manual/jmx.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/jmx.adoc @@ -34,18 +34,23 @@ JMX support is disabled by default. NOTE: JMX support was enabled by default in Log4j 2 versions before 2.24.0. -To enable JMX support, set the following system property when starting the Java VM: +To enable JMX support, set the +xref:manual/systemproperties.adoc#log4j2.disableJmx[log4j2.disableJmx] +system property when starting the Java VM: -`xref:manual/configuration.adoc#log4j2.disableJmx[log4j2.disableJmx]=false` +`log4j2.disableJmx=false` [#Local] == Local Monitoring and Management -To perform local monitoring you need to specify the `xref:manual/configuration.adoc#log4j2.disableJmx[log4j2.disableJmx]=false` system -property. The JConsole tool that is included in the Java JDK can be +To perform local monitoring you need to set the +xref:manual/systemproperties.adoc#log4j2.disableJmx[log4j2 +.disableJmx] +system property to `false`. +The JConsole tool that is included in the Java JDK can be used to monitor your application. Start JConsole by typing `$JAVA_HOME/bin/jconsole` in a command shell. For more details, -see Oracle's documentation on +see Oracle's documentation at https://docs.oracle.com/javase/7/docs/technotes/guides/management/jconsole.html[how to use JConsole]. @@ -55,7 +60,7 @@ to use JConsole]. To enable monitoring and management from remote systems, set the following two system properties when starting the Java VM: -`xref:manual/configuration.adoc#log4j2.disableJmx[log4j2.disableJmx]=false` +`log4j2.disableJmx=false` and @@ -64,7 +69,7 @@ and In the property above, `portNum` is the port number through which you want to enable JMX RMI connections. -For more details, see Oracle's documentation on +For more details, see Oracle's documentation at https://docs.oracle.com/javase/7/docs/technotes/guides/management/agent.html#gdenl[Remote Monitoring and Management]. @@ -78,7 +83,7 @@ documentation] for the `sun.rmi.dgc.server.gcInterval` and properties is 3600000 milliseconds (one hour). Before Java 6, it was one minute. -The two sun.rmi arguments reflect whether your JVM is running in server +The two `sun.rmi` arguments reflect whether your JVM is running in server or client mode. If you want to modify the GC interval time it may be best to specify both properties to ensure the argument is picked up by the JVM. diff --git a/src/site/antora/modules/ROOT/pages/manual/layouts.adoc b/src/site/antora/modules/ROOT/pages/manual/layouts.adoc index 87ee914bea9..a890f45049b 100644 --- a/src/site/antora/modules/ROOT/pages/manual/layouts.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/layouts.adoc @@ -17,25 +17,39 @@ = Layouts Ralph Goers ; Gary Gregory ; Volkan Yazıcı -An Appender uses a Layout to format a LogEvent into a form that meets -the needs of whatever will be consuming the log event. In Log4j 1.x and -Logback Layouts were expected to transform an event into a String. In -Log4j 2 Layouts return a byte array. This allows the result of the -Layout to be useful in many more types of Appenders. However, this means -you need to configure most Layouts with a +An Appender uses a Layout to format a LogEvent into a form that meets the needs of whatever will be consuming the log event. +In Log4j 1.x and Logback Layouts were expected to transform an event into a String. +In Log4j 2 Layouts return a byte array. +This allows the result of the Layout to be useful in many more types of Appenders. +However, this means you need to configure most Layouts with a https://docs.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html[`Charset`] to ensure the byte array contains correct values. The root class for layouts that use a Charset is -`org.apache.logging.log4j.core.layout.AbstractStringLayout` where the -default is UTF-8. Each layout that extends `AbstractStringLayout` can -provide its own default. See each layout below. +`org.apache.logging.log4j.core.layout.AbstractStringLayout` where the default is UTF-8. Each layout that extends `AbstractStringLayout` can provide its own default. +See each layout below. -A custom character encoder was added to Log4j 2.4.1 for the ISO-8859-1 -and US-ASCII charsets, to bring some of the performance improvements -built-in to Java 8 to Log4j for use on Java 7. For applications that log -only ISO-8859-1 characters, specifying this charset will improve -performance significantly. +A custom character encoder was added to Log4j 2.4.1 for the ISO-8859-1 and US-ASCII charsets, to bring some of the performance improvements built-in to Java 8 to Log4j for use on Java 7. For applications that log only ISO-8859-1 characters, specifying this charset will improve performance significantly. + +[#common-concerns] +== Common concerns + +[#location-information] +=== Location information + +Computing the location information of a logging statement is an expensive operation. +For this reason many Log4j components implement the +link:../javadoc/log4j-core/org/apache/logging/log4j/core/impl/LocationAware.html[LocationAware] +interface to only compute location information when needed. + +While the methods of determining if location information is required are specific to each layout, most layouts implement `LocationAware`. + +[NOTE] +==== +Even if a layout is configured not to **request** location information, it might use it if the information is already available. +This is always the case of information location computed at build time using the +link:/log4j/transform/latest/#log4j-transform-maven-plugin[Log4j Transform Maven Plugin]. +==== [#CSVLayouts] == CSV Layouts @@ -49,15 +63,11 @@ Value (CSV)] records and requires https://commons.apache.org/proper/commons-csv/[Apache Commons CSV] 1.4. The CSV layout can be used in two ways: First, using -`CsvParameterLayout` to log event parameters to create a custom -database, usually to a logger and file appender uniquely configured for -this purpose. Second, using `CsvLogEventLayout` to log events to create -a database, as an alternative to using a full DBMS or using a JDBC -driver that supports the CSV format. +`CsvParameterLayout` to log event parameters to create a custom database, usually to a logger and file appender uniquely configured for this purpose. +Second, using `CsvLogEventLayout` to log events to create a database, as an alternative to using a full DBMS or using a JDBC driver that supports the CSV format. -The `CsvParameterLayout` converts an event's parameters into a CSV -record, ignoring the message. To log CSV records, you can use the usual -Logger methods `info()`, `debug()`, and so on: +The `CsvParameterLayout` converts an event's parameters into a CSV record, ignoring the message. +To log CSV records, you can use the usual Logger methods `info()`, `debug()`, and so on: [source,java] ---- @@ -70,16 +80,14 @@ Which will create the CSV record: value1, value2, value3 .... -Alternatively, you can use a `ObjectArrayMessage`, which only carries -parameters: +Alternatively, you can use an `ObjectArrayMessage`, which only carries parameters: [source,java] ---- logger.info(new ObjectArrayMessage(value1, value2, value3)); ---- -The layouts `CsvParameterLayout` and `CsvLogEventLayout` are configured -with the following parameters: +The layouts `CsvParameterLayout` and `CsvLogEventLayout` are configured with the following parameters: .CsvParameterLayout and CsvLogEventLayout [cols="1m,1,4"] @@ -131,7 +139,7 @@ specified value. One of: `ALL`, `MINIMAL`, `NON_NUMERIC`, `NONE`. |Desc. |=== -Logging as a CSV events looks like this: +Logging as a CSV event looks like this: [source,java] ---- @@ -140,15 +148,15 @@ logger.debug("one={}, two={}, three={}", 1, 2, 3); Produces a CSV record with the following fields: -1. Time Nanos -2. Time Millis -3. Level -4. Thread ID -5. Thread Name -6. Thread Priority -7. Formatted Message -8. Logger FQCN -9. Logger Name +1. Time Nanos +2. Time Millis +3. Level +4. Thread ID +5. Thread Name +6. Thread Priority +7. Formatted Message +8. Logger FQCN +9. Logger Name 10. Marker 11. Thrown Proxy 12. Source @@ -159,15 +167,15 @@ Produces a CSV record with the following fields: 0,1441617184044,DEBUG,main,"one=1, two=2, three=3",org.apache.logging.log4j.spi.AbstractLogger,,,,org.apache.logging.log4j.core.layout.CsvLogEventLayoutTest.testLayout(CsvLogEventLayoutTest.java:98),{},[] .... -Additional xref:runtime-dependencies.adoc[runtime dependencies] are -required for using CSV layouts. +Additional xref:runtime-dependencies.adoc[runtime dependencies] are required for using CSV layouts. [#GELFLayout] == GELF Layout Lays out events in the Graylog Extended Log Format (GELF) 1.1. -This layout compresses JSON to GZIP or ZLIB (`compressionType`) if log event data is larger than 1024 bytes (`compressionThreshold`). This layout does not implement chunking. +This layout compresses JSON to GZIP or ZLIB (`compressionType`) if log event data is larger than 1024 bytes (`compressionThreshold`). +This layout does not implement chunking. Configure as follows to send to a Graylog 2.x server with UDP: @@ -223,18 +231,17 @@ To include any custom field in the output, use following syntax: ---- -Custom fields are included in the order they are declared. The values support xref:manual/lookups.adoc[lookups]. +Custom fields are included in the order they are declared. +The values support xref:manual/lookups.adoc[lookups]. See also: * The https://docs.graylog.org/en/latest/pages/gelf.html#gelf[GELF specification] - [#HTMLLayout] == HTML Layout -The HtmlLayout generates an HTML page and adds each LogEvent to a row in -a table. +The HtmlLayout generates an HTML page and adds each LogEvent to a row in a table. .HtmlLayout Parameters [cols="1m,1,4"] @@ -273,7 +280,7 @@ expensive operation and may impact performance. Use with caution. |fontSize |String -|The `font-size` to use. The default is "small". +|The `font size` to use. The default is "small". |datePattern |String @@ -281,12 +288,13 @@ expensive operation and may impact performance. Use with caution. |timezone |String -|The timezone id of the logging event. If not specified, this layout uses the https://docs.oracle.com/javase/6/docs/api/java/util/TimeZone.html#getDefault()[java.util.TimeZone.getDefault] as default timezone. Like link:#PatternDate[date pattern] of PatternLayout, you can use timezone id from +|The timezone id of the logging event. If not specified, this layout uses the https://docs.oracle.com/javase/6/docs/api/java/util/TimeZone.html#getDefault()[java.util.TimeZone.getDefault] as the default timezone. Like link:#PatternDate[date pattern] of PatternLayout, you can use the timezone id from https://docs.oracle.com/javase/6/docs/api/java/util/TimeZone.html#getTimeZone(java.lang.String)[java.util.TimeZone.getTimeZone]. |=== -Configure as follows to use dataPattern and timezone in HtmlLayout: +Configure as follows to use `dataPattern` and timezone in `HtmlLayout`: + [source,xml] ---- @@ -299,13 +307,15 @@ Configure as follows to use dataPattern and timezone in HtmlLayout: [[JSONLayout]] == JSON Layout -NOTE: JsonTemplate is considered deprecated. JsonTemplateLayout provides more capabilities and should be used instead. +NOTE: JsonTemplate is considered deprecated. +JsonTemplateLayout provides more capabilities and should be used instead. Appends a series of JSON events as strings serialized as bytes. === Complete well-formed JSON vs. fragment JSON -If you configure `complete="true"`, the appender outputs a well-formed JSON document. By default, with `complete="false"`, you should include the output as an _external file_ in a separate file to form a well-formed JSON document. +If you configure `complete="true"`, the appender outputs a well-formed JSON document. +By default, with `complete="false"`, you should include the output as an _external file_ in a separate file to form a well-formed JSON document. If `complete="false"`, the appender does not write the JSON open array character "[" at the start of the document, "]" at the end, nor comma "," between records. @@ -371,7 +381,10 @@ Log event follows this pattern: === Pretty vs. compact JSON -The compact attribute determines whether the output will be "pretty" or not. The default value is "false", which means the appender uses end-of-line characters and indents lines to format the text. If `compact="true"`, then no end-of-line or indentation is used, which will cause the output to take less space. Of course, the message content may contain, escaped end-of-lines. +The compact attribute determines whether the output will be "pretty" or not. +The default value is "false", which means the appender uses end-of-line characters and indent lines to format the text. +If `compact="true"`, then no end-of-line or indentation is used, which will cause the output to take less space. +Of course, the message content may contain, escaped end-of-lines. [options="header"] |=== @@ -391,7 +404,7 @@ The compact attribute determines whether the output will be "pretty" or not. The | objectMessageAsJsonObject | boolean | If true, ObjectMessage is serialized as JSON object to the "message" field of the output log. Defaults to false. |=== -To include any custom field in the output, use following syntax: +To include any custom field in the output, use the following syntax: [source,xml] ---- @@ -401,18 +414,17 @@ To include any custom field in the output, use following syntax: ---- -Custom fields are always last, in the order they are declared. The values support xref:manual/lookups.adoc[lookups]. +Custom fields are always last, in the order they are declared. +The values support xref:manual/lookups.adoc[lookups]. Additional xref:runtime-dependencies.adoc[runtime dependencies] are required for using JsonLayout. - [#JSONTemplateLayout] == JSON Template Layout -`JsonTemplateLayout` is a customizable, efficient, and garbage-free JSON -emitting layout. It encodes ``LogEvent``s according to the structure described -by the JSON template provided. For instance, given the following JSON template -modelling https://github.com/logstash/log4j-jsonevent-layout[the official +`JsonTemplateLayout` is a customizable, efficient, and garbage-free JSON-emitting layout. +It encodes ``LogEvent``s according to the structure described by the JSON template provided. +For instance, given the following JSON template modelling https://github.com/logstash/log4j-jsonevent-layout[the official Logstash `JSONEventLayoutV1`] [source,json] @@ -509,33 +521,28 @@ JSON Template Layout will render JSON documents as follows: } ---- -See xref:manual/json-template-layout.adoc[JSON Template Layout] page for the complete -documentation. +See xref:manual/json-template-layout.adoc[JSON Template Layout] page for the complete documentation. -[#PatternLayout] -== Pattern Layout +[id=pattern-layout] +== [[PatternLayout]] Pattern Layout -A flexible layout configurable with pattern string. The goal of this -class is to format a LogEvent and return the results. The format of the -result depends on the _conversion pattern_. +A flexible layout is configurable with a pattern string. +The goal of this class is to format a LogEvent and return the results. +The format of the result depends on the _conversion pattern_. -The conversion pattern is closely related to the conversion pattern of -the printf function in C. A conversion pattern is composed of literal -text and format control expressions called _conversion specifiers_. +The conversion pattern is closely related to the conversion pattern of the `printf()` function in C. A conversion pattern is composed of literal text and format control expressions called _conversion specifiers_. -_Note that any literal text, including *Special Characters*, may be -included in the conversion pattern._ Special Characters include *\t*, -*\n*, *\r*, *\f*. Use *\\* to insert a single backslash into the output. +_Note that any literal text, including *Special Characters*, may be included in the conversion pattern._ Special Characters include *\t*, +*\n*, *\r*, *\f*. +Use *\\* to insert a single backslash into the output. -Each conversion specifier starts with a percent sign (%) and is followed -by optional _format modifiers_ and a _conversion character_. The -conversion character specifies the type of data, e.g. category, -priority, date, thread name. The format modifiers control such things as -field width, padding, left and right justification. The following is a -simple example. +Each conversion specifier starts with a percent sign (%) and is followed by optional _format modifiers_ and a _conversion character_. +The conversion character specifies the type of data, e.g. category, priority, date, thread name. +The format modifiers control such things as field width, padding, and left and right justification. +The following is a simple example. -Let the conversion pattern be *"%-5p [%t]: %m%n"* and assume that the -Log4j environment was set to use a PatternLayout. Then the statements +Let the conversion pattern be *"%-5p [%t]: %m%n"* and assume that the Log4j environment was set to use a PatternLayout. +Then the statements .... Logger logger = LogManager.getLogger("MyLogger"); @@ -550,17 +557,12 @@ DEBUG [main]: Message 1 WARN [main]: Message 2 .... -Note that there is no explicit separator between text and conversion -specifiers. The pattern parser knows when it has reached the end of a -conversion specifier when it reads a conversion character. In the -example above the conversion specifier `%-5p` means the priority of the -logging event should be left justified to a width of five characters. +Note that there is no explicit separator between text and conversion specifiers. +The pattern parser knows when it has reached the end of a conversion specifier when it reads a conversion character. +In the example above the conversion specifier `%-5p` means the priority of the logging event should be left justified to a width of five characters. -If the pattern string does not contain a specifier to handle a Throwable -being logged, parsing of the pattern will act as if the `%xEx` specifier -had be added to the end of the string. To suppress formatting of the -Throwable completely simply add `%ex\{0}` as a specifier in the pattern -string. +If the pattern string does not contain a specifier to handle a Throwable being logged, parsing of the pattern will act as if the `%xEx` specifier had been added to the end of the string. +To suppress the formatting of the Throwable completely simply add `%ex\{0}` as a specifier in the pattern string. .PatternLayout Parameters [cols="1m,1,4"] @@ -632,7 +634,7 @@ escape codes. |regex |String -|A Java-compliant regular expression to match in the resulting string. See +|A Java-compliant regular expression to match the resulting string. See https://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html[Pattern]. |replacement @@ -658,7 +660,7 @@ with a decimal integer. When the precision specifier is an integer value, it reduces the size of the logger name. If the number is positive, the layout prints the -corresponding number of rightmost logger name components. If negative, +corresponding number of the rightmost logger name components. If negative, the layout removes the corresponding number of leftmost logger name components. If the precision contains periods then the number before the first period identifies the length to be printed from items that precede tokens in the rest of the pattern. @@ -824,7 +826,7 @@ You can define custom date formats: `%d\{UNIX}` outputs the UNIX time in seconds. `%d\{UNIX_MILLIS}` outputs the UNIX time in milliseconds. The UNIX time is the difference, in seconds -for UNIX and in milliseconds for UNIX_MILLIS, between the current time +for UNIX and milliseconds for UNIX_MILLIS, between the current time and midnight, January 1, 1970 UTC. While the time unit is milliseconds, the granularity depends on the operating system (http://msdn.microsoft.com/en-us/windows/hardware/gg463266.aspx[Windows]). @@ -835,11 +837,11 @@ involved. Log4j 2.11 adds limited support for timestamps more precise than milliseconds when running on Java 9. Note that not all https://docs.oracle.com/javase/9/docs/api/java/time/format/DateTimeFormatter.html[DateTimeFormatter] -formats are supported. Only timestamps in the formats mentioned in the -table above may use the "nano-of-second" pattern letter `n` instead of +formats are supported. Only timestamps in the formats mentioned in the table +above may use the "nano-of-second" pattern letter `n` instead of the "fraction-of-second" pattern letter `S`. -Users may revert back to a millisecond-precision clock when running on +Users may revert to a millisecond-precision clock when running on Java 9 by setting system property `log4j2.Clock` to `SystemMillisClock`. |*enc*\{pattern}{[HTML\|XML\|JSON\|CRLF]} + @@ -847,9 +849,8 @@ Java 9 by setting system property `log4j2.Clock` to `SystemMillisClock`. |Encodes and escapes special characters suitable for output in specific markup languages. By default, this encodes for HTML if only one option is specified. The second option is used to specify which encoding format -should be used. This converter is particularly useful for encoding user -provided data so that the output data is not written improperly or -insecurely. +should be used. This converter is particularly useful for encoding user-provided +data so that the output data is not written improperly or insecurely. A typical usage would encode the message `%enc{%m}` but user input could come from other locations as well, such as the MDC `%enc{%mdc\{key}}` @@ -911,9 +912,9 @@ Using the CRLF encoding format, the following characters are replaced: |*equals*\{pattern}\{test}\{substitution} + *equalsIgnoreCase*\{pattern}\{test}\{substitution} |Replaces occurrences of 'test', a string, with its replacement -'substitution' in the string resulting from evaluation of the pattern. +'substitution' in the string resulting from the evaluation of the pattern. For example, "%equals{[%marker]}{[]}\{}" will replace '[]' strings -produces by events without markers with an empty string. +produced by events without markers with an empty string. The pattern can be arbitrarily complex and in particular can contain multiple conversion keywords. @@ -968,7 +969,7 @@ Use `{filters(packages)}` where _packages_ is a list of package names to suppress matching stack frames from stack traces. Use `{suffix(pattern)}` to add the output of _pattern_ at the end of -each stack frames. +each stack frame. Use a `{separator(...)}` as the end-of-line string. For example: `separator(\|)`. The default value is the `line.separator` system @@ -1014,8 +1015,7 @@ The color names are ANSI names defined in the link:../javadoc/log4j-core/org/apache/logging/log4j/core/pattern/AnsiEscape.html[`AnsiEscape`] class. -The color and attribute names and are standard, but the exact shade, -hue, or value. +The color and attribute names are standard, but the exact shade, hue, or value. .Color table !=== @@ -1039,14 +1039,13 @@ example: %highlight{%d [%t] %-5level: %msg%n%throwable}{FATAL=white, ERROR=red, WARN=blue, INFO=black, DEBUG=green, TRACE=blue} .... -You can highlight only the a portion of the log event: +You can highlight only the portion of the log event: .... %d [%t] %highlight{%-5level: %msg%n%throwable} .... -You can style one part of the message and highlight the rest the log -event: +You can style one part of the message and highlight the rest of the log event: .... %style{%d [%t]}{black} %highlight{%-5level: %msg%n%throwable} @@ -1085,16 +1084,16 @@ The STYLE value can be one of: link:../javadoc/log4j-api/org/apache/logging/log4j/message/MapMessage.html[MapMessage], if one is present in the event. The `K` conversion character can be followed by the key for the map placed between braces, as in -`%K\{clientNumber}` where `clientNumber` is the key. The value in the -Map corresponding to the key will be output. If no additional sub-option -is specified, then the entire contents of the Map key value pair set is +`%K\{clientNumber}` where `clientNumber` is the key. The value of the Map +corresponding to the key will be output. If no additional sub-option +is specified, then the entire contents of the Map key-value pair set is output using a format {{key1,val1},{key2,val2}} |[[PatternLocation]] *l* + *location* -|Outputs location information of the caller which generated the logging event. +|Outputs location information of the caller which generates the logging event. -The location information depends on the JVM implementation but usually +The location information depends on the JVM implementation but it usually consists of the fully qualified name of the calling method followed by the callers source the file name and line number between parentheses. @@ -1112,7 +1111,7 @@ with caution. |[[PatternMessage]] *m*\{lookups}\{ansi} + *msg*\{lookups}\{ansi} + *message\{lookups}\{ansi} -|Outputs the application supplied message associated with the logging +|Outputs the application-supplied message associated with the logging event. Add `\{ansi}` to render messages with ANSI escape codes (requires JAnsi, @@ -1192,7 +1191,7 @@ example: `%maxLen{%m}\{20}` will be limited to 20 characters and no trailing ellipsis. |[[PatternNewLine]] *n* -|Outputs the platform dependent line separator character or characters. +|Outputs the platform-dependent line separator character or characters. This conversion character offers practically the same performance as using non-portable line separator strings such as "\n", or "\r\n". Thus, @@ -1200,8 +1199,7 @@ it is the preferred way of specifying a line separator. |[[NanoTime]] *N* + *nano* -|Outputs the result of `System.nanoTime()` at the time the log -event was created. +|Outputs the result of `System.nanoTime()` at the time the log event was created. |[[Process_ID]] *pid*{[defaultValue]} + *processId*{[defaultValue]} @@ -1225,7 +1223,7 @@ For example: ...} **p**\|*level*{length=_n_} **p**\|*level*{lowerCase=__true__\|_false_} |Outputs the level of the logging event. You provide a level name map in -the form "level=value, level=value" where level is the name of the Level +the form "level=value, level=value" where the level is the name of the Level and value is the value that should be displayed instead of the name of the Level. @@ -1257,11 +1255,10 @@ You can combine the two kinds of options: %level{ERROR=Error, length=2} .... -This give you the `Error` level name and all other level names of length +This gives you the `Error` level name and all other level names of length 2. -Finally, you can output lower-case level names (the default is -upper-case): +Finally, you can output lower-case level names (the default is upper-case): .... %level{lowerCase=true} @@ -1279,11 +1276,11 @@ For example, "%repeat{\*}\{2}" will result in the string "**". |[[PatternReplace]] *replace*\{pattern}\{regex}\{substitution} |Replaces occurrences of 'regex', a regular expression, with its -replacement 'substitution' in the string resulting from evaluation of +replacement 'substitution' in the string resulting from the evaluation of the pattern. For example, "%replace{%msg}{\s}\{}" will remove all spaces contained in the event message. -The pattern can be arbitrarily complex and in particular can contain +The pattern can be arbitrarily complex and in particular, can contain multiple conversion keywords. For instance, "%replace{%logger %msg}{\.}{/}" will replace all dots in the logger or the message of the event with a forward slash. @@ -1329,7 +1326,7 @@ within applications that share the same converter Class object. |[[PatternStyle]] *style*\{pattern}{ANSI style} |Uses ANSI escape sequences to style the result of the enclosed pattern. -The style can consist of a comma separated list of style names from the +The style can consist of a comma-separated list of style names from the following table. (See Jansi link:#enable-jansi[configuration].) !=== @@ -1357,55 +1354,55 @@ following table. (See Jansi link:#enable-jansi[configuration].) ! !Black or FG_Black -!Set foreground color to black +!Set the foreground color to black !Red or FG_Red -!Set foreground color to red +!Set the foreground color to red !Green or FG_Green -!Set foreground color to green +!Set the foreground color to green !Yellow or FG_Yellow -!Set foreground color to yellow +!Set the foreground color to yellow !Blue or FG_Blue -!Set foreground color to blue +!Set the foreground color to blue !Magenta or FG_Magenta -!Set foreground color to magenta +!Set the foreground color to magenta !Cyan or FG_Cyan -!Set foreground color to cyan +!Set the foreground color to cyan !White or FG_White -!Set foreground color to white +!Set the foreground color to white !Default or FG_Default -!Set foreground color to default (white) +!Set the foreground color to default (white) !BG_Black -!Set background color to black +!Set the background color to black !BG_Red -!Set background color to red +!Set the background color to red !BG_Green -!Set background color to green +!Set the background color to green !BG_Yellow -!Set background color to yellow +!Set the background color to yellow !BG_Blue -!Set background color to blue +!Set the background color to blue !BG_Magenta -!Set background color to magenta +!Set the background color to magenta !BG_Cyan -!Set background color to cyan +!Set the background color to cyan !BG_White -!Set background color to white +!Set the background color to white !=== For example: @@ -1464,14 +1461,14 @@ for the map placed between braces, as in *%X\{clientNumber}* where `clientNumber` is the key. The value in the MDC corresponding to the key will be output. -If a list of keys are provided, such as *%X{name, number}*, then each +If a list of keys is provided, such as *%X{name, number}*, then each key that is present in the ThreadContext will be output using the format {name=val1, number=val2}. The key/value pairs will be printed in the order they appear in the list. -If no sub-options are specified then the entire contents of the MDC key -value pair set is output using a format {key1=val1, key2=val2}. The -key/value pairs will be printed in sorted order. +If no sub-options are specified then the entire contents of the MDC key-value pair +set is output using a format {key1=val1, key2=val2}. +The key/value pairs will be printed in sorted order. See the link:../javadoc/log4j-api/org/apache/logging/log4j/ThreadContext.html[ThreadContext] @@ -1480,10 +1477,10 @@ class for more details. |[[PatternUUID]] *u*{"RANDOM" \| "TIME"} + *uuid* |Includes either a random or a time-based UUID. The time-based -UUID is a Type 1 UUID that can generate up to 10,000 unique ids per -millisecond, will use the MAC address of each host, and to try to insure -uniqueness across multiple JVMs and/or ClassLoaders on the same host a -random number between 0 and 16,384 will be associated with each instance +UUID is a Type 1 UUID that can generate up to 10,000 unique IDs per +millisecond will use the MAC address of each host, and to try to insure +uniqueness across multiple JVMs and/or ClassLoaders on the same host +a random number between 0 and 16,384 will be associated with each instance of the UUID generator Class and included in each time-based UUID generated. Because time-based UUIDs contain the MAC address and timestamp they should be used with care as they can cause a security @@ -1524,9 +1521,9 @@ Use a `separator` string to separate the lines of a stack trace. For example: `separator(\|)`. The default value is the `line.separator` system property, which is operating system dependent. -The `ansi` option renders stack traces with ANSI escapes code using the +The `ansi` option renders stack traces with ANSI escape code using the JAnsi library. (See link:#enable-jansi[configuration].) Use `\{ansi}` to -use the default color mapping. You can specify your own mappings with +use the default color mapping. You can specify your mappings with `key=value` pairs. The keys are: * Prefix @@ -1568,41 +1565,31 @@ print. |The sequence %% outputs a single percent sign. |=== -By default the relevant information is output as is. However, with the -aid of format modifiers it is possible to change the minimum field -width, the maximum field width and justification. +By default, the relevant information is output as is. +However, with the aid of format modifiers it is possible to change the minimum field width, the maximum field width and justification. -The optional format modifier is placed between the percent sign and the -conversion character. +The optional format modifier is placed between the percent sign and the conversion character. The first optional format modifier is the _left justification flag_ -which is just the minus (-) character. Then comes the optional _minimum -field width_ modifier. This is a decimal constant that represents the -minimum number of characters to output. If the data item requires fewer -characters, it is padded on either the left or the right until the -minimum width is reached. The default is to pad on the left (right -justify) but you can specify right padding with the left justification -flag. The padding character is space. If the data item is larger than -the minimum field width, the field is expanded to accommodate the data. -The value is never truncated. To use zeros as the padding character prepend -the _minimum field width_ with a zero. - -This behavior can be changed using the _maximum field width_ modifier -which is designated by a period followed by a decimal constant. If the -data item is longer than the maximum field, then the extra characters -are removed from the _beginning_ of the data item and not from the end. -For example, it the maximum field width is eight and the data item is -ten characters long, then the first two characters of the data item are -dropped. This behavior deviates from the printf function in C where -truncation is done from the end. - -Truncation from the end is possible by appending a minus character right -after the period. In that case, if the maximum field width is eight and -the data item is ten characters long, then the last two characters of -the data item are dropped. - -Below are various format modifier examples for the category conversion -specifier. +which is just the minus (-) character. +Then comes the optional _minimum field width_ modifier. +This is a decimal constant that represents the minimum number of characters to output. +If the data item requires fewer characters, it is padded on either the left or the right until the minimum width is reached. +The default is to pad on the left (right justify) but you can specify right padding with the left justification flag. +The padding character is space. +If the data item is larger than the minimum field width, the field is expanded to accommodate the data. +The value is never truncated. +To use zeros as the padding character prepend the _minimum field width_ with a zero. + +This behavior can be changed using the _maximum field width_ modifier which is designated by a period followed by a decimal constant. +If the data item is longer than the maximum field, then the extra characters are removed from the _beginning_ of the data item and not from the end. +For example, if the maximum field width is eight and the data item is ten characters long, then the first two characters of the data item are dropped. +This behavior deviates from the `printf()` function in C where truncation is done from the end. + +Truncation from the end is possible by appending a minus character right after the period. +In that case, if the maximum field width is eight and the data item is ten characters long, then the last two characters of the data item are dropped. + +Below are various format modifier examples for the category conversion specifier. .Pattern Converters |=== @@ -1626,15 +1613,14 @@ less than 20 characters long. |NA |none |30 -|Truncate from the beginning if the category name -is longer than 30 characters. +|Truncate from the beginning if the category name is longer than 30 characters. |%20.30c |false |20 |30 |Left pad with spaces if the category name is -shorter than 20 characters. However, if category name is longer than 30 +shorter than 20 characters. However, if the category name is longer than 30 characters, then truncate from the beginning. |%-20.30c @@ -1642,7 +1628,7 @@ characters, then truncate from the beginning. |20 |30 |Right pad with spaces if the category name is -shorter than 20 characters. However, if category name is longer than 30 +shorter than 20 characters. However, if the category name is longer than 30 characters, then truncate from the beginning. |%-20.-30c @@ -1650,32 +1636,28 @@ characters, then truncate from the beginning. |20 |30 |Right pad with spaces if the category name is -shorter than 20 characters. However, if category name is longer than 30 +shorter than 20 characters. However, if the category name is longer than 30 characters, then truncate from the end. |=== [#enable-jansi] === ANSI Styling on Windows -ANSI escape sequences are supported natively on many platforms but are -not by default on Windows. To enable ANSI support add the -http://jansi.fusesource.org/[Jansi] jar to your application and set -property `log4j.skipJansi` to `false`. This allows Log4j to use Jansi to -add ANSI escape codes when writing to the console. +ANSI escape sequences are supported natively on many platforms but are not by default on Windows. +To enable ANSI support add the +http://jansi.fusesource.org/[Jansi] jar to your application and set property `log4j.skipJansi` to `false`. +This allows Log4j to use Jansi to add ANSI escape codes when writing to the console. -NOTE: Prior to Log4j 2.10, Jansi was enabled by default. The fact that -Jansi requires native code means that Jansi can only be loaded by a -single class loader. For web applications this means the Jansi jar has -to be in the web container's classpath. To avoid causing problems for -web applications, Log4j will no longer automatically try to load Jansi -without explicit configuration from Log4j 2.10 onward. +NOTE: Before Log4j 2.10, Jansi was enabled by default. +The fact that Jansi requires native code means that Jansi can only be loaded by a single class loader. +For web applications, this means the Jansi jar has to be in the web container's classpath. +To avoid causing problems for web applications, Log4j will no longer automatically try to load Jansi without explicit configuration from Log4j 2.10 onward. === Example Patterns ==== Filtered Throwables -This example shows how to filter out classes from unimportant packages -in stack traces. +This example shows how to filter out classes from unimportant packages in stack traces. [source,xml] ---- @@ -1716,20 +1698,14 @@ All the content that follows the level will be bright green. [#PatternSelectors] === Pattern Selectors -The PatternLayout can be configured with a PatternSelector to allow it -to choose a pattern to use based on attributes of the log event or other -factors. A PatternSelector will normally be configured with a -defaultPattern attribute, which is used when other criteria don't match, -and a set of PatternMatch elements that identify the various patterns -that can be selected. +The PatternLayout can be configured with a PatternSelector to allow it to choose a pattern to use based on attributes of the log event or other factors. +A PatternSelector will normally be configured with a defaultPattern attribute, which is used when other criteria don't match, and a set of PatternMatch elements that identify the various patterns that can be selected. [#LevelPatternSelector] ==== LevelPatternSelector -The LevelPatternSelector selects patterns based on the log level of -the log event. If the Level in the log event is equal to (ignoring case) - the name specified on the PatternMatch key attribute, then -the pattern specified on that PatternMatch element will be used. +The LevelPatternSelector selects patterns based on the log level of the log event. +If the Level in the log event is equal to (ignoring case) the name specified on the PatternMatch key attribute, then the pattern specified on that PatternMatch element will be used. [source,xml] ---- @@ -1743,10 +1719,8 @@ the pattern specified on that PatternMatch element will be used. [#MarkerPatternSelector] ==== MarkerPatternSelector -The MarkerPatternSelector selects patterns based on the Marker included -in the log event. If the Marker in the log event is equal to or is an -ancestor of the name specified on the PatternMatch key attribute, then -the pattern specified on that PatternMatch element will be used. +The MarkerPatternSelector selects patterns based on the Marker included in the log event. +If the Marker in the log event is equal to or is an ancestor of the name specified on the PatternMatch key attribute, then the pattern specified on that PatternMatch element will be used. [source,xml] ---- @@ -1760,14 +1734,9 @@ the pattern specified on that PatternMatch element will be used. [#ScriptPatternSelector] ==== ScriptPatternSelector -The ScriptPatternSelector executes a script as descibed in the -xref:manual/configuration.adoc#Scripts[Scripts] section of the Configuration -chapter. The script is passed all the properties configured in the -Properties section of the configuration, the StrSubstitutor used by the -Confguration in the "substitutor" variables, and the log event in the -"logEvent" variable, and is expected to return the value of the -PatternMatch key that should be used, or null if the default pattern -should be used. +The ScriptPatternSelector executes a script as described in the +xref:manual/configuration.adoc#Scripts[Scripts] section of the Configuration chapter. +The script is passed all the properties configured in the Properties section of the configuration, the StrSubstitutor used by the Configuration in the "substitutor" variables, and the log event in the "logEvent" variable, and is expected to return the value of the PatternMatch key that should be used, or null if the default pattern should be used. [source,xml] ---- @@ -1791,12 +1760,8 @@ should be used. [#RFC5424Layout] == RFC5424 Layout -As the name implies, the Rfc5424Layout formats LogEvents in accordance -with http://tools.ietf.org/html/rfc5424[RFC 5424], the enhanced Syslog -specification. Although the specification is primarily directed at -sending messages via Syslog, this format is quite useful for other -purposes since items are passed in the message as self-describing -key/value pairs. +As the name implies, the Rfc5424Layout formats LogEvents by http://tools.ietf.org/html/rfc5424[RFC 5424], the enhanced Syslog specification. +Although the specification is primarily directed at sending messages via Syslog, this format is quite useful for other purposes since items are passed in the message as self-describing key/value pairs. .Rfc5424Layout Parameters [cols="1m,1,4"] @@ -1811,7 +1776,7 @@ syslog record. |charset |String |The character set to use when converting the syslog -String to a byte array. The String must be a valid +String to a byte array. The String must be valid http://docs.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html[Charset]. If not specified, the default system Charset will be used. @@ -1835,21 +1800,20 @@ The facility option must be set to one of "KERN", "USER", "MAIL", "DAEMON", "AUTH", "SYSLOG", "LPR", "NEWS", "UUCP", "CRON", "AUTHPRIV", "FTP", "NTP", "AUDIT", "ALERT", "CLOCK", "LOCAL0", "LOCAL1", "LOCAL2", "LOCAL3", "LOCAL4", "LOCAL5", "LOCAL6", or "LOCAL7". These values may be -specified as upper or lower case characters. +specified as upper or lowercase characters. |format |String -|If set to "RFC5424" the data will be formatted in -accordance with RFC 5424. Otherwise, it will be formatted as a BSD +|If set to "RFC5424" the data will be formatted by RFC 5424. +Otherwise, it will be formatted as a BSD Syslog record. Note that although BSD Syslog records are required to be 1024 bytes or shorter the SyslogLayout does not truncate them. The RFC5424Layout also does not truncate records since the receiver must -accept records of up to 2048 bytes and may accept records that are -longer. +accept records of up to 2048 bytes and may accept longer records. |id |String -|The default structured data id to use when formatting +|The default structured data-id to use when formatting according to RFC 5424. If the LogEvent contains a StructuredDataMessage the id from the Message will be used instead of this value. @@ -1870,29 +1834,28 @@ which specifies the PatternLayout pattern to use as the value. |mdcExcludes |String -|A comma separated list of mdc keys that should be +|A comma-separated list of mdc keys that should be excluded from the LogEvent. This is mutually exclusive with the mdcIncludes attribute. This attribute only applies to RFC 5424 syslog records. |mdcIncludes |String -|A comma separated list of mdc keys that should be +|A comma-separated list of mdc keys that should be included in the FlumeEvent. Any keys in the MDC not found in the list will be excluded. This option is mutually exclusive with the mdcExcludes attribute. This attribute only applies to RFC 5424 syslog records. |mdcRequired |String -|A comma separated list of mdc keys that must be +|A comma-separated list of mdc keys that must be present in the MDC. If a key is not present a LoggingException will be thrown. This attribute only applies to RFC 5424 syslog records. |mdcPrefix |String -|A string that should be prepended to each MDC key in -order to distinguish it from event attributes. The default string is -"mdc:". This attribute only applies to RFC 5424 syslog records. +|A string that should be prepended to each MDC key to distinguish it from event attributes. +The default string is "mdc:". This attribute only applies to RFC 5424 syslog records. |mdcId |String @@ -1914,18 +1877,15 @@ order to distinguish it from event attributes. The default string is [#SerializedLayout] == Serialized Layout -The SerializedLayout simply serializes the LogEvent into a byte array -using Java Serialization. The SerializedLayout accepts no parameters. +The SerializedLayout simply serializes the LogEvent into a byte array using Java Serialization. +The SerializedLayout accepts no parameters. -This layout is deprecated since version 2.9. Java Serialization has -inherent security weaknesses, using this layout is no longer -recommended. +This layout has been deprecated since version 2.9. Java Serialization has inherent security weaknesses, using this layout is no longer recommended. [#SyslogLayout] == Syslog Layout -The SyslogLayout formats the LogEvent as BSD Syslog records matching the -same format used by Log4j 1.2. +The SyslogLayout formats the LogEvent as BSD Syslog records matching the the same format used by Log4j 1.2. .SyslogLayout Parameters [cols="1m,1,4"] @@ -1946,7 +1906,7 @@ The facility option must be set to one of "KERN", "USER", "MAIL", "DAEMON", "AUTH", "SYSLOG", "LPR", "NEWS", "UUCP", "CRON", "AUTHPRIV", "FTP", "NTP", "AUDIT", "ALERT", "CLOCK", "LOCAL0", "LOCAL1", "LOCAL2", "LOCAL3", "LOCAL4", "LOCAL5", "LOCAL6", or "LOCAL7". These values may be -specified as upper or lower case characters. +specified as upper or lowercase characters. |newLine |boolean @@ -1964,7 +1924,8 @@ within the message text. === Complete well-formed XML vs. fragment XML -If you configure `complete="true"`, the appender outputs a well-formed XML document where the default namespace is the Log4j namespace `https://logging.apache.org/log4j/2.0/events`. By default, with `complete="false"`, you should include the output as an _external entity_ in a separate file to form a well-formed XML document, in which case the appender uses `namespacePrefix` with a default of `log4j`. +If you configure `complete="true"`, the appender outputs a well-formed XML document where the default namespace is the Log4j namespace `https://logging.apache.org/log4j/2.0/events`. +By default, with `complete="false"`, you should include the output as an _external entity_ in a separate file to form a well-formed XML document, in which case the appender uses `namespacePrefix` with a default of `log4j`. A well-formed XML document follows this pattern: @@ -2021,11 +1982,15 @@ If `complete="false"`, the appender does not write the XML processing instructio === Marker -Markers are represented by a `Marker` element within the `Event` element. The `Marker` element appears only when a marker is used in the log message. The name of the marker's parent will be provided in the `parent` attribute of the `Marker` element. +Markers are represented by a `Marker` element within the `Event` element. +The `Marker` element appears only when a marker is used in the log message. +The name of the marker's parent will be provided in the `parent` attribute of the `Marker` element. === Pretty vs. compact XML -By default, the XML layout is not compact (a.k.a. not "pretty") with `compact="false"`, which means the appender uses end-of-line characters and indents lines to format the XML. If `compact="true"`, then no end-of-line or indentation is used. Message content may contain, of course, end-of-lines. +By default, the XML layout is not compact (a.k.a. not "pretty") with `compact="false"`, which means the appender uses end-of-line characters and indent lines to format the XML. +If `compact="true"`, then no end-of-line or indentation is used. +Message content may contain, of course, end-of-lines. [options="header"] |=== @@ -2050,7 +2015,8 @@ To include any custom field in the output, use the following syntax: ---- -Custom fields are always last, in the order they are declared. The values support xref:manual/lookups.adoc[lookups]. +Custom fields are always last, in the order they are declared. +The values support xref:manual/lookups.adoc[lookups]. NOTE: Additional xref:runtime-dependencies.adoc[runtime dependencies] are required for using XmlLayout. @@ -2126,34 +2092,27 @@ To include any custom field in the output, use the following syntax: ---- -Custom fields are always last, in the order they are declared. The values support xref:manual/lookups.adoc[lookups]. +Custom fields are always last, in the order they are declared. +The values support xref:manual/lookups.adoc[lookups]. NOTE: Additional xref:runtime-dependencies.adoc[runtime dependencies] are required for using YamlLayout. - [#LocationInformation] == Location Information -If one of the layouts is configured with a location-related attribute -like HTML link:#HtmlLocationInfo[locationInfo], or one of the patterns +If one of the layouts is configured with a location-related attribute like HTML link:#HtmlLocationInfo[locationInfo], or one of the patterns link:#PatternClass[%C or %class], link:#PatternFile[%F or %file], link:#PatternLocation[%l or %location], link:#PatternLine[%L or %line], -link:#PatternMethod[%M or %method], Log4j will take a snapshot of the -stack, and walk the stack trace to find the location information. - -This is an expensive operation: 1.3 - 5 times slower for synchronous -loggers. Synchronous loggers wait as long as possible before they take -this stack snapshot. If no location is required, the snapshot will never -be taken. - -However, asynchronous loggers need to make this decision before passing -the log message to another thread; the location information will be lost -after that point. The -xref:manual/performance.adoc#asyncLoggingWithLocation[performance impact] of -taking a stack trace snapshot is even higher for asynchronous loggers: -logging with location is 30-100 times slower than without location. For -this reason, asynchronous loggers and asynchronous appenders do not -include location information by default. - -You can override the default behaviour in your logger or asynchronous -appender configuration by specifying `includeLocation="true"`. +link:#PatternMethod[%M or %method], Log4j will take a snapshot of the stack, and walk the stack trace to find the location information. + +This is an expensive operation: 1.3 - 5 times slower for synchronous loggers. +Synchronous loggers wait as long as possible before they take this stack snapshot. +If no location is required, the snapshot will never be taken. + +However, asynchronous loggers need to make this decision before passing the log message to another thread; the location information will be lost after that point. +The +xref:manual/performance.adoc#asyncLoggingWithLocation[performance impact] of taking a stack trace snapshot is even higher for asynchronous loggers: +logging with location is 30-100 times slower than without location. +For this reason, asynchronous loggers and asynchronous appenders do not include location information by default. + +You can override the default behavior in your logger or asynchronous appender configuration by specifying `includeLocation="true"`. diff --git a/src/site/antora/modules/ROOT/pages/manual/lookups.adoc b/src/site/antora/modules/ROOT/pages/manual/lookups.adoc index 1ac6898e464..58c8b138371 100644 --- a/src/site/antora/modules/ROOT/pages/manual/lookups.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/lookups.adoc @@ -107,8 +107,8 @@ Log4j Docker provides access to the following container attributes: This Lookup is subject to the requirements listed at xref:log4j-docker.adoc[Log4j Docker Support] -[#EnvironmentLookup] -== Environment Lookup +[id=environment-lookup] +== [[EnvironmentLookup]] Environment Lookup The EnvironmentLookup allows systems to configure environment variables, either in global files such as /etc/profile or in the startup scripts @@ -596,8 +596,8 @@ while "type" would have to be an item in the Map in a MapMessage. ---- -[#SystemPropertiesLookup] -== System Properties Lookup +[id=system-properties-lookup] +== [[SystemPropertiesLookup]] System Properties Lookup As it is quite common to define values inside and outside the application by using System Properties, it is only natural that they diff --git a/src/site/antora/modules/ROOT/pages/manual/migration.adoc b/src/site/antora/modules/ROOT/pages/manual/migration.adoc index 202cae8d919..6bb50d23060 100644 --- a/src/site/antora/modules/ROOT/pages/manual/migration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/migration.adoc @@ -39,7 +39,7 @@ image:whichjar-log4j-1.2-api.png[Using log4j 2 via the log4j 1.x API] For most applications this is sufficient. This is a low-effort way to migrate, and may also allow for migration to proceed gradually over time. -[#EnablingLog4j12Bridge] +[id=enabling-the-log4j-1-x-bridge] === Enabling the Log4j 1.x bridge Enable the Log4j 1.x bridge via one of the following steps: diff --git a/src/site/antora/modules/ROOT/pages/manual/scripts.adoc b/src/site/antora/modules/ROOT/pages/manual/scripts.adoc new file mode 100644 index 00000000000..df835933db7 --- /dev/null +++ b/src/site/antora/modules/ROOT/pages/manual/scripts.adoc @@ -0,0 +1,127 @@ +//// + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +//// +[id=scripts] += Scripts + +Log4j provides support for +https://docs.oracle.com/javase/6/docs/technotes/guides/scripting/[JSR +223] scripting languages to be used in some of its components. + +[WARNING] +==== +In order to enable a scripting language, its name must be included in the +xref:manual/systemproperties.adoc#log4j2.scriptEnableLanguages[log4j2.scriptEnableLanguages] +configuration property. +==== + +Each component that allows scripts can contain on of the following configuration elements: + +Script:: ++ +This element specifies the content of the script directly and has: ++ +-- +* a required `language` configuration attribute that specifies the name of the JSR 223 language to use, +* a required `scriptText` configuration attribute that contains the text of the script. +In the XML configuration format, the text of the script can also be written as content of the `