diff --git a/.github/workflows/build-reusable.yaml b/.github/workflows/build-reusable.yaml index a998be7..a7195b7 100644 --- a/.github/workflows/build-reusable.yaml +++ b/.github/workflows/build-reusable.yaml @@ -1,11 +1,12 @@ +# tag::license[] # -# Copyright © 2024 Piotr P. Karwasz +# Copyright (C) 2024 Piotr P. Karwasz # # Licensed 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 +# https://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, @@ -13,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# end::license[] name: build-reusable diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 1e9d31e..af0f44a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,11 +1,12 @@ +# tag::license[] # -# Copyright © 2024 Piotr P. Karwasz +# Copyright (C) 2024 Piotr P. Karwasz # # Licensed 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 +# https://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, @@ -13,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# end::license[] name: build on: diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 52d0ddd..6ae5f4b 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -1,11 +1,12 @@ +# tag::license[] # -# Copyright © 2024 Piotr P. Karwasz +# Copyright (C) 2024 Piotr P. Karwasz # # Licensed 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 +# https://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, @@ -13,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# end::license[] name: "CodeQL" on: diff --git a/.github/workflows/merge-dependabot.yaml b/.github/workflows/merge-dependabot.yaml index d184b33..05800db 100644 --- a/.github/workflows/merge-dependabot.yaml +++ b/.github/workflows/merge-dependabot.yaml @@ -1,11 +1,12 @@ +# tag::license[] # -# Copyright © 2024 Piotr P. Karwasz +# Copyright (C) 2024 Piotr P. Karwasz # # Licensed 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 +# https://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, @@ -13,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# end::license[] name: merge-dependabot on: diff --git a/distribution/pom.xml b/distribution/pom.xml new file mode 100644 index 0000000..2fe21cb --- /dev/null +++ b/distribution/pom.xml @@ -0,0 +1,103 @@ + + + + 4.0.0 + + eu.copernik + log4j-plugins-parent + 3.0.0-SNAPSHOT + + + copernik-tomcat-log4j + pom + Copernik.eu extensions for Log4j and Tomcat + + + true + true + + + + + + eu.copernik + log4j-tomcat + ${project.version} + + + + eu.copernik + tomcat-log4j + ${project.version} + + + + eu.copernik + tomcat-juli-to-log4j + ${project.version} + + + + org.apache.logging.log4j + log4j-api + + + + org.apache.logging.log4j + log4j-core + + + + org.apache.logging.log4j + log4j-layout-template-json + + + + org.apache.logging.log4j + log4j-jakarta-web + + + + + + + + + maven-assembly-plugin + + + create-distribution + + single + + package + + false + + src/main/assembly/distribution.xml + + + + + + + + + + diff --git a/distribution/src/main/assembly/distribution.xml b/distribution/src/main/assembly/distribution.xml new file mode 100644 index 0000000..6eb86c9 --- /dev/null +++ b/distribution/src/main/assembly/distribution.xml @@ -0,0 +1,55 @@ + + + + overlay + + zip + + + + src/main/resources + / + + + + + + + eu.copernik:* + org.apache.logging.log4j:* + + + eu.copernik:tomcat-log4j + org.apache.logging.log4j:log4j-jakarta-web + + overlay/bin/logging + + + + eu.copernik:tomcat-log4j + org.apache.logging.log4j:log4j-jakarta-web + + overlay/lib + + + diff --git a/distribution/src/main/resources/overlay/bin/setenv-log4j.sh b/distribution/src/main/resources/overlay/bin/setenv-log4j.sh new file mode 120000 index 0000000..065da6e --- /dev/null +++ b/distribution/src/main/resources/overlay/bin/setenv-log4j.sh @@ -0,0 +1 @@ +../../../../../../src/antora/modules/ROOT/examples/setenv.sh \ No newline at end of file diff --git a/distribution/src/main/resources/overlay/conf/context-log4j.xml b/distribution/src/main/resources/overlay/conf/context-log4j.xml new file mode 120000 index 0000000..0b05146 --- /dev/null +++ b/distribution/src/main/resources/overlay/conf/context-log4j.xml @@ -0,0 +1 @@ +../../../../../../src/antora/modules/ROOT/examples/tomcat-components/context.xml \ No newline at end of file diff --git a/distribution/src/main/resources/overlay/conf/logging/log4j2.component.properties b/distribution/src/main/resources/overlay/conf/logging/log4j2.component.properties new file mode 100644 index 0000000..73e84c0 --- /dev/null +++ b/distribution/src/main/resources/overlay/conf/logging/log4j2.component.properties @@ -0,0 +1,45 @@ +# tag::license[] +# +# Copyright (C) 2024 Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] +## +# SEPARATE LOGGER CONTEXTS +# +# Enable Tomcat context selector +log4j2.contextSelector = eu.copernik.log4j.tomcat.TomcatContextSelector + +# To enable asynchronous loggers with multiple logger contexts: +# 1. Add `com.lmax:disruptor` to `$CATALINA_BASE/bin/logging`. +# 2. Replace the `log4j2.contextSelector` property with: +# +# log4j2.contextSelector = eu.copernik.log4j.tomcat.TomcatAsyncContextSelector + +# SINGLE LOGGER CONTEXT +# +# To use a single logger context, replace the `log4j2.contextSelector` property with: +# +# log4j2.contextSelector = org.apache.logging.log4j.core.selector.BasicContextSelector + +# To enable asynchronous loggers with a single logger context: +# 1. Add `com.lmax:disruptor` to `$CATALINA_BASE/bin/logging`. +# 2. Replace the `log4j2.contextSelector` property with: +# +# log4j2.contextSelector = org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector + +# ADDITIONAL CONTEXT DATA +# Uncomment to use additional context data: +# +# log4j2.tomcatContextDataEnabled = true diff --git a/distribution/src/main/resources/overlay/conf/logging/log4j2.xml b/distribution/src/main/resources/overlay/conf/logging/log4j2.xml new file mode 120000 index 0000000..f125e86 --- /dev/null +++ b/distribution/src/main/resources/overlay/conf/logging/log4j2.xml @@ -0,0 +1 @@ +../../../../../../../src/antora/modules/ROOT/examples/bridge/log4j2.xml \ No newline at end of file diff --git a/log4j-tomcat/pom.xml b/log4j-tomcat/pom.xml index b1cc9ba..5b5faf1 100644 --- a/log4j-tomcat/pom.xml +++ b/log4j-tomcat/pom.xml @@ -1,5 +1,6 @@ - - + ~ + ~ end::license[] --> + 4.0.0 eu.copernik @@ -50,6 +51,12 @@ test + + org.apache.logging.log4j + log4j-api-test + test + + org.assertj assertj-core diff --git a/log4j-tomcat/src/main/java/eu/copernik/log4j/tomcat/TomcatContextDataProvider.java b/log4j-tomcat/src/main/java/eu/copernik/log4j/tomcat/TomcatContextDataProvider.java index dd791a1..ba6af5a 100644 --- a/log4j-tomcat/src/main/java/eu/copernik/log4j/tomcat/TomcatContextDataProvider.java +++ b/log4j-tomcat/src/main/java/eu/copernik/log4j/tomcat/TomcatContextDataProvider.java @@ -24,45 +24,64 @@ import java.util.concurrent.ConcurrentMap; import org.apache.juli.WebappProperties; import org.apache.logging.log4j.core.util.ContextDataProvider; +import org.apache.logging.log4j.util.PropertiesUtil; import org.apache.logging.log4j.util.SortedArrayStringMap; import org.apache.logging.log4j.util.StringMap; @ServiceProvider(value = ContextDataProvider.class, resolution = Resolution.OPTIONAL) public class TomcatContextDataProvider implements ContextDataProvider { + private static final String CONTEXT_DATA_ENABLED = "log4j2.tomcatContextDataEnabled"; + private static final StringMap EMPTY_STRING_MAP = new SortedArrayStringMap(); + + static { + EMPTY_STRING_MAP.freeze(); + } + private final ConcurrentMap> mapCache = new ConcurrentHashMap<>(); private final ConcurrentMap stringMapCache = new ConcurrentHashMap<>(); + private final boolean enabled; + + public TomcatContextDataProvider() { + enabled = PropertiesUtil.getProperties().getBooleanProperty(CONTEXT_DATA_ENABLED); + } @Override public Map supplyContextData() { - final ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - final int hashCode = System.identityHashCode(tccl); - return mapCache.computeIfAbsent(hashCode, __ -> { - final HashMap map = new HashMap<>(3); - if (tccl instanceof WebappProperties) { - final WebappProperties props = (WebappProperties) tccl; - map.put(TomcatLookup.CONTEXT_NAME, props.getWebappName()); - map.put(TomcatLookup.ENGINE_NAME, props.getServiceName()); - map.put(TomcatLookup.HOST_NAME, props.getHostName()); - } - return Collections.unmodifiableMap(map); - }); + if (enabled) { + final ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + final int hashCode = System.identityHashCode(tccl); + return mapCache.computeIfAbsent(hashCode, __ -> { + final Map map = new HashMap<>(3); + if (tccl instanceof WebappProperties) { + final WebappProperties props = (WebappProperties) tccl; + map.put(TomcatLookup.CONTEXT_NAME, props.getWebappName()); + map.put(TomcatLookup.ENGINE_NAME, props.getServiceName()); + map.put(TomcatLookup.HOST_NAME, props.getHostName()); + } + return Collections.unmodifiableMap(map); + }); + } + return Collections.emptyMap(); } @Override public StringMap supplyStringMap() { - final ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - final int hashCode = System.identityHashCode(tccl); - return stringMapCache.computeIfAbsent(hashCode, __ -> { - final StringMap map = new SortedArrayStringMap(3); - if (tccl instanceof WebappProperties) { - final WebappProperties props = (WebappProperties) tccl; - map.putValue(TomcatLookup.CONTEXT_NAME, props.getWebappName()); - map.putValue(TomcatLookup.ENGINE_NAME, props.getServiceName()); - map.putValue(TomcatLookup.HOST_NAME, props.getHostName()); - } - map.freeze(); - return map; - }); + if (enabled) { + final ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + final int hashCode = System.identityHashCode(tccl); + return stringMapCache.computeIfAbsent(hashCode, __ -> { + final StringMap map = new SortedArrayStringMap(3); + if (tccl instanceof WebappProperties) { + final WebappProperties props = (WebappProperties) tccl; + map.putValue(TomcatLookup.CONTEXT_NAME, props.getWebappName()); + map.putValue(TomcatLookup.ENGINE_NAME, props.getServiceName()); + map.putValue(TomcatLookup.HOST_NAME, props.getHostName()); + } + map.freeze(); + return map; + }); + } + return EMPTY_STRING_MAP; } } diff --git a/log4j-tomcat/src/test/java/eu/copernik/log4j/tomcat/GlobalTomcatContextDataProviderTest.java b/log4j-tomcat/src/test/java/eu/copernik/log4j/tomcat/GlobalTomcatContextDataProviderTest.java index b8ddf0b..e1881ae 100644 --- a/log4j-tomcat/src/test/java/eu/copernik/log4j/tomcat/GlobalTomcatContextDataProviderTest.java +++ b/log4j-tomcat/src/test/java/eu/copernik/log4j/tomcat/GlobalTomcatContextDataProviderTest.java @@ -18,11 +18,13 @@ import static org.assertj.core.api.Assertions.assertThat; import org.apache.logging.log4j.core.util.ContextDataProvider; +import org.apache.logging.log4j.test.junit.SetTestProperty; import org.junit.jupiter.api.Test; -public class GlobalTomcatContextDataProviderTest { +class GlobalTomcatContextDataProviderTest { @Test + @SetTestProperty(key = "log4j2.tomcatContextDataEnabled", value = "true") void mapsAreEmpty() { final ContextDataProvider provider = new TomcatContextDataProvider(); assertThat(provider.supplyContextData()).isEmpty(); diff --git a/log4j-tomcat/src/test/java/eu/copernik/log4j/tomcat/GlobalTomcatLookupTest.java b/log4j-tomcat/src/test/java/eu/copernik/log4j/tomcat/GlobalTomcatLookupTest.java index 7377c81..88c5d94 100644 --- a/log4j-tomcat/src/test/java/eu/copernik/log4j/tomcat/GlobalTomcatLookupTest.java +++ b/log4j-tomcat/src/test/java/eu/copernik/log4j/tomcat/GlobalTomcatLookupTest.java @@ -25,7 +25,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -public class GlobalTomcatLookupTest { +class GlobalTomcatLookupTest { static Stream lookupWorksProperly() { return TomcatLookupTest.lookupWorksProperly().map(args -> (String) args.get()[0]); diff --git a/log4j-tomcat/src/test/java/eu/copernik/log4j/tomcat/TomcatContextDataProviderTest.java b/log4j-tomcat/src/test/java/eu/copernik/log4j/tomcat/TomcatContextDataProviderTest.java index 663ce69..6c36605 100644 --- a/log4j-tomcat/src/test/java/eu/copernik/log4j/tomcat/TomcatContextDataProviderTest.java +++ b/log4j-tomcat/src/test/java/eu/copernik/log4j/tomcat/TomcatContextDataProviderTest.java @@ -20,6 +20,8 @@ import eu.copernik.log4j.tomcat.junit.ContextClassLoaderExtension; import java.util.Map; import java.util.function.BiFunction; +import org.apache.logging.log4j.core.util.ContextDataProvider; +import org.apache.logging.log4j.test.junit.SetTestProperty; import org.apache.logging.log4j.util.StringMap; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -28,11 +30,13 @@ class TomcatContextDataProviderTest { @Test + @SetTestProperty(key = "log4j2.tomcatContextDataEnabled", value = "true") void supplyContextData() { assertData(new TomcatContextDataProvider().supplyContextData(), Map::get); } @Test + @SetTestProperty(key = "log4j2.tomcatContextDataEnabled", value = "true") void supplyStringMap() { assertData(new TomcatContextDataProvider().supplyStringMap(), StringMap::getValue); } @@ -42,4 +46,14 @@ private static void assertData(final T map, final BiFunction - + ~ + ~ end::license[] --> 4.0.0 @@ -49,6 +51,7 @@ + distribution log4j-tomcat tomcat-log4j tomcat-juli-to-log4j @@ -764,21 +767,7 @@ - + ${maven.multiModuleProjectDirectory}/src/headers/java.txt ${palantir-java-format.version} @@ -786,23 +775,7 @@ - - -]]> + ${maven.multiModuleProjectDirectory}/src/headers/xml.txt <project @@ -823,52 +796,46 @@ src/changelog/**/*.xml - - -]]> + ${maven.multiModuleProjectDirectory}/src/headers/xml.txt + ^<\?xml.*\?>$ <(!DOCTYPE|\w) + + + src/**/*.adoc + + + ${maven.multiModuleProjectDirectory}/src/headers/adoc.txt + [^/] + + + + + + + src/**/*.properties + src/**/*.sh + + + ${maven.multiModuleProjectDirectory}/src/headers/yaml.txt + ^#!/.+$ + (##|[^#]) + + + + - .asf.yaml .github/**/*.yaml + src/**/*.yml src/**/*.yaml - - + ${maven.multiModuleProjectDirectory}/src/headers/yaml.txt (##|[^#]) diff --git a/src/antora/antora.yml b/src/antora/antora.yml new file mode 100644 index 0000000..02a16cf --- /dev/null +++ b/src/antora/antora.yml @@ -0,0 +1,34 @@ +# tag::license[] +# +# Copyright (C) 2024 Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] +name: home +title: Home +version: ~ +start_page: index.adoc +asciidoc: + attributes: + disruptor-version: 4.0.0 + examples-url: https://github.com/copernik-eu/log4j-tomcat/blob/main/src/antora/modules/ROOT/examples + log4j-api-url: https://logging.apache.org/log4j/2.x + log4j-version: 2.23.1 + maven-base-url: https://repo.maven.apache.org/maven2/eu/copernik + project-version: 3.0.0-beta1 + tomcat-major-version: 10 + tomcat-minor-version: 10.1 + tomcat-url: https://tomcat.apache.org/tomcat-10.1-doc +nav: + - modules/ROOT/nav.adoc diff --git a/src/antora/modules/ROOT/examples/guide/enable-context-data.properties b/src/antora/modules/ROOT/examples/guide/enable-context-data.properties new file mode 100644 index 0000000..1c93d8b --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/enable-context-data.properties @@ -0,0 +1,20 @@ +# tag::license[] +# +# Copyright (C) 2024 Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] +## +# Enable the Tomcat context data provider +log4j2.tomcatContextDataEnabled = true diff --git a/src/antora/modules/ROOT/examples/guide/multiple-contexts-multiple-files.json b/src/antora/modules/ROOT/examples/guide/multiple-contexts-multiple-files.json new file mode 100644 index 0000000..d11badf --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/multiple-contexts-multiple-files.json @@ -0,0 +1,43 @@ +{ + "Configuration": { + "Properties": { + "Property": [ + { + "name": "logs.dir", + "value": "${sys:catalina.base}/logs" + }, + { + "name": "context.name", + "value": "catalina" + } + ] + }, + "Appenders": { + "RollingFile": { + "name": "FILE", + "filePattern": "${logs.dir}/${tomcat:context.name}.%d{yyyy-MM-dd}.log", + "JsonTemplateLayout": {}, + "DirectWriteRolloverStrategy": { + "Delete": { + "basePath": "${logs.dir}", + "IfFileName": { + "regex": "${tomcat:context.name}\\.\\d{4}-\\d{2}-\\d{2}\\.log" + }, + "IfLastModified": { + "age": "P90D" + } + } + }, + "TimeBasedTriggeringPolicy": {} + } + }, + "Loggers": { + "Root": { + "level": "INFO", + "AppenderRef": { + "ref": "FILE" + } + } + } + } +} \ No newline at end of file diff --git a/src/antora/modules/ROOT/examples/guide/multiple-contexts-multiple-files.xml b/src/antora/modules/ROOT/examples/guide/multiple-contexts-multiple-files.xml new file mode 100644 index 0000000..17e8e84 --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/multiple-contexts-multiple-files.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/antora/modules/ROOT/examples/guide/multiple-contexts-multiple-files.yaml b/src/antora/modules/ROOT/examples/guide/multiple-contexts-multiple-files.yaml new file mode 100644 index 0000000..a980ccf --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/multiple-contexts-multiple-files.yaml @@ -0,0 +1,42 @@ +# tag::license[] +# +# Copyright (C) 2024 Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] +Configuration: + Properties: + Property: + - name: "logs.dir" + value: "${sys:catalina.base}/logs" + - name: "context.name" + value: "catalina" + Appenders: + RollingFile: + name: "FILE" + filePattern: "${logs.dir}/${tomcat:context.name}.%d{yyyy-MM-dd}.log" + JsonTemplateLayout: {} + DirectWriteRolloverStrategy: + Delete: + basePath: "${logs.dir}" + IfFileName: + regex: "${tomcat:context.name}\.\d{4}-\d{2}-\d{2}\.log" + IfLastModified: + age: "P90D" + TimeBasedTriggeringPolicy: { } + Loggers: + Root: + level: "INFO" + AppenderRef: + - ref: "FILE" diff --git a/src/antora/modules/ROOT/examples/guide/multiple-contexts-one-file.json b/src/antora/modules/ROOT/examples/guide/multiple-contexts-one-file.json new file mode 100644 index 0000000..738b4a1 --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/multiple-contexts-one-file.json @@ -0,0 +1,33 @@ +{ + "Configuration": { + "Properties": { + "Property": [ + { + "name": "context.name", + "value": "catalina" + } + ] + }, + "Appenders": { + "Console": { + "name": "CONSOLE", + "direct": true, + "JsonTemplateLayout": { + "EventTemplateAdditionalField": { // <1> + "key": "context.name", + "value": "${tomcat:context.name}" + } + }, + "TimeBasedTriggeringPolicy": {} + } + }, + "Loggers": { + "Root": { + "level": "INFO", + "AppenderRef": { + "ref": "CONSOLE" + } + } + } + } +} \ No newline at end of file diff --git a/src/antora/modules/ROOT/examples/guide/multiple-contexts-one-file.xml b/src/antora/modules/ROOT/examples/guide/multiple-contexts-one-file.xml new file mode 100644 index 0000000..1e9cfb9 --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/multiple-contexts-one-file.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/antora/modules/ROOT/examples/guide/multiple-contexts-one-file.yaml b/src/antora/modules/ROOT/examples/guide/multiple-contexts-one-file.yaml new file mode 100644 index 0000000..c541822 --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/multiple-contexts-one-file.yaml @@ -0,0 +1,35 @@ +# tag::license[] +# +# Copyright (C) 2024 Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] +Configuration: + Properties: + Property: + - name: "context.name" + value: "catalina" + Appenders: + RollingFile: + name: "CONSOLE" + direct: true + JsonTemplateLayout: + EventTemplateAdditionalField: # <1> + key: "context.name" + value: "${tomcat:context.name}" + Loggers: + Root: + level: "INFO" + AppenderRef: + - ref: "CONSOLE" diff --git a/src/antora/modules/ROOT/examples/guide/multiple-contexts.properties b/src/antora/modules/ROOT/examples/guide/multiple-contexts.properties new file mode 100644 index 0000000..35c8192 --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/multiple-contexts.properties @@ -0,0 +1,26 @@ +# tag::license[] +# +# Copyright (C) 2024 Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] +## +# Enable Tomcat context selector +log4j2.contextSelector = eu.copernik.log4j.tomcat.TomcatContextSelector + +# To enable asynchronous loggers: +# 1. Add `com.lmax:disruptor` to `$CATALINA_BASE/bin/logging`. +# 2. Replace the `log4j2.contextSelector` property with: +# +# log4j2.contextSelector = eu.copernik.log4j.tomcat.TomcatAsyncContextSelector diff --git a/src/antora/modules/ROOT/examples/guide/one-context-multiple-files.json b/src/antora/modules/ROOT/examples/guide/one-context-multiple-files.json new file mode 100644 index 0000000..61e48fa --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/one-context-multiple-files.json @@ -0,0 +1,51 @@ +{ + "Configuration": { + "Properties": { + "Property": [ + { + "name": "logs.dir", + "value": "${sys:catalina.base}/logs" + }, + { + "name": "context.name", + "value": "catalina" + } + ] + }, + "Appenders": { + "Routing": { + "name": "ROUTING", + "Routes": { + "pattern": "$${tomcat:context.name}", + "Route": { + "RollingFile": { + "name": "${tomcat:context.name}", + "filePattern": "${logs.dir}/${tomcat:context.name}.%d{yyyy-MM-dd}.log", + "JsonTemplatelayout": {}, + "DirectWriteRolloverStrategy": { + "Delete": { + "basePath": "${logs.dir}", + "IfFileName": { + "regex": "${tomcat:context.name}\\.\\d{4}-\\d{2}-\\d{2}\\.log" + }, + "IfLastModified": { + "age": "P90D" + } + } + }, + "TimeBasedTriggeringPolicy": {} + } + } + } + } + }, + "Loggers": { + "Root": { + "level": "INFO", + "AppenderRef": { + "ref": "ROUTING" + } + } + } + } +} \ No newline at end of file diff --git a/src/antora/modules/ROOT/examples/guide/one-context-multiple-files.xml b/src/antora/modules/ROOT/examples/guide/one-context-multiple-files.xml new file mode 100644 index 0000000..36e664e --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/one-context-multiple-files.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/antora/modules/ROOT/examples/guide/one-context-multiple-files.yaml b/src/antora/modules/ROOT/examples/guide/one-context-multiple-files.yaml new file mode 100644 index 0000000..29395f7 --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/one-context-multiple-files.yaml @@ -0,0 +1,52 @@ +# tag::license[] +# +# Copyright (C) 2024 Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] +Configuration: + Properties: + Property: + - name: "logs.dir" + value: "${sys:catalina.base}/logs" + - name: "one.line.pattern" + value: "%d{dd-MMM-yyyy HH:mm:ss.SSS} %p [%t] %C.%M %m%n" + - name: "context.name" + value: "catalina" + Appenders: + # tag::appender[] + Routing: + name: "ROUTING" + Routes: + pattern: "$${tomcat:context.name}" + Route: + RollingFile: + name: "${tomcat:context.name}" + filePattern: "${logs.dir}/${tomcat:context.name}.%d{yyyy-MM-dd}.log" # + PatternLayout: + pattern: "${one.line.pattern}" + DirectWriteRolloverStrategy: + Delete: + basePath: "${logs.dir}" + IfFileName: + regex: "${tomcat:context.name}\.\d{4}-\d{2}-\d{2}\.log" + IfLastModified: + age: "P90D" + TimeBasedTriggeringPolicy: { } + # end::appender[] + Loggers: + Root: + level: "INFO" + AppenderRef: + - ref: "FILE" diff --git a/src/antora/modules/ROOT/examples/guide/one-context-one-file.json b/src/antora/modules/ROOT/examples/guide/one-context-one-file.json new file mode 100644 index 0000000..fb6a0e9 --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/one-context-one-file.json @@ -0,0 +1,28 @@ +{ + "Configuration": { + "Properties": { + "Property": [ + { + "name": "context.name", + "value": "catalina" + } + ] + }, + "Appenders": { + "Console": { + "name": "CONSOLE", + "direct": true, + "JsonTemplateLayout": {}, + "TimeBasedTriggeringPolicy": {} + } + }, + "Loggers": { + "Root": { + "level": "INFO", + "AppenderRef": { + "ref": "CONSOLE" + } + } + } + } +} \ No newline at end of file diff --git a/src/antora/modules/ROOT/examples/guide/one-context-one-file.xml b/src/antora/modules/ROOT/examples/guide/one-context-one-file.xml new file mode 100644 index 0000000..e4744c1 --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/one-context-one-file.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + diff --git a/src/antora/modules/ROOT/examples/guide/one-context-one-file.yaml b/src/antora/modules/ROOT/examples/guide/one-context-one-file.yaml new file mode 100644 index 0000000..62e02f3 --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/one-context-one-file.yaml @@ -0,0 +1,32 @@ +# tag::license[] +# +# Copyright (C) 2024 Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] +Configuration: + Properties: + Property: + - name: "context.name" + value: "catalina" + Appenders: + RollingFile: + name: "CONSOLE" + direct: true + JsonTemplateLayout: { } + Loggers: + Root: + level: "INFO" + AppenderRef: + - ref: "CONSOLE" diff --git a/src/antora/modules/ROOT/examples/guide/one-context.properties b/src/antora/modules/ROOT/examples/guide/one-context.properties new file mode 100644 index 0000000..2c6767d --- /dev/null +++ b/src/antora/modules/ROOT/examples/guide/one-context.properties @@ -0,0 +1,26 @@ +# tag::license[] +# +# Copyright (C) 2024 Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] +## +# Use the `BasicContextSelector` +log4j2.contextSelector = org.apache.logging.log4j.core.selector.BasicContextSelector + +# To enable asynchronous loggers: +# 1. Add `com.lmax:disruptor` to `$CATALINA_BASE/bin/logging`. +# 2. Replace the `log4j2.contextSelector` property with: +# +# log4j2.contextSelector = org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector diff --git a/src/antora/modules/ROOT/examples/log4j-tomcat/reusable.json b/src/antora/modules/ROOT/examples/log4j-tomcat/reusable.json new file mode 100644 index 0000000..89dccb8 --- /dev/null +++ b/src/antora/modules/ROOT/examples/log4j-tomcat/reusable.json @@ -0,0 +1,55 @@ +{ + "Configuration": { + // tag::default[] + "Properties": { + "Property": [ + // tag::ignore[] + { + "name": "logs.dir", + "value": "${sys:catalina.base}/logs" + }, + { + "name": "one.line.pattern", + "value": "%d{dd-MMM-yyyy HH:mm:ss.SSS} %p [%t] %C.%M %m%n" + }, + // end::ignore[] + { + "name": "context.name", + "value": "catalina" + } + ] + }, + // end::default[] + "Appenders": { + // tag::appender[] + "RollingFile": { + "name": "FILE", + "filePattern": "${logs.dir}/${tomcat:context.name}.%d{yyyy-MM-dd}.log", // <1> + "PatternLayout": { + "pattern": "${one.line.pattern}" + }, + "DirectWriteRolloverStrategy": { + "Delete": { + "basePath": "${logs.dir}", + "IfFileName": { + "regex": "${tomcat:context.name}\\.\\d{4}-\\d{2}-\\d{2}\\.log" + }, + "IfLastModified": { + "age": "P90D" + } + } + }, + "TimeBasedTriggeringPolicy": {} + } + // end::appender[] + }, + "Loggers": { + "Root": { + "level": "INFO", + "AppenderRef": { + "ref": "FILE" + } + } + } + } +} \ No newline at end of file diff --git a/src/antora/modules/ROOT/examples/log4j-tomcat/reusable.xml b/src/antora/modules/ROOT/examples/log4j-tomcat/reusable.xml new file mode 100644 index 0000000..d953c7d --- /dev/null +++ b/src/antora/modules/ROOT/examples/log4j-tomcat/reusable.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/antora/modules/ROOT/examples/log4j-tomcat/reusable.yaml b/src/antora/modules/ROOT/examples/log4j-tomcat/reusable.yaml new file mode 100644 index 0000000..c6d657f --- /dev/null +++ b/src/antora/modules/ROOT/examples/log4j-tomcat/reusable.yaml @@ -0,0 +1,51 @@ +# tag::license[] +# +# Copyright (C) 2024 Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] +Configuration: + # tag::default[] + Properties: + Property: + # tag::ignore[] + - name: "logs.dir" + value: "${sys:catalina.base}/logs" + - name: "one.line.pattern" + value: "%d{dd-MMM-yyyy HH:mm:ss.SSS} %p [%t] %C.%M %m%n" + # end::ignore[] + - name: "context.name" + value: "catalina" + # end::default[] + Appenders: + # tag::appender[] + RollingFile: + name: "FILE" + filePattern: "${logs.dir}/${tomcat:context.name}.%d{yyyy-MM-dd}.log" # <1> + PatternLayout: + pattern: "${one.line.pattern}" + DirectWriteRolloverStrategy: + Delete: + basePath: "${logs.dir}" + IfFileName: + regex: "${tomcat:context.name}\.\d{4}-\d{2}-\d{2}\.log" + IfLastModified: + age: "P90D" + TimeBasedTriggeringPolicy: { } + # end::appender[] + Loggers: + Root: + level: "INFO" + AppenderRef: + - ref: "FILE" diff --git a/src/antora/modules/ROOT/examples/log4j-tomcat/routing.json b/src/antora/modules/ROOT/examples/log4j-tomcat/routing.json new file mode 100644 index 0000000..8fce125 --- /dev/null +++ b/src/antora/modules/ROOT/examples/log4j-tomcat/routing.json @@ -0,0 +1,59 @@ +{ + "Configuration": { + "Properties": { + "Property": [ + { + "name": "logs.dir", + "value": "${sys:catalina.base}/logs" + }, + { + "name": "one.line.pattern", + "value": "%d{dd-MMM-yyyy HH:mm:ss.SSS} %p [%t] %C.%M %m%n" + }, + { + "name": "context.name", + "value": "catalina" + } + ] + }, + "Appenders": { + // tag::appender[] + "Routing": { + "name": "ROUTING", + "Routes": { + "pattern": "$${tomcat:context.name}", + "Route": { + "RollingFile": { + "name": "${tomcat:context.name}", + "filePattern": "${logs.dir}/${tomcat:context.name}.%d{yyyy-MM-dd}.log", + "PatternLayout": { + "pattern": "${one.line.pattern}" + }, + "DirectWriteRolloverStrategy": { + "Delete": { + "basePath": "${logs.dir}", + "IfFileName": { + "regex": "${tomcat:context.name}\\.\\d{4}-\\d{2}-\\d{2}\\.log" + }, + "IfLastModified": { + "age": "P90D" + } + } + }, + "TimeBasedTriggeringPolicy": {} + } + } + } + } + // end::appender[] + }, + "Loggers": { + "Root": { + "level": "INFO", + "AppenderRef": { + "ref": "ROUTING" + } + } + } + } +} \ No newline at end of file diff --git a/src/antora/modules/ROOT/examples/log4j-tomcat/routing.xml b/src/antora/modules/ROOT/examples/log4j-tomcat/routing.xml new file mode 100644 index 0000000..1cacb2e --- /dev/null +++ b/src/antora/modules/ROOT/examples/log4j-tomcat/routing.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/antora/modules/ROOT/examples/log4j-tomcat/routing.yaml b/src/antora/modules/ROOT/examples/log4j-tomcat/routing.yaml new file mode 100644 index 0000000..29395f7 --- /dev/null +++ b/src/antora/modules/ROOT/examples/log4j-tomcat/routing.yaml @@ -0,0 +1,52 @@ +# tag::license[] +# +# Copyright (C) 2024 Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] +Configuration: + Properties: + Property: + - name: "logs.dir" + value: "${sys:catalina.base}/logs" + - name: "one.line.pattern" + value: "%d{dd-MMM-yyyy HH:mm:ss.SSS} %p [%t] %C.%M %m%n" + - name: "context.name" + value: "catalina" + Appenders: + # tag::appender[] + Routing: + name: "ROUTING" + Routes: + pattern: "$${tomcat:context.name}" + Route: + RollingFile: + name: "${tomcat:context.name}" + filePattern: "${logs.dir}/${tomcat:context.name}.%d{yyyy-MM-dd}.log" # + PatternLayout: + pattern: "${one.line.pattern}" + DirectWriteRolloverStrategy: + Delete: + basePath: "${logs.dir}" + IfFileName: + regex: "${tomcat:context.name}\.\d{4}-\d{2}-\d{2}\.log" + IfLastModified: + age: "P90D" + TimeBasedTriggeringPolicy: { } + # end::appender[] + Loggers: + Root: + level: "INFO" + AppenderRef: + - ref: "FILE" diff --git a/src/antora/modules/ROOT/examples/setenv.sh b/src/antora/modules/ROOT/examples/setenv.sh new file mode 100644 index 0000000..fd604ea --- /dev/null +++ b/src/antora/modules/ROOT/examples/setenv.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# tag::license[] +# +# Copyright (C) 2024 Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] +## +# Add the additional libraries +CLASSPATH="$CLASSPATH:$CATALINA_BASE/bin/logging/*" +## +# Add a folder for the logging configuration +CLASSPATH="$CLASSPATH:$CATALINA_BASE/conf/logging/" diff --git a/src/antora/modules/ROOT/examples/tomcat-jul-to-log4j/log4j2.json b/src/antora/modules/ROOT/examples/tomcat-jul-to-log4j/log4j2.json new file mode 100644 index 0000000..6e8e798 --- /dev/null +++ b/src/antora/modules/ROOT/examples/tomcat-jul-to-log4j/log4j2.json @@ -0,0 +1,139 @@ +{ + "Configuration": { + "Properties": { + "Property": [ + { + "name": "logs.dir", + "value": "${sys:catalina.base}/logs" + }, + { + "name": "one.line.pattern", + "value": "%d{dd-MMM-yyyy HH:mm:ss.SSS} %p [%t] %C.%M %m%n" + } + ] + }, + "Appenders": { + "RollingFile": [ + { + "name": "catalina", + "filePattern": "${logs.dir}/catalina.%d{yyyy-MM-dd}.log", + "PatternLayout": { + "pattern": "${one.line.pattern}" + }, + "DirectWriteRolloverStrategy": { + "Delete": { + "basePath": "${logs.dir}", + "IfFileName": { + "regex": "catalina\\.\\d{4}-\\d{2}-\\d{2}\\.log" + }, + "IfLastModified": { + "age": "P90D" + } + } + }, + "TimeBasedTriggeringPolicy": {} + }, + { + "name": "localhost", + "filePattern": "${logs.dir}/localhost.%d{yyyy-MM-dd}.log", + "PatternLayout": { + "pattern": "${one.line.pattern}" + }, + "DirectWriteRolloverStrategy": { + "Delete": { + "basePath": "${logs.dir}", + "IfFileName": { + "regex": "localhost\\.\\d{4}-\\d{2}-\\d{2}\\.log" + }, + "IfLastModified": { + "age": "P90D" + } + } + }, + "TimeBasedTriggeringPolicy": {} + }, + { + "name": "manager", + "filePattern": "${logs.dir}/manager.%d{yyyy-MM-dd}.log", + "PatternLayout": { + "pattern": "${one.line.pattern}" + }, + "DirectWriteRolloverStrategy": { + "Delete": { + "basePath": "${logs.dir}", + "IfFileName": { + "regex": "manager\\.\\d{4}-\\d{2}-\\d{2}\\.log" + }, + "IfLastModified": { + "age": "P90D" + } + } + }, + "TimeBasedTriggeringPolicy": {} + }, + { + "name": "host-manager", + "filePattern": "${logs.dir}/host-manager.%d{yyyy-MM-dd}.log", + "PatternLayout": { + "pattern": "${one.line.pattern}" + }, + "DirectWriteRolloverStrategy": { + "Delete": { + "basePath": "${logs.dir}", + "IfFileName": { + "regex": "host-manager\\.\\d{4}-\\d{2}-\\d{2}\\.log" + }, + "IfLastModified": { + "age": "P90D" + } + } + }, + "TimeBasedTriggeringPolicy": {} + } + ], + "Console": { + "name": "console", + "target": "SYSTEM_ERR", + "PatternLayout": { + "pattern": "${one.line.pattern}" + } + } + }, + "Loggers": { + "Root": { + "level": "INFO", + "AppenderRef": [ + { + "ref": "catalina" + }, + { + "ref": "console" + } + ] + }, + "Logger": [ + { + "name": "org.apache.catalina.core.ContainerBase.[Catalina].[localhost]", + "additivity": false, + "AppenderRef": { + "ref": "localhost" + } + }, + { + "name": "org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager]", + "additivity": false, + "AppenderRef": { + "ref": "manager" + } + }, + { + "name": "org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager]", + "additivity": false, + "AppenderRef": { + "ref": "host-manager" + } + } + ] + } + } +} \ No newline at end of file diff --git a/src/antora/modules/ROOT/examples/tomcat-jul-to-log4j/log4j2.xml b/src/antora/modules/ROOT/examples/tomcat-jul-to-log4j/log4j2.xml new file mode 100644 index 0000000..1d39b96 --- /dev/null +++ b/src/antora/modules/ROOT/examples/tomcat-jul-to-log4j/log4j2.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/antora/modules/ROOT/examples/tomcat-jul-to-log4j/log4j2.yaml b/src/antora/modules/ROOT/examples/tomcat-jul-to-log4j/log4j2.yaml new file mode 100644 index 0000000..abb0948 --- /dev/null +++ b/src/antora/modules/ROOT/examples/tomcat-jul-to-log4j/log4j2.yaml @@ -0,0 +1,98 @@ +# tag::license[] +# +# Copyright (C) 2024 Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] +Configuration: + Properties: + Property: + - name: "logs.dir" + value: "${sys:catalina.base}/logs" + - name: "one.line.pattern" + value: "%d{dd-MMM-yyyy HH:mm:ss.SSS} %p [%t] %C.%M %m%n" + Appenders: + RollingFile: + - name: "catalina" + filePattern: "${logs.dir}/catalina.%d{yyyy-MM-dd}.log" + PatternLayout: + pattern: "${one.line.pattern}" + DirectWriteRolloverStrategy: + Delete: + basePath: "${logs.dir}" + IfFileName: + regex: "catalina\.\d{4}-\d{2}-\d{2}\.log" + IfLastModified: + age: "P90D" + TimeBasedTriggeringPolicy: { } + - name: "localhost" + filePattern: "${logs.dir}/localhost.%d{yyyy-MM-dd}.log" + PatternLayout: + pattern: "${one.line.pattern}" + DirectWriteRolloverStrategy: + Delete: + basePath: "${logs.dir}" + IfFileName: + regex: "localhost\.\d{4}-\d{2}-\d{2}\.log" + IfLastModified: + age: "P90D" + TimeBasedTriggeringPolicy: { } + - name: "manager" + filePattern: "${logs.dir}/manager.%d{yyyy-MM-dd}.log" + PatternLayout: + pattern: "${one.line.pattern}" + DirectWriteRolloverStrategy: + Delete: + basePath: "${logs.dir}" + IfFileName: + regex: "manager\.\d{4}-\d{2}-\d{2}\.log" + IfLastModified: + age: "P90D" + TimeBasedTriggeringPolicy: { } + - name: "host-manager" + filePattern: "${logs.dir}/host-manager.%d{yyyy-MM-dd}.log" + PatternLayout: + pattern: "${one.line.pattern}" + DirectWriteRolloverStrategy: + Delete: + basePath: "${logs.dir}" + IfFileName: + regex: "host-manager\.\d{4}-\d{2}-\d{2}\.log" + IfLastModified: + age: "P90D" + TimeBasedTriggeringPolicy: { } + Console: + name: "console" + target: "SYSTEM_ERR" + PatternLayout: + pattern: "${one.line.pattern}" + Loggers: + Root: + level: "INFO" + AppenderRef: + - ref: "catalina" + - ref: "console" + Logger: + - name: "org.apache.catalina.core.ContainerBase.[Catalina].[localhost]" + additivity: false + AppenderRef: + ref: "localhost" + - name: "org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager]" + additivity: false + AppenderRef: + ref: "manager" + - name: "org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager]" + additivity: false + AppenderRef: + ref: "host-manager" diff --git a/src/antora/modules/ROOT/examples/tomcat-log4j/context.xml b/src/antora/modules/ROOT/examples/tomcat-log4j/context.xml new file mode 100644 index 0000000..64ddec6 --- /dev/null +++ b/src/antora/modules/ROOT/examples/tomcat-log4j/context.xml @@ -0,0 +1,34 @@ + + + + + + WEB-INF/web.xml + WEB-INF/tomcat-web.xml + ${catalina.base}/conf/web.xml + + + + + + + + diff --git a/src/antora/modules/ROOT/nav.adoc b/src/antora/modules/ROOT/nav.adoc new file mode 100644 index 0000000..3a87148 --- /dev/null +++ b/src/antora/modules/ROOT/nav.adoc @@ -0,0 +1,25 @@ +//// +// tag::license[] +// +// Copyright © 2024 Piotr P. Karwasz +// +// Licensed 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 +// +// https://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. +// +// end::license[] +//// + +* xref:guide.adoc[User guide] +* xref:components.adoc[Components] +** xref:components/tomcat-juli-to-log4j.adoc[] +** xref:components/tomcat-log4j.adoc[] +** xref:components/log4j-tomcat.adoc[] diff --git a/src/antora/modules/ROOT/pages/components.adoc b/src/antora/modules/ROOT/pages/components.adoc new file mode 100644 index 0000000..c1ab7b3 --- /dev/null +++ b/src/antora/modules/ROOT/pages/components.adoc @@ -0,0 +1,56 @@ +//// +// tag::license[] +// +// Copyright © 2024 Piotr P. Karwasz +// +// Licensed 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 +// +// https://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. +// +// end::license[] +//// + += Components + +Due to Tomcat's complex classloader architecture (cf. https://tomcat.apache.org/tomcat-10.1-doc/class-loader-howto.html[Class Loader How-TO]), the Copernik.eu extensions for Log4j and Tomcat has been split into three artifacts. +This way each of them can be deployed in a different classloader: + +* The `tomcat-juli-to-log4j` artifact needs to be in the same classloader as `tomcat-juli`: the _system_ classloader. +* The `tomcat-log4j` artifact needs to be in the same classloader as the Tomcat server classes: the _common_ or _server_ classloaders. +* The `log4j-tomcat` artifact needs to be in the same classloader as Log4j Core. +Depending on the deployment, this might be the _system_, _common_ or _webapp_ classloader. + +[#tomcat-juli-to-log4j] +== `tomcat-juli-to-log4j` + +The `tomcat-juli-to-log4j` artifact provides a bridge between Tomcat JUL and Log4j API. + +See xref:components/tomcat-juli-to-log4j.adoc[] for more details. + +include::partial$components/tomcat-juli-to-log4j.adoc[] + +[#tomcat-log4j] +== `tomcat-log4j` + +The `tomcat-log4j` artifact provides Tomcat components that improve its usage with Log4j. + +See xref:components/tomcat-log4j.adoc[] for more details. + +include::partial$components/tomcat-log4j.adoc[] + +[#log4j-tomcat] +== `log4j-tomcat` + +The `log4j-tomcat` artifact provides Log4j Core plugins that extend the possibility of the logging backend by providing Tomcat-specific functionalities. + +See xref:components/log4j-tomcat.adoc[] for more details. + +include::partial$components/log4j-tomcat.adoc[] diff --git a/src/antora/modules/ROOT/pages/components/log4j-tomcat.adoc b/src/antora/modules/ROOT/pages/components/log4j-tomcat.adoc new file mode 100644 index 0000000..5a37ba9 --- /dev/null +++ b/src/antora/modules/ROOT/pages/components/log4j-tomcat.adoc @@ -0,0 +1,438 @@ +//// +// tag::license[] +// +// Copyright © 2024 Piotr P. Karwasz +// +// Licensed 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 +// +// https://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. +// +// end::license[] +//// + += Log4j Core Plugins + +The xref:components.adoc#log4j-tomcat[`log4j-tomcat`] artifact contains three Log4j Core plugins that help to split logs between web applications: + +* The <> can be used to split loggers into separate +{log4j-api-url}/manual/architecture.html#LoggerContext[logger contexts], one context for each application. +* The <> can be used to retrieve the name of the current Tomcat engine, host or context and use it in a Log4j Core +{log4j-api-url}/manual/configuration.html[configuration file]. +* The <> injects the name of the current Tomcat engine, host and context into the context data of each event. + +[#installation] +== Generic installation + +The Log4j Core Plugins can be installed in two different ways: + +[#global-installation] +Global:: ++ +If you use Log4j Core as Tomcat's logging system, follow the +xref:components/tomcat-juli-to-log4j.adoc#installation[Tomcat JULI to Log4j API bridge installation instructions] +and add the `log4j-tomcat-{project-version}.jar` artifact to you `$CATALINA_BASE/bin/logging` folder. ++ +You can download the artifact from +{maven-base-url}/log4j-tomcat/{project-version}/[this Maven Central location]. + +[#web-app-installation] +Web application:: ++ +If you want to add the plugins to a single web application, add this dependency to your dependency management system: ++ +-- +include::partial$components/log4j-tomcat.adoc[] +-- + +[#TomcatContextSelector] +== Tomcat Context Selectors + +The Tomcat Context Selectors are a pair +{log4j-api-url}/manual/extending.html#ContextSelector[`ContextSelector`] +that splits loggers according to the value of the current context classloader. +The **name** of the logger contexts is determined as follows: + +* if the context classloader is the classloader of a web application, the name is of the form `///`, where: + +``:: +The name of the Tomcat Engine container. +See {tomcat-url}/config/engine.html[Tomcat Engine Container] for more details. + +``:: +The name of the Tomcat Host container. +See {tomcat-url}/config/host.html[Tomcat Host Container] for more details. + +``:: +The base file name of the Tomcat Context container. +See {tomcat-url}/config/context.html#Naming[Tomcat Context Naming] for more details. + +* if the context classloader is not the classloader of a web application, the name is `-tomcat`. + +Due to the Log4j Core automatic configuration procedure (see +{log4j-api-url}/manual/configuration.html#automatic-configuration[Configuration location]) you can: + +* Provide a configuration file for a single web application by creating a file named: ++ +-- +`log4j2///.` +-- ++ +on the classpath of the application, e.g. ++ +-- +`log4j2/Catalina/localhost/app.xml` +-- + +* Provide a configuration file for the global Tomcat logger context by creating a `log4j2-tomcat.xml` file. + +[WARNING] +==== +Loggers used by the libraries in +https://tomcat.apache.org/tomcat-9.0-doc/class-loader-howto.html#Class_Loader_Definitions[Tomcat's common classloader] +will be assigned to the web application that was active when the logger was created. +The assignment will be appropriate only if the library uses **instance** field to store application-specific loggers. + +Tomcat libraries use instance and static logger fields correctly to differentiate the log statements specific to a web application from the global ones. +Most third-party libraries, however, only use **static** logger fields. +The output of those libraries will be assigned to the global logger context or in the worst case scenario to the logger context of the first web application that initialized the library. +==== + +[#TomcatContextSelector-installation] +=== Installation + +[NOTE] +==== +Using Tomcat Context Selectors only makes sense if you installed the Copernik.eu Log4j Core Plugins globally. +In this section, we assume you followed the <>. +==== + +To use the Tomcat Context Selector, you need to set the +{log4j-api-url}/manual/systemproperties.html#log4j2.contextSelector[`log4j2.contextSelector`] +Log4j configuration property to one of: + +`eu.copernik.log4j.tomcat.TomcatContextSelector`:: +This selector creates synchronous loggers that append log events to the target resource on the calling thread. + +`eu.copernik.log4j.tomcat.TomcatAsyncContextSelector`:: +This selector creates asynchronous loggers. +See +{log4j-api-url}/manual/async.html[Asynchronous Loggers] +for more details. ++ +[WARNING] +===== +The `TomcatAsyncContextSelector` required additional dependencies on the classpath. + +Add `disruptor-{disruptor-version}.jar` to the `$CATALINA_BASE/bin/logging` folder. +You can download the artifact from +https://repo.maven.apache.org/maven2/com/lmax/disruptor/{disruptor-version}/[this Maven Central location]. + +===== + +This can be easily achieved, by creating a `log4j2.component.properties` file in the `$CATALINA_BASE/conf/logging` folder with the following content: + +[source,properties] +---- +log4j2.contextSelector = eu.copernik.log4j.tomcat.TomcatContextSelector +---- + +or + +[source,properties] +---- +log4j2.contextSelector = eu.copernik.log4j.tomcat.TomcatAsyncContextSelector +---- + +See +{log4j-api-url}/manual/systemproperties.html#property-sources[Log4j Property Sources] +for alternative ways to set a Log4j configuration property. + +[#TomcatLookup] +== Tomcat Lookup + +[cols="1h,4"] +|=== +| Syntax +| `+${tomcat:}+` + +where `` is one of the <>. +|=== + +The Tomcat Lookup is a +{log4j-api-url}/manual/lookups.html[Log4j Core Lookup] +that can be used in configuration files to retrieve parameters of the web application active on the current thread. + +The lookup uses the context classloader, so it can be used eagerly (`+${tomcat:}+`) in every value of the configuration file or lazily (`+$${tomcat:}+`) in the configuration attributes that accept runtime evaluation. +See +{log4j-api-url}/manual/configuration.html#lazy-property-substitution[Runtime Property Substitution] +for more details. + +The keys supported by the lookup are: + +.Tomcat Lookup supported keys +[cols="1m,4",id=TomcatLookup-keys] +|=== +| Key | Description + +| [[context.name]]context.name +| +The base name of the current Tomcat Context Container. + +See {tomcat-url}/config/context.html#Naming[Tomcat Context Naming] for more details. + +| [[context.logger]]context.logger +a| +Returns the name of the logger that captures all +https://jakarta.ee/specifications/servlet/6.1/apidocs/jakarta.servlet/jakarta/servlet/genericservlet#log(java.lang.String)[`GenericServlet.log()`] +method calls for the current web application, e.g. +-- +`org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[ROOT]` +-- + +| [[host.name]]host.name +| +The name of the current Tomcat Host Container. + +See {tomcat-url}/config/host.html[Tomcat Host Container] for more details. + +| [[host.logger]]host.logger +a| +Returns the name of the logger that captures all +https://jakarta.ee/specifications/servlet/6.1/apidocs/jakarta.servlet/jakarta/servlet/genericservlet#log(java.lang.String)[`GenericServlet.log()`] +method calls for the current Tomcat Host container, e.g. +-- +`org.apache.catalina.core.ContainerBase.[Catalina].[localhost]` +-- + +| [[engine.name]]engine.name +| +The name of the current Tomcat Engine Container. + +See {tomcat-url}/config/engine.html[Tomcat Engine Container] for more details. + +| [[engine.logger]]engine.logger +a| +Returns the name of the logger that captures all +https://jakarta.ee/specifications/servlet/6.1/apidocs/jakarta.servlet/jakarta/servlet/genericservlet#log(java.lang.String)[`GenericServlet.log()`] +method calls for the current Tomcat Engine container, e.g. +-- +`org.apache.catalina.core.ContainerBase.[Catalina]` +-- + +| [[classloader.webappName]]classloader.webappName +| +An alias for <>, +it returns the same value as `${classloader.webappName}` in a Tomcat default `logging.properties` file. + +See +{tomcat-url}/logging.html#Using_java.util.logging_(default)[Using `java.util.logging`] in Tomcat's documentation for details. + +| [[classloader.hostName]]classloader.hostName +| +An alias for <>, +it returns the same value as `${classloader.hostName}` in a Tomcat default `logging.properties` file. + +See +{tomcat-url}/logging.html#Using_java.util.logging_(default)[Using `java.util.logging`] in Tomcat's documentation for details. + +| [[classloader.serviceName]]classloader.serviceName +| +An alias for <>, +it returns the same value as `${classloader.serviceName}` in a Tomcat default `logging.properties` file. + +See +{tomcat-url}/logging.html#Using_java.util.logging_(default)[Using `java.util.logging`] in Tomcat's documentation for details. +|=== + +[#TomcatLookup-examples] +=== Configuration examples + +[TIP] +===== +Since the Tomcat Lookup returns `null`, whenever we are outside a web application context, it is useful to give a default value to its keys in the +{log4j-api-url}/manual/configuration.html#property-substitution[`Properties` section] +of the configuration file. + +For example, we can assign a default value to `+${tomcat:context.name}+` with the snippet below: + +[tabs] +==== +XML:: ++ +.Snippet from an {examples-url}/log4j-plugins/reusable.xml[example `log4j2.xml` file] +[source,xml,indent=0] +---- +include::example$log4j-tomcat/reusable.xml[tags=default;!ignore] +---- + +JSON:: ++ +.Snippet from an {examples-url}/log4j-plugins/reusable.json[example `log4j2.json` file] +[source,json,indent=0] +---- +include::example$log4j-tomcat/reusable.json[tags=default;!ignore] +---- + +YAML:: ++ +.Snippet from an {examples-url}/log4j-plugins/reusable.yaml[example `log4j2.yaml` file] +[source,yaml,indent=0] +---- +include::example$log4j-tomcat/reusable.yaml[tags=default;!ignore] +---- +==== + +The examples below all contain this definition. +===== + +[#single-configuration-multiple-contexts] +==== Single configuration file for multiple contexts + +If we use <> to split the loggers into one logger context per-application, we can still use a single configuration file. +To provide a different configuration to each context, we can use the Tomcat Lookup. + +The snippet below provides a rolling file appender named after the Tomcat Context, as in the +xref:components/tomcat-juli-to-log4j.adoc#configuration-log4j-core[standard configuration file]: + +[tabs] +==== +XML:: ++ +.Snippet from an {examples-url}/log4j-plugins/reusable.xml[example `log4j2.xml` file] +[source,xml,indent=0] +---- +include::example$log4j-tomcat/reusable.xml[tag=appender] +---- + +JSON:: ++ +.Snippet from an {examples-url}/log4j-plugins/reusable.json[example `log4j2.json` file] +[source,json,indent=0] +---- +include::example$log4j-tomcat/reusable.json[tag=appender] +---- + +YAML:: ++ +.Snippet from an {examples-url}/log4j-plugins/reusable.yaml[example `log4j2.yaml` file] +[source,yaml,indent=0] +---- +include::example$log4j-tomcat/reusable.yaml[tag=appender] +---- +==== + +<1> We name the log file after the context name. +For the global logger context we provide the fallback name `catalina`. + +[#single-context-dynamic-appenders] +==== Single context with dynamic appenders + +If we have a single logger context for the entire JVM, we can still split application-specific logs into separate log files. +To do that we just need to wrap the example above in a +{log4j-api-url}/manual/appenders/delegating.html#RoutingAppender[Routing Appender]. + +[tabs] +==== +XML:: ++ +.Snippet from an {examples-url}/log4j-plugins/routing.xml[example `log4j2.xml` file] +[source,xml,indent=0] +---- +include::example$log4j-tomcat/routing.xml[tag=appender] +---- + +JSON:: ++ +.Snippet from an {examples-url}/log4j-plugins/routing.json[example `log4j2.json` file] +[source,json,indent=0] +---- +include::example$log4j-tomcat/routing.json[tag=appender] +---- + +YAML:: ++ +.Snippet from an {examples-url}/log4j-plugins/routing.yaml[example `log4j2.yaml` file] +[source,yaml,indent=0] +---- +include::example$log4j-tomcat/routing.yaml[tag=appender] +---- +==== + +[#TomcatContextDataProvider] +== Tomcat Context Data Provider + +If log events from multiple web applications are written to the same target resource, we can tag the events to determine their origin. +See +{log4j-api-url}/manual/api.html#fish-tagging[Fish tagging] +for more information. + +The Tomcat Context Data Provider uses the Log4j +{log4j-api-url}/manual/extending.html#ContextDataProvider[`ContextDataProvider`] +extension point to inject the key/value pairs below into the context data map of each log event. + +.Tomcat context data key/value pairs +[cols="1m,4",id=TomcatContextDataProvider-keys] +|=== +| Key | Value + +| [[TomcatContextDataProvider-context.name]]context.name +| +The base name of the current Tomcat Context Container. + +See {tomcat-url}/config/context.html#Naming[Tomcat Context Naming] for more details. + +| [[TomcatContextDataProvider-host.name]]host.name +| +The name of the current Tomcat Host Container. + +See {tomcat-url}/config/host.html[Tomcat Host Container] for more details. + +| [[TomcatContextDataProvider-engine.name]]engine.name +| +The name of the current Tomcat Engine Container. + +See {tomcat-url}/config/engine.html[Tomcat Engine Container] for more details. + +|=== + +[WARNING] +==== +The Tomcat Context Data Provider is only useful if you installed the Copernik.eu Log4j Core Plugins using the +<>. + +The provider must be explicitly enabled by setting the +<> configuration property to `true`. +This can be done by adding to the `$CATALINA_BASE/conf/logging/log4j2.component.properties` file the following snippet: + +[source,properties] +---- +log4j2.tomcatContextDataEnabled = true +---- +==== + +[#configuration-properties] +== Configuration properties + +The Copernik.eu Log4j Core Plugins recognize the following +{log4j-api-url}/manual/systemproperties.html[Log4j configuration properties]: + +[id=log4j2.tomcatContextDataEnabled] +=== `log4j2.tomcatContextDataEnabled` + +[cols="1h,5"] +|=== +| Env. variable | `LOG4J_TOMCAT_CONTEXT_DATA_ENABLED` +| Type | `boolean` +| Default value | `false` +|=== + +If set to `true`, the context data map of each log event is enriched by Tomcat-specific properties. +See <> for more information. diff --git a/src/antora/modules/ROOT/pages/components/tomcat-juli-to-log4j.adoc b/src/antora/modules/ROOT/pages/components/tomcat-juli-to-log4j.adoc new file mode 100644 index 0000000..66b8493 --- /dev/null +++ b/src/antora/modules/ROOT/pages/components/tomcat-juli-to-log4j.adoc @@ -0,0 +1,104 @@ +//// +// tag::license[] +// +// Copyright © 2024 Piotr P. Karwasz +// +// Licensed 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 +// +// https://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. +// +// end::license[] +//// + += Tomcat JULI to Log4j API bridge + +Tomcat uses an internal logging API called +{tomcat-url}/logging.html[Tomcat JULI]. +The Tomcat JULI to Log4j API bridge contains an implementation of Tomcat JULI, which forwards all log events to +{log4j-api-url}/manual/api.html[Log4j API]. + +[#installation] +== Installation + +To install the bridge, you need to: + +. Create a `$CATALINA_BASE/bin/logging` folder and add the following content: + +* Add xref:components.adoc#tomcat-juli-to-log4j[`tomcat-jul-to-log4j-{project-version}.jar`]. +You can download the artifact from +{maven-base-url}/tomcat-jul-to-log4j/{project-version}/[this Maven Central location]. +* Add `log4j-api-{log4j-version}.jar`. +You can download the artifact from +https://repo.maven.apache.org/maven2/org/apache/logging/log4j/log4j-api/{log4j-version}[this Maven Central location]. +* Add a Log4j API implementation. +See +{log4j-api-url}/manual/installation.html#impl[Installing a logging implementation] +in the Log4j documentation site. + +. Create an empty `$CATALINA_BASE/conf/logging` folder for the configuration files of the logging backend. + +. Add the libraries to Tomcat's `CLASSPATH` environment variable: + +UNIX:: ++ +On a UNIX system, create a `$CATALINA_BASE/bin/setenv.sh` files with the following content: ++ +[source,shell,subs="+attributes"] +---- +include::example$setenv.sh[] +---- + +Windows:: ++ +Windows users start the +https://commons.apache.org/proper/commons-daemon/procrun.html#Procrun_monitor_application[Tomcat Monitor application], e.g. `$CATALINA_HOME/bin/tomcat{tomcat-major-version}w.exe` +and add the libraries to "Java Classpath" configuration entry in the "Java" tab. + +include::partial$tomcat-dirs.adoc[] + +[#configuration] +== Configuration + +You need to configure the logging implementation of your choice. + +[#configuration-log4j-core] +=== Log4j Core Configuration + +If you use +{log4j-api-url}/manual/implementation.html[Log4j Core] +as logging implementation, and you wish to keep the standard Tomcat log files, create a `$CATALINA_BASE/conf/logging/log4j2.xml` file like the one below: + +[tabs] +==== +XML:: ++ +.Example `log4j2.xml` file equivalent to Tomcat's standard configuration +[source,xml] +---- +include::example$tomcat-jul-to-log4j/log4j2.xml[tags=!license] +---- + +JSON:: ++ +.Example `log4j2.json` file equivalent to Tomcat's standard configuration +[source,json] +---- +include::example$tomcat-jul-to-log4j/log4j2.json[] +---- + +YAML:: ++ +.Example `log4j2.yaml` file equivalent to Tomcat's standard configuration +[source,yaml] +---- +include::example$tomcat-jul-to-log4j/log4j2.yaml[tags=!license] +---- +==== diff --git a/src/antora/modules/ROOT/pages/components/tomcat-log4j.adoc b/src/antora/modules/ROOT/pages/components/tomcat-log4j.adoc new file mode 100644 index 0000000..1a41b63 --- /dev/null +++ b/src/antora/modules/ROOT/pages/components/tomcat-log4j.adoc @@ -0,0 +1,79 @@ +//// +// tag::license[] +// +// Copyright © 2024 Piotr P. Karwasz +// +// Licensed 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 +// +// https://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. +// +// end::license[] +//// + += Tomcat components +:servlet-api-quote: Servlet API Specification https://jakarta.ee/specifications/servlet/6.0/jakarta-servlet-spec-6.0#web-application-class-loader[10.7.2] + +The xref:components.adoc#tomcat-log4j[`tomcat-log4j`] artifact contains Tomcat classloaders that delegate the Log4j API classes to the parent. + +[#classloaders] +== Classloaders + +One of the main obstacles to the usage of Log4j as a global logging backend for the server and all applications is the Servlet API parent-last delegation model: + +[quote,id=servlet-api,'{servlet-api-quote}'] +____ +The container should not allow applications to override or access the container’s implementation classes. +It is recommended also that the application class loader be implemented so that classes and resources packaged within the WAR are loaded in preference to classes and resources residing in container-wide library JARs. +____ + +This delegation model implies that applications that ship with their own copy of Log4j API will not use the global logging backend. +The `tomcat-log4j` artifact contains two classloaders that solve this problem by always looking for Log4j API in the parent classloader first. + +[#classloaders-installation] +=== Installation + +To use a global Log4j API for all web applications, you need to: + +include::partial$tomcat-dirs.adoc[] + +. Install Log4j API in either the _system_ or _common_ +{tomcat-url}/class-loader-howto.html[Tomcat classloader]: + +* If you wish to replace at the same time Tomcat's logging subsystem, follow the +xref:components/tomcat-juli-to-log4j.adoc#installation[Bridge installation instructions]. +* If you **do not** with to replace Tomcat's logging subsystem, add the `log4j-api-{log4j-version}.jar` artifact and a Log4j API implementation to the `$CATALINA_BASE/lib` folder of your Tomcat instance. +You can download the artifact from +https://repo.maven.apache.org/maven2/org/apache/logging/log4j/log4j-api/{log4j-version}[this Maven Central location]. +See +{log4j-api-url}/manual/installation.html#impl[Installing a logging implementation] for details on how to install the implementation. + +. Add the `tomcat-log4j-{project-version}.jar` artifact to the `$CATALINA_BASE/lib` folder of your Tomcat installation. +You can download the artifact from +{maven-base-url}/tomcat-log4j/{project-version}/[this Maven Central location]. + +. Configure the context of each web application to use +`eu.copernik.tomcat.log4j.loader.Log4jParallelWebappClassLoader` +as classloader. +You can do it by modifying the `$CATALINA_BASE/conf/context.xml` file to include a properly configured +{tomcat-url}/config/loader.html[`Loader` element]: ++ +[source,xml] +---- +include::example$tomcat-log4j/context.xml[tags=!license] +---- ++ +-- +<1> Specifies an alternative classloader to use. +-- ++ +See +{tomcat-url}/config/context.html#Defining_a_context[Defining a context] +in Tomcat documentation for more ways to define the context of a web application. diff --git a/src/antora/modules/ROOT/pages/guide.adoc b/src/antora/modules/ROOT/pages/guide.adoc new file mode 100644 index 0000000..63e3ed3 --- /dev/null +++ b/src/antora/modules/ROOT/pages/guide.adoc @@ -0,0 +1,273 @@ +//// +// tag::license[] +// +// Copyright © 2024 Piotr P. Karwasz +// +// Licensed 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 +// +// https://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. +// +// end::license[] +//// += Logging in Tomcat using Log4j Core + +Logging configuration in Java is complex, mostly due to the presence of multiple logging APIs and logging backends, that need to be configured separately. + +On a Tomcat server we might find: + +* Tomcat's own logging interface, called Tomcat JULI (cf. https://tomcat.apache.org/tomcat-11.0-doc/logging.html[Tomcat's documentation]). +This logging interface by default binds to `java.util.logging` (JUL). +* Each application can use its own logging API, and each library can use a different one. +The most popular are +https://www.slf4j.org/[SLF4J], +https://commons.apache.org/proper/commons-logging/index.html[Apache Commons Logging (JCL)], +https://github.com/jboss-logging/jboss-logging[JBoss Logging], +https://logging.apache.org/log4j/2.x/manual/api.html[Log4j API] +and https://docs.oracle.com/en/java/javase/17/docs/api/java.logging/java/util/logging/package-summary.html[`java.util.logging` (JUL)]. + +In this guide, we will present a way to bring all these logging APIs together and direct them to use a single instance of +https://logging.apache.org/log4j/2.x/manual/implementation.html[Log4j Core]. + +[IMPORTANT] +==== +We assume that all the web applications running on Tomcat are wired to forward all other logging APIs to Log4j API. +If that is not the case, see +https://logging.apache.org/log4j/2.x/manual/installation.html#impl-core-bridges[Installing bridges] +in Apache Log4j documentation. +==== + +[#installation] +== Installation + +To install all Copernik.eu plugins for Tomcat and Log4j: + +include::partial$tomcat-dirs.adoc[] + +* Download the `copernik-log4j-tomcat-{project-version}.zip` distribution archive available on the +https://github.com/copernik-eu/log4j-tomcat/releases/tag/v{project-version}[GitHub releases page]. +* Unzip the contents of the `overlay` folder of the archive in the `$CATALINA_BASE` folder of you Tomcat installation. +* Customize if necessary the `$CATALINA_BASE/bin/setenv-log4j.sh` file and move it to `$CATALINA_BASE/bin/setenv.sh`. +* Customize if necessary the `$CATALINA_BASE/conf/context-log4j.xml` file and move it to `$CATALINA_BASE/conf/context.xml`. + +[#configuration] +== Configuration + +Depending on the flexibility of configuration you want on your Tomcat server: + +* You can use separate +https://logging.apache.org/log4j/2.x/manual/architecture.html#LoggerContext[logging contexts] +for each application, which allows you to use a separate Log4j Core configuration for each application. +See <> for more information. +* You can use a single logger context with a single configuration file. +See <> for more information. + +[#multiple-contexts] +=== Separate logging contexts + +To use multiple logging contexts, you need to modify the `conf/logging/log4j2.component.properties` file in `$CATALINA_BASE` and enable one of the +xref:components/log4j-tomcat.adoc#TomcatContextSelector[Tomcat context selectors]: + +.Example `log4j2.component.properties` file +[source,properties] +---- +include::example$guide/multiple-contexts.properties[tags=!license] +---- + +After the context selector has been enabled, you will be able to add configuration files in the following locations of `$CATALINA_BASE`: + +`conf/logging/log4j2-tomcat.`:: ++ +This configuration file, if present, will be used by the Tomcat server itself. + +`conf/logging/log4j2///.`:: ++ +This configuration file will be used by the application with **base name** `` in the host `` of Tomcat's `` engine. + +`conf/logging/log4j2.xml`:: ++ +This configuration file will be used as a fallback if a more specific configuration file does not exist. + +[NOTE] +==== +Using multiple logger contexts will always correctly separate the logs issued by the web applications themselves. + +The logs issued by shared `$CATALINA_BASE/lib` libraries might, however, end up in the global Tomcat logger context if the libraries were not written with log separation in mind. +As far as we know, Tomcat's libraries behave correctly when used with multiple logger contexts. + +See +https://logging.apache.org/log4j/2.x/jakarta.html#log-separation[Log Separation] +on Apache Log4j site for more information on the topic. +==== + +[#multiple-contexts-examples] +=== Separate logging contexts examples + +[#multiple-contexts-multiple-files] +==== Multiple files + +To separate the logs of each application into their own log file, create a `conf/logging/log4j2.xml` file as the example below: + +[tabs] +==== +XML:: ++ +.{examples-url}/guide/multiple-contexts-multiple-files.xml[Example `log4j2.xml` file] +[source,xml,indent=0] +---- +include::example$guide/multiple-contexts-multiple-files.xml[tags=!license] +---- + +JSON:: ++ +.{examples-url}/guide/multiple-contexts-multiple-files.json[Example `log4j2.json` file] +[source,json,indent=0] +---- +include::example$guide/multiple-contexts-multiple-files.json[] +---- + +YAML:: ++ +.{examples-url}/guide/multiple-contexts-multiple-files.yaml[Example `log4j2.yaml` file] +[source,yaml,indent=0] +---- +include::example$guide/multiple-contexts-multiple-files.yaml[tags=!license] +---- +==== + +[#multiple-contexts-one-file] +==== Single appender + +If you prefer to send all logs to the console, make sure to mark the origin of each log event. +You can do it with a configuration file like: + +[tabs] +==== +XML:: ++ +.{examples-url}/guide/multiple-contexts-one-file.xml[Example `log4j2.xml` file] +[source,xml,indent=0] +---- +include::example$guide/multiple-contexts-one-file.xml[tags=!license] +---- + +JSON:: ++ +.{examples-url}/guide/multiple-contexts-one-file.json[Example `log4j2.json` file] +[source,json,indent=0] +---- +include::example$guide/multiple-contexts-one-file.json[] +---- + +YAML:: ++ +.{examples-url}/guide/multiple-contexts-one-file.yaml[Example `log4j2.yaml` file] +[source,yaml,indent=0] +---- +include::example$guide/multiple-contexts-one-file.yaml[tags=!license] +---- +==== + +<1> Use the +xref:components/log4j-tomcat.adoc#TomcatLookup[Tomcat lookup] +to store the context name as additional `context.name` key in the JSON template. + +[#one-context] +=== Single logging context + +To use a single logging context for the entire JVM, switch Log4j Core from its default context selector to either `BasicContextLoggerSelector` or `BasicAsyncContextLoggerSelector` by modifying the `conf/logging/log4j2.component.properties` file: + +.Example `log4j2.component.properties` file +[source,properties] +---- +include::example$guide/one-context.properties[tags=!license] +---- + +[#one-context-examples] +=== Single logging contexts examples + +[#one-context-multiple-files] +==== Multiple log files + +To separate the logs coming from each web application into its own file, you can use the +https://logging.apache.org/log4j/2.x/manual/appenders/delegating.html#RoutingAppender[Routing Appender] +as in the example below: + +[tabs] +==== +XML:: ++ +.{examples-url}/guide/one-context-multiple-files.xml[Example `log4j2.xml` file] +[source,xml,indent=0] +---- +include::example$guide/one-context-multiple-files.xml[tags=!license] +---- + +JSON:: ++ +.{examples-url}/guide/one-context-multiple-files.json[Example `log4j2.json` file] +[source,json,indent=0] +---- +include::example$guide/one-context-multiple-files.json[] +---- + +YAML:: ++ +.{examples-url}/guide/one-context-multiple-files.yaml[Example `log4j2.yaml` file] +[source,yaml,indent=0] +---- +include::example$guide/one-context-multiple-files.yaml[tags=!license] +---- +==== + +[#one-context-one-file] +==== Single appender + +If you prefer instead to send all log events to a single appender, make sure to mark each log event with the name of the web application they come from. +You can do it by enabling the +xref:components/log4j-tomcat.adoc#TomcatContextDataProvider[Tomcat context data provider]. +You can do it by modifying your `conf/logging/log4j2.component.properties` to look like: + +.Example `log4j2.component.properties` file +[source,properties] +---- +include::example$guide/one-context.properties[tags=!license] + +include::example$guide/enable-context-data.properties[tags=!license] +---- + +Once the context data provider is enabled, you can use a configuration file like this: + +[tabs] +==== +XML:: ++ +.{examples-url}/guide/one-context-one-file.xml[Example `log4j2.xml` file] +[source,xml,indent=0] +---- +include::example$guide/one-context-one-file.xml[tags=!license] +---- + +JSON:: ++ +.{examples-url}/guide/one-context-one-file.json[Example `log4j2.json` file] +[source,json,indent=0] +---- +include::example$guide/one-context-one-file.json[] +---- + +YAML:: ++ +.{examples-url}/guide/one-context-one-file.yaml[Example `log4j2.yaml` file] +[source,yaml,indent=0] +---- +include::example$guide/one-context-one-file.yaml[tags=!license] +---- +==== diff --git a/src/antora/modules/ROOT/pages/index.adoc b/src/antora/modules/ROOT/pages/index.adoc new file mode 100644 index 0000000..3296c02 --- /dev/null +++ b/src/antora/modules/ROOT/pages/index.adoc @@ -0,0 +1,72 @@ +//// +// tag::license[] +// +// Copyright © 2024 Piotr P. Karwasz +// +// Licensed 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 +// +// https://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. +// +// end::license[] +//// += Copernik.eu extensions for Log4j and Tomcat + +The Copernik.eu extensions for Log4j and Tomcat are a set of small artifacts that improve the integration between +https://logging.apache.org/log4j/index.html[Apache Log4j] +and +https://tomcat.apache.org/[Apache Tomcat]. + +Do you want to use Log4j Core as Tomcat's logging system?:: ++ +See the xref:guide.adoc[]. + +Are you looking for an in-depth description of the artifacts?:: ++ +See xref:components.adoc[]. + +== Download + +=== Source + +The source code of the project is maintained in the +https://github.com/copernik-eu/log4j-tomcat[`copernik-eu/log4j-tomcat` GitHub repository]. + +The source code of the latest release is available on the +https://github.com/copernik-eu/log4j-tomcat/releases/tag/v{project-version}[GitHub releases page]. + +=== Binary + +All the artifacts are published on +https://central.sonatype.com/[Maven Central] +under the `copernik.eu` group id. +See xref:components.adoc[] for more details on their coordinates. + +A binary archive containing all the artifacts together with Log4j {log4j-version} is available on the +https://github.com/copernik-eu/log4j-tomcat/releases/tag/v{project-version}[GitHub releases page]. + +== License + +The Copernik.eu extensions for Log4j and Tomcat are available under the +https://www.apache.org/licenses/LICENSE-2.0[Apache License, version 2.0]. + +== Security + +=== Supported Versions + +Only the most recent release of Copernik.eu Log4j2 Plugins is supported. + +=== Reporting a Vulnerability + +If you have encountered an unlisted security vulnerability or other unexpected behaviour that has security impact, please report them privately to the [maintainer](mailto:security@copernik.eu). + +=== Past Vulnerabilities + +None so far... diff --git a/src/antora/modules/ROOT/partials/components/log4j-tomcat.adoc b/src/antora/modules/ROOT/partials/components/log4j-tomcat.adoc new file mode 100644 index 0000000..dcd58db --- /dev/null +++ b/src/antora/modules/ROOT/partials/components/log4j-tomcat.adoc @@ -0,0 +1,41 @@ +//// +// tag::license[] +// +// Copyright © 2024 Piotr P. Karwasz +// +// Licensed 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 +// +// https://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. +// +// end::license[] +//// + + +[tabs] +==== +Maven:: ++ +[source,xml,subs="+attributes"] +---- + + eu.copernik + log4j-tomcat + {project-version} + +---- + +Gradle:: ++ +[source,groovy,subs="+attributes"] +---- +implementation 'eu.copernik:log4j-tomcat:{project-version}' +---- +==== diff --git a/src/antora/modules/ROOT/partials/components/tomcat-juli-to-log4j.adoc b/src/antora/modules/ROOT/partials/components/tomcat-juli-to-log4j.adoc new file mode 100644 index 0000000..0b4b965 --- /dev/null +++ b/src/antora/modules/ROOT/partials/components/tomcat-juli-to-log4j.adoc @@ -0,0 +1,41 @@ +//// +// tag::license[] +// +// Copyright © 2024 Piotr P. Karwasz +// +// Licensed 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 +// +// https://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. +// +// end::license[] +//// + + +[tabs] +==== +Maven:: ++ +[source,xml,subs="+attributes"] +---- + + eu.copernik + tomcat-juli-to-log4j + {project-version} + +---- + +Gradle:: ++ +[source,groovy,subs="+attributes"] +---- +implementation 'eu.copernik:tomcat-juli-to-log4j:{project-version}' +---- +==== diff --git a/src/antora/modules/ROOT/partials/components/tomcat-log4j.adoc b/src/antora/modules/ROOT/partials/components/tomcat-log4j.adoc new file mode 100644 index 0000000..90ddec1 --- /dev/null +++ b/src/antora/modules/ROOT/partials/components/tomcat-log4j.adoc @@ -0,0 +1,41 @@ +//// +// tag::license[] +// +// Copyright © 2024 Piotr P. Karwasz +// +// Licensed 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 +// +// https://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. +// +// end::license[] +//// + + +[tabs] +==== +Maven:: ++ +[source,xml,subs="+attributes"] +---- + + eu.copernik + tomcat-log4j + {project-version} + +---- + +Gradle:: ++ +[source,groovy,subs="+attributes"] +---- +implementation 'eu.copernik:tomcat-log4j:{project-version}' +---- +==== diff --git a/src/antora/modules/ROOT/partials/features/async-loggers.adoc b/src/antora/modules/ROOT/partials/features/async-loggers.adoc new file mode 100644 index 0000000..4092684 --- /dev/null +++ b/src/antora/modules/ROOT/partials/features/async-loggers.adoc @@ -0,0 +1,59 @@ +//// +// tag::license[] +// +// Copyright © 2024 Piotr P. Karwasz +// +// Licensed 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 +// +// https://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. +// +// end::license[] +//// + 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. +//// + +// This file exists in both the 2.x and 3.x branches. +// It contains the dependencies required to enable Asynchronous Loggers. + +[tabs] +==== +Maven:: ++ +[source,xml,subs="+attributes"] +---- + + com.lmax + disruptor + {disruptor-version} + runtime + +---- + +Gradle:: ++ +[source,groovy,subs="+attributes"] +---- +runtimeOnly 'com.lmax:disruptor:{disruptor-version}' +---- +==== diff --git a/src/antora/modules/ROOT/partials/tomcat-dirs.adoc b/src/antora/modules/ROOT/partials/tomcat-dirs.adoc new file mode 100644 index 0000000..6039d47 --- /dev/null +++ b/src/antora/modules/ROOT/partials/tomcat-dirs.adoc @@ -0,0 +1,40 @@ +//// +// tag::license[] +// +// Copyright © 2024 Piotr P. Karwasz +// +// Licensed 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 +// +// https://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. +// +// end::license[] +//// + +.Click here for a definition of `CATALINA_BASE` and `CATALINA_HOME` +[%collapsible] +==== +A Tomcat installation can be split in two separate folders: + +`CATALINA_HOME`:: This is the folder that contains the code of the server and the default configuration of Tomcat instances. + +`CATALINA_BASE`:: This is the folder that contains the runtime configuration and working directories of a specific Tomcat instance. + +The typical location of these folders varies between OSes: + +Debian:: ++ +On Debian and derived GNU/Linux distributions `CATALINA_BASE` is located in the `/var/lib` folder (e.g. `/var/lib/tomcat{tomcat-major-version}`). +`CATALINA_HOME` on the other hand is located in `/usr/share` (e.g. `/usr/share/tomcat{tomcat-major-version}`). + +Windows:: ++ +If you installed Tomcat from the MSI package, both `CATALINA_BASE` and `CATALINA_HOME` point to the same subfolder of `C:\Program Files\Apache Software Foundation`, e.g. `C:\Program Files\Apache Software Foundation/Tomcat {tomcat-minor-version}`. +==== diff --git a/src/headers/adoc.txt b/src/headers/adoc.txt new file mode 100644 index 0000000..6cdfa86 --- /dev/null +++ b/src/headers/adoc.txt @@ -0,0 +1,19 @@ +//// +// tag::license[] +// +// Copyright © $YEAR Piotr P. Karwasz +// +// Licensed 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 +// +// https://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. +// +// end::license[] +//// \ No newline at end of file diff --git a/src/headers/java.txt b/src/headers/java.txt new file mode 100644 index 0000000..2e81cfd --- /dev/null +++ b/src/headers/java.txt @@ -0,0 +1,15 @@ +/* + * Copyright © $YEAR Piotr P. Karwasz + * + * Licensed 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 + * + * https://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. + */ \ No newline at end of file diff --git a/src/headers/xml.txt b/src/headers/xml.txt new file mode 100644 index 0000000..6505847 --- /dev/null +++ b/src/headers/xml.txt @@ -0,0 +1,17 @@ + \ No newline at end of file diff --git a/src/headers/yaml.txt b/src/headers/yaml.txt new file mode 100644 index 0000000..c634a4a --- /dev/null +++ b/src/headers/yaml.txt @@ -0,0 +1,17 @@ +# tag::license[] +# +# Copyright (C) $YEAR Piotr P. Karwasz +# +# Licensed 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 +# +# https://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. +# +# end::license[] \ No newline at end of file diff --git a/tomcat-juli-to-log4j/pom.xml b/tomcat-juli-to-log4j/pom.xml index e40dec9..2fd3c6e 100644 --- a/tomcat-juli-to-log4j/pom.xml +++ b/tomcat-juli-to-log4j/pom.xml @@ -1,5 +1,6 @@ - + ~ + ~ end::license[] --> 4.0.0 @@ -22,7 +24,6 @@ 3.0.0-SNAPSHOT - eu.copernik tomcat-juli-to-log4j Tomcat JULI to Log4j API bridge Tomcat JULI implementation that forwards to the Log4j API. diff --git a/tomcat-juli-to-log4j/src/test/resources/log4j2-test.xml b/tomcat-juli-to-log4j/src/test/resources/log4j2-test.xml index 69ec410..8c467ee 100644 --- a/tomcat-juli-to-log4j/src/test/resources/log4j2-test.xml +++ b/tomcat-juli-to-log4j/src/test/resources/log4j2-test.xml @@ -1,19 +1,21 @@ - + ~ + ~ end::license[] --> diff --git a/tomcat-log4j/pom.xml b/tomcat-log4j/pom.xml index 884c0b2..cc16dc5 100644 --- a/tomcat-log4j/pom.xml +++ b/tomcat-log4j/pom.xml @@ -1,5 +1,6 @@ - + ~ + ~ end::license[] --> 4.0.0 diff --git a/tomcat-log4j/src/main/java/eu/copernik/tomcat/log4j/loader/Log4jParallelWebappClassLoader.java b/tomcat-log4j/src/main/java/eu/copernik/tomcat/log4j/loader/Log4jParallelWebappClassLoader.java index e580b40..7ec32f1 100644 --- a/tomcat-log4j/src/main/java/eu/copernik/tomcat/log4j/loader/Log4jParallelWebappClassLoader.java +++ b/tomcat-log4j/src/main/java/eu/copernik/tomcat/log4j/loader/Log4jParallelWebappClassLoader.java @@ -34,7 +34,7 @@ *
  * <Context>
  *     ...
- *     <Loader loaderClass="eu.copernik.log4j.tomcat.Log4jParallelWebappClassLoader"/>
+ *     <Loader loaderClass="eu.copernik.tomcat.log4j.loader.Log4jParallelWebappClassLoader"/>
  * </Context>
  * 
* @@ -44,9 +44,7 @@ */ public class Log4jParallelWebappClassLoader extends ParallelWebappClassLoader { - public Log4jParallelWebappClassLoader() { - super(); - } + public Log4jParallelWebappClassLoader() {} public Log4jParallelWebappClassLoader(final ClassLoader parent) { super(parent); @@ -65,7 +63,7 @@ protected boolean filter(final String name, final boolean isClassName) { @SuppressFBWarnings("DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED") public Log4jParallelWebappClassLoader copyWithoutTransformers() { final Log4jParallelWebappClassLoader result = new Log4jParallelWebappClassLoader(getParent()); - super.copyStateWithoutTransformers(result); + copyStateWithoutTransformers(result); startUnchecked(result); return result; }