Codebase list apache-log4j2 / 973dfd4
New upstream version 2.19.0 Emmanuel Bourg 1 year, 4 months ago
252 changed file(s) with 7013 addition(s) and 4272 deletion(s). Raw diff Collapse all Expand all
2727 steps:
2828
2929 - name: Checkout repository
30 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1
30 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2
3131
3232 # JDK 11 is needed for the build.
3333 # Search `maven-toolchains-plugin` usages for details.
3434 - name: Set up JDK 11
35 uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1
35 uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1
3636 with:
3737 distribution: temurin
3838 java-version: 11
4343 # JDK 8 is needed for the build, and it is the primary bytecode target.
4444 # Hence, JDK 8 is set up after 11, so that JAVA_HOME used by Maven during build will point to 8.
4545 - name: Set up JDK 8
46 uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1
46 uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1
4747 with:
4848 distribution: temurin
4949 java-version: 8
6363 package
6464
6565 - name: Upload built sources
66 uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # 3.0.0
66 uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # 3.1.0
6767 with:
6868 name: benchmarks.jar
6969 path: log4j-perf/target/benchmarks.jar
8686 steps:
8787
8888 - name: Checkout repository
89 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1
89 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2
9090
9191 - name: Download built sources
9292 uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 # 3.0.0
9595 path: log4j-perf/target
9696
9797 - name: Set up JDK ${{ matrix.jdk }}
98 uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1
98 uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1
9999 with:
100100 distribution: temurin
101101 java-version: ${{ matrix.jdk }}
191191 steps:
192192
193193 - name: Checkout repository
194 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1
194 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2
195195 with:
196196 ref: gh-pages
197197
198198 - name: Setup Python 3
199 uses: actions/setup-python@d09bd5e6005b175076f227b13d9730d56e9dcfcb # 4.0.0
199 uses: actions/setup-python@b55428b1882923874294fa556849718a1d7f2ca5 # 4.2.0
200200 with:
201201 python-version: 3.x
202202
2727 build:
2828
2929 runs-on: ${{ matrix.os }}
30
30 # Based on: https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
31 env:
32 MAVEN_OPTS: -Xms3072m -Xmx3072m
3133 strategy:
3234 matrix:
3335 os: [ ubuntu-latest, windows-latest, macos-latest ]
3537 steps:
3638
3739 - name: Checkout repository
38 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1
40 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2
3941
4042 # JDK 11 is needed for the build.
4143 # Search `maven-toolchains-plugin` usages for details.
4244 - name: Setup JDK 11
43 uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1
45 uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1
4446 with:
4547 distribution: temurin
4648 java-version: 11
5153 # JDK 8 is needed for the build, and it is the primary bytecode target.
5254 # Hence, JDK 8 is set up after 11, so that JAVA_HOME used by Maven during build will point to 8.
5355 - name: Setup JDK 8
54 uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1
56 uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1
5557 with:
5658 distribution: temurin
5759 java-version: 8
101103 deploy:
102104
103105 runs-on: ubuntu-latest
106 env:
107 MAVEN_OPTS: -Xms3072m -Xmx3072m
104108 needs: build
105109 if: github.repository == 'apache/logging-log4j2' && github.ref == 'refs/heads/release-2.x'
106110
107111 steps:
108112
109113 - name: Checkout repository
110 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1
114 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2
111115
112116 # JDK 11 is needed for the build.
113117 # Search `maven-toolchains-plugin` usages for details.
114118 - name: Setup JDK 11
115 uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1
119 uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1
116120 with:
117121 distribution: temurin
118122 java-version: 11
123127 # JDK 8 is needed for the build, and it is the primary bytecode target.
124128 # Hence, JDK 8 is set up after 11, so that JAVA_HOME used by Maven during build will point to 8.
125129 - name: Setup JDK 8
126 uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1
130 uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1
127131 with:
128132 distribution: temurin
129133 java-version: 8
4444 steps:
4545
4646 - name: Checkout repository
47 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1
47 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2
4848
4949 # Initializes the CodeQL tools for scanning.
5050 - name: Initialize CodeQL
51 uses: github/codeql-action/init@v2
51 uses: github/codeql-action/init@b398f525a5587552e573b247ac661067fafa920b # 2.1.22
5252 with:
5353 languages: ${{ matrix.language }}
5454 # If you wish to specify custom queries, you can do so here or in a config file.
5959 # JDK 11 is needed for the build.
6060 # Search `maven-toolchains-plugin` usages for details.
6161 - name: Setup JDK 11
62 uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1
62 uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1
6363 with:
6464 distribution: temurin
6565 java-version: 11
7070 # JDK 8 is needed for the build, and it is the primary bytecode target.
7171 # Hence, JDK 8 is set up after 11, so that JAVA_HOME used by Maven during build will point to 8.
7272 - name: Setup JDK 8
73 uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1
73 uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1
7474 with:
7575 distribution: temurin
7676 java-version: 8
8888 --global-toolchains ".github/workflows/maven-toolchains.xml"
8989
9090 - name: Perform CodeQL Analysis
91 uses: github/codeql-action/analyze@935969c6f771d9f0a35efa2ae9cf7c10d9886ca3 # 2.8.5
91 uses: github/codeql-action/analyze@b398f525a5587552e573b247ac661067fafa920b # 2.1.22
3737 steps:
3838
3939 - name: "Checkout code"
40 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1
40 uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2
4141 with:
4242 persist-credentials: false
4343
4444 - name: "Run analysis"
45 uses: ossf/scorecard-action@3e15ea8318eee9b333819ec77a36aca8d39df13e # 1.1.1
45 uses: ossf/scorecard-action@ce330fde6b1a5c9c75b417e7efc510b822a35564 # 1.1.2
4646 with:
4747 results_file: results.sarif
4848 results_format: sarif
5454 publish_results: true
5555
5656 - name: "Upload artifact"
57 uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # 3.0.0
57 uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # 3.1.0
5858 with:
5959 name: SARIF file
6060 path: results.sarif
6161 retention-days: 5
6262
6363 - name: "Upload to code-scanning"
64 uses: github/codeql-action/upload-sarif@935969c6f771d9f0a35efa2ae9cf7c10d9886ca3 # 2.8.5
64 uses: github/codeql-action/upload-sarif@b398f525a5587552e573b247ac661067fafa920b # 2.1.22
6565 with:
6666 sarif_file: results.sarif
1313 See the License for the specific language governing permissions and
1414 limitations under the License.
1515 -->
16
1617 # Requirements
1718
1819 * JDK 8 and 9+
2223 <a name="toolchains"></a>
2324 # Configuring Maven Toolchains
2425
25 Maven Toolchains is used to employ both JDKs during compilation.
26 Maven Toolchains is used to employ multiple JDKs required for compilation.
2627 You either need to have a user-level configuration in `~/.m2/toolchains.xml` or explicitly provide one to the Maven: `./mvnw --global-toolchains /path/to/toolchains.xml`.
27 See `.github/workflows/maven-toolchains.xml` used by CI for a sample Maven Toolchains configuration.
28 See [`.github/workflows/maven-toolchains.xml`](.github/workflows/maven-toolchains.xml) used by CI for a sample Maven Toolchains configuration.
2829 Note that this file requires `JAVA_HOME_8_X64` and `JAVA_HOME_11_X64` environment variables to be defined, though these can very well be hardcoded.
2930
31 <a name="building"></a>
3032 # Building the sources
3133
3234 You can build and verify the sources as follows:
3335
3436 ./mvnw verify
3537
36 To speed up build, you can skip verification and increase concurrency:
38 `verify` goal runs validation and test steps next to building (i.e., compiling) the sources.
39 To speed up the build, you can skip verification:
3740
38 ./mvwn -DskipTests -T8C package
41 ./mvnw -DskipTests package
3942
40 If you want to install generated artifacts to your local Maven repository, replace above `veriy` and/or `package` goals with `install`.
43 If you want to install generated artifacts to your local Maven repository, replace above `verify` and/or `package` goals with `install`.
4144
45 <a name="dns"></a>
46 ## DNS lookups in tests
47
48 Note that if your `/etc/hosts` file does not include an entry for your computer's hostname, then
49 many unit tests may execute slow due to DNS lookups to translate your hostname to an IP address in
50 [`InetAddress.getLocalHost()`](http://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html#getLocalHost()).
51 To remedy this, you can execute the following:
52
53 printf '127.0.0.1 %s\n::1 %s\n' `hostname` `hostname` | sudo tee -a /etc/hosts
54
55 <a name="website"></a>
4256 # Building the website and manual
4357
4458 You can build the website and manual as follows:
0 <!---
1 Licensed to the Apache Software Foundation (ASF) under one or more
2 contributor license agreements. See the NOTICE file distributed with
3 this work for additional information regarding copyright ownership.
4 The ASF licenses this file to You under the Apache License, Version 2.0
5 (the "License"); you may not use this file except in compliance with
6 the License. You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 -->
16
017 # [Apache Log4j 2](https://logging.apache.org/log4j/2.x/)
118
219 Apache Log4j 2 is an upgrade to Log4j that provides significant improvements over its predecessor, Log4j 1.x,
1633 ## Usage
1734
1835 Users should refer to [Maven, Ivy, Gradle, and SBT Artifacts](http://logging.apache.org/log4j/2.x/maven-artifacts.html)
19 on the Log4j web site for instructions on how to include Log4j into their project using their chosen build tool.
36 on the Log4j website for instructions on how to include Log4j into their project using their chosen build tool.
2037
2138 Basic usage of the `Logger` API:
2239
93110
94111 ## Building From Source
95112
96 Log4j requires Apache Maven 3.x. To build from source and install to your local Maven repository, execute the following:
97
98 ```sh
99 mvn install
100 ```
113 See [the detailed build instructions](BUILDING.md) on how to build to the project and website from sources.
101114
102115 ## Contributing
103116
104 We love contributions! Take a look at
105 [our contributing page](https://github.com/apache/logging-log4j2/blob/master/CONTRIBUTING.md).
117 We love contributions!
118 Take a look at [our contributing page](CONTRIBUTING.md).
1313 See the License for the specific language governing permissions and
1414 limitations under the License.
1515 -->
16 # Apache Log4j 2.18.0 Release Notes
16 # Apache Log4j 2.19.0 Release Notes
1717
18 The Apache Log4j 2 team is pleased to announce the Log4j 2.18.0 release!
18 The Apache Log4j 2 team is pleased to announce the Log4j 2.19.0 release!
1919
2020 Apache Log4j is a well known framework for logging application behavior. Log4j 2 is an upgrade
2121 to Log4j that provides significant improvements over its predecessor, Log4j 1.x, and provides
2929 This release primarily contains bug fixes and minor enhancements.
3030
3131 Due to a break in compatibility in the SLF4J binding, Log4j now ships with two versions of the SLF4J to Log4j adapters.
32 log4j-slf4j-impl should be used with SLF4J 1.7.x and earlier and log4j-slf4j18-impl should be used with SLF4J 1.8.x and
33 later. SLF4J-2.0.0 alpha releases are not fully supported. See https://issues.apache.org/jira/browse/LOG4J2-2975 and
34 https://jira.qos.ch/browse/SLF4J-511.
32 log4j-slf4j-impl should be used with SLF4J 1.7.x and earlier and log4j-slf4j2-impl should be used with SLF4J 2.x and
33 later. SLF4J-1.8.x is no longer supported as a GA release never occurred.
3534
36 The Log4j 2.18.0 API, as well as many core components, maintains binary compatibility with previous releases.
35 The Log4j 2.19.0 API, as well as many core components, maintains binary compatibility with previous releases.
3736
38 ## GA Release 2.18.0
37 ## GA Release 2.19.0
3938
4039 Changes in this version include:
4140
4241 ### New Features
43 * [LOG4J2-3495](https://issues.apache.org/jira/browse/LOG4J2-3495):
44 Add MutableThreadContextMapFilter.
45 * [LOG4J2-3472](https://issues.apache.org/jira/browse/LOG4J2-3472):
46 Add support for custom LMAX disruptor WaitStrategy configuration.
47 * [LOG4J2-3419](https://issues.apache.org/jira/browse/LOG4J2-3419):
48 Add support for custom Log4j 1.x levels.
49 * [LOG4J2-3440](https://issues.apache.org/jira/browse/LOG4J2-3440):
50 Add support for adding and retrieving appenders in Log4j 1.x bridge.
51 * [LOG4J2-3362](https://issues.apache.org/jira/browse/LOG4J2-3362):
52 Add support for Jakarta Mail API in the SMTP appender.
53 * [LOG4J2-3483](https://issues.apache.org/jira/browse/LOG4J2-3483):
54 Add support for Apache Extras' RollingFileAppender in Log4j 1.x bridge.
55 * [LOG4J2-3538](https://issues.apache.org/jira/browse/LOG4J2-3538):
56 Add support for 24 colors in highlighting Thanks to Pavel_K.
42 * [LOG4J2-3583](https://issues.apache.org/jira/browse/LOG4J2-3583):
43 Add support for SLF4J2 stack-valued MDC. Thanks to Pierrick Terrettaz.
44 * [LOG4J2-2975](https://issues.apache.org/jira/browse/LOG4J2-2975):
45 Add implementation of SLF4J2 fluent API. Thanks to Daniel Gray.
5746
5847 ### Fixed Bugs
59 * [LOG4J2-3339](https://issues.apache.org/jira/browse/LOG4J2-3339):
60 DirectWriteRolloverStrategy should use the current time when creating files.
61 * [LOG4J2-3534](https://issues.apache.org/jira/browse/LOG4J2-3534):
62 Fix LevelRangeFilterBuilder to align with log4j1's behavior.
63 * [LOG4J2-3527](https://issues.apache.org/jira/browse/LOG4J2-3527):
64 Don't use Paths.get() to avoid circular file systems.
65 * [LOG4J2-3490](https://issues.apache.org/jira/browse/LOG4J2-3490):
66 The DirectWriteRolloverStrategy was not detecting the correct index to use during startup.
67 * [LOG4J2-3432](https://issues.apache.org/jira/browse/LOG4J2-3432):
68 SizeBasedTriggeringPolicy would fail to rename files properly when integer pattern contained a leading zero.
69 * [LOG4J2-3491](https://issues.apache.org/jira/browse/LOG4J2-3491):
70 Async Loggers were including the location information by default. Thanks to Avihai Marchiano.
71 * [LOG4J2-1376](https://issues.apache.org/jira/browse/LOG4J2-1376):
72 Allow enterprise id to be an OID fragment.
73 * [LOG4J2-3493](https://issues.apache.org/jira/browse/LOG4J2-3493):
74 ClassArbiter's newBuilder method referenced the wrong class. Thanks to Dmytro Voloshyn.
75 * [LOG4J2-3481](https://issues.apache.org/jira/browse/LOG4J2-3481):
76 HttpWatcher did not pass credentials when polling.
77 * [LOG4J2-3482](https://issues.apache.org/jira/browse/LOG4J2-3482):
78 UrlConnectionFactory.createConnection now accepts an AuthorizationProvider as a parameter.
79 * [LOG4J2-3477](https://issues.apache.org/jira/browse/LOG4J2-3477):
80 Add the missing context stack to JsonLayout template. Thanks to filipc.
81 * [LOG4J2-3393](https://issues.apache.org/jira/browse/LOG4J2-3393):
82 Improve JsonTemplateLayout performance.
83 * [LOG4J2-3424](https://issues.apache.org/jira/browse/LOG4J2-3424):
84 Properties defined in configuration using a value attribute (as opposed to element) are read correctly.
85 * [LOG4J2-3413](https://issues.apache.org/jira/browse/LOG4J2-3413):
86 Fix resolution of non-Log4j properties.
87 * [LOG4J2-3423](https://issues.apache.org/jira/browse/LOG4J2-3423):
88 JAR file containing Log4j configuration isn't closed. Thanks to Radim Tlusty.
89 * [LOG4J2-3425](https://issues.apache.org/jira/browse/LOG4J2-3425):
90 Syslog appender lacks the SocketOptions setting. Thanks to Jiří Smolík.
91 * [](https://issues.apache.org/jira/browse/LOG4J2-3425):
92 Improve validation and reporting of configuration errors.
93 * [](https://issues.apache.org/jira/browse/LOG4J2-3425):
94 Log4j 1.2 bridge should generate Log4j 2.x messages based on the parameter runtime type.
95 * [LOG4J2-3426](https://issues.apache.org/jira/browse/LOG4J2-3426):
96 Log4j 1.2 bridge should not wrap components unnecessarily. Thanks to Pooja Pandey.
97 * [LOG4J2-3418](https://issues.apache.org/jira/browse/LOG4J2-3418):
98 Fixes Spring Boot logging system registration in a multi-application environment.
99 * [LOG4J2-3040](https://issues.apache.org/jira/browse/LOG4J2-3040):
100 Avoid ClassCastException in JeroMqManager with custom LoggerContextFactory #791. Thanks to LF-Lin.
101 * [](https://issues.apache.org/jira/browse/LOG4J2-3040):
102 Fix minor typo #792. Thanks to LF-Lin.
103 * [LOG4J2-3439](https://issues.apache.org/jira/browse/LOG4J2-3439):
104 Fixes default SslConfiguration, when a custom keystore is used. Thanks to Jayesh Netravali.
105 * [LOG4J2-3447](https://issues.apache.org/jira/browse/LOG4J2-3447):
106 Fixes appender concurrency problems in Log4j 1.x bridge. Thanks to Pooja Pandey.
107 * [LOG4J2-3452](https://issues.apache.org/jira/browse/LOG4J2-3452):
108 Fix and test for race condition in FileUtils.mkdir(). Thanks to Stefan Vodita.
109 * [LOG4J2-3458](https://issues.apache.org/jira/browse/LOG4J2-3458):
110 LocalizedMessage logs misleading errors on the console.
111 * [LOG4J2-3359](https://issues.apache.org/jira/browse/LOG4J2-3359):
112 Fixes the syslog appender in Log4j 1.x bridge, when used with a custom layout. Thanks to Tukesh.
113 * [LOG4J2-3359](https://issues.apache.org/jira/browse/LOG4J2-3359):
114 log4j-1.2-api 2.17.2 throws NullPointerException while removing appender with name as null. Thanks to Rajesh.
115 * [LOG4J2-2872](https://issues.apache.org/jira/browse/LOG4J2-2872):
116 Fix problem with non-uppercase custom levels. Thanks to Alla Gofman.
117 * [LOG4J2-3475](https://issues.apache.org/jira/browse/LOG4J2-3475):
118 Add missing message parameterization in RegexFilter. Thanks to Jeremy Lin.
119 * [LOG4J2-3428](https://issues.apache.org/jira/browse/LOG4J2-3428):
120 Update 3rd party dependencies for 2.18.0.
121 * [LOG4J2-3531](https://issues.apache.org/jira/browse/LOG4J2-3531):
122 Fix parsing error, when XInclude is disabled. Thanks to Simo Nikula.
123 * [LOG4J2-3537](https://issues.apache.org/jira/browse/LOG4J2-3537):
124 Fixes problem with wrong ANSI escape code for bright colors Thanks to Pavel_K.
48 * [LOG4J2-3578](https://issues.apache.org/jira/browse/LOG4J2-3578):
49 Generate new SSL certs for testing.
50 * [LOG4J2-3556](https://issues.apache.org/jira/browse/LOG4J2-3556):
51 Make JsonTemplateLayout stack trace truncation operate for each label block. Thanks to Arthur Gavlyukovskiy.
52 * [LOG4J2-3550](https://issues.apache.org/jira/browse/LOG4J2-3550):
53 SystemPropertyArbiter was assigning the value as the name. Thanks to DongjianPeng.
54 * [LOG4J2-3560](https://issues.apache.org/jira/browse/LOG4J2-3560):
55 Logger$PrivateConfig.filter(Level, Marker, String) was allocating empty varargs array. Thanks to David Schlosnagle.
56 * [LOG4J2-3561](https://issues.apache.org/jira/browse/LOG4J2-3561):
57 Allows a space separated list of style specifiers in the %style pattern for consistency with %highlight. Thanks to Robert Papp.
58 * [LOG4J2-3564](https://issues.apache.org/jira/browse/LOG4J2-3564):
59 Fix NPE in `log4j-to-jul` in the case the root logger level is null.
60 * [LOG4J2-3545](https://issues.apache.org/jira/browse/LOG4J2-3545):
61 Add correct manifest entries for OSGi to log4j-jcl Thanks to Johan Compagner.
62 * [LOG4J2-3565](https://issues.apache.org/jira/browse/LOG4J2-3565):
63 Fix RollingRandomAccessFileAppender with DirectWriteRolloverStrategy can't create the first log file of different directory.
64 * [LOG4J2-3579](https://issues.apache.org/jira/browse/LOG4J2-3579):
65 Fix ServiceLoaderUtil behavior in the presence of a SecurityManager. Thanks to Boris Unckel.
66 * [LOG4J2-3559](https://issues.apache.org/jira/browse/LOG4J2-3559):
67 Fix resolution of properties not starting with `log4j2.`. Thanks to Gary Gregory.
68 * [LOG4J2-3557](https://issues.apache.org/jira/browse/LOG4J2-3557):
69 Fix recursion between Log4j 1.2 LogManager and Category. Thanks to Andreas Leitgeb.
70 * [LOG4J2-3587](https://issues.apache.org/jira/browse/LOG4J2-3587):
71 Fix regression in Rfc5424Layout default values. Thanks to Tomas Micko.
72 * [LOG4J2-3548](https://issues.apache.org/jira/browse/LOG4J2-3548):
73 Improve support for passwordless keystores. Thanks to Kristof Farkas-Pall.
74 * [LOG4J2-708](https://issues.apache.org/jira/browse/LOG4J2-708):
75 Add async support to `Log4jServletFilter`.
12576
12677 ### Changes
127 * [LOG4J2-3536](https://issues.apache.org/jira/browse/LOG4J2-3536):
128 Upgrade the Flume Appender to Flume 1.10.0
129 * [LOG4J2-3516](https://issues.apache.org/jira/browse/LOG4J2-3516):
130 Move perf tests to log4j-core-its
131 * [LOG4J2-3506](https://issues.apache.org/jira/browse/LOG4J2-3506):
132 Support Spring 2.6.x.
133 * [LOG4J2-3473](https://issues.apache.org/jira/browse/LOG4J2-3473):
134 Make the default disruptor WaitStrategy used by Async Loggers garbage-free.
135 * [LOG4J2-3476](https://issues.apache.org/jira/browse/LOG4J2-3476):
136 Do not throw UnsupportedOperationException when JUL ApiLogger::setLevel is called.
137 * [LOG4J2-3427](https://issues.apache.org/jira/browse/LOG4J2-3427):
138 Improves ServiceLoader support on servlet containers.
78 * [LOG4J2-3572](https://issues.apache.org/jira/browse/LOG4J2-3572):
79 Add getExplicitLevel method to LoggerConfig.
80 * [LOG4J2-3589](https://issues.apache.org/jira/browse/LOG4J2-3589):
81 Allow Plugins to be injected with the LoggerContext reference.
82 * [LOG4J2-3588](https://issues.apache.org/jira/browse/LOG4J2-3588):
83 Allow PropertySources to be added.
13984
85 ### Removed
86 * [LOG4J2-3573](https://issues.apache.org/jira/browse/LOG4J2-3573):
87 Removed build page in favor of a single build instructions file. Thanks to Wolff Bock von Wuelfingen.
88 * [LOG4J2-3590](https://issues.apache.org/jira/browse/LOG4J2-3590):
89 Remove SLF4J 1.8.x binding.
14090 ---
14191
142 Apache Log4j 2.18.0 requires a minimum of Java 8 to build and run.
92 Apache Log4j 2.19.0 requires a minimum of Java 8 to build and run.
14393 Log4j 2.12.4 is the last release to support Java 7.
14494 Log4j 2.3.2 is the last release to support Java 6.
14595 Java 6 and Java 7 are no longer supported by the Log4j team.
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-1.2-api</artifactId>
2525 <packaging>jar</packaging>
4747 <dependency>
4848 <groupId>org.junit.vintage</groupId>
4949 <artifactId>junit-vintage-engine</artifactId>
50 <scope>test</scope>
5051 </dependency>
5152 <dependency>
5253 <groupId>org.junit.jupiter</groupId>
5354 <artifactId>junit-jupiter-engine</artifactId>
55 <scope>test</scope>
5456 </dependency>
5557 <dependency>
5658 <groupId>org.junit.jupiter</groupId>
5759 <artifactId>junit-jupiter-params</artifactId>
60 <scope>test</scope>
5861 </dependency>
5962 <dependency>
6063 <groupId>org.mockito</groupId>
6164 <artifactId>mockito-core</artifactId>
65 <scope>test</scope>
6266 </dependency>
6367 <dependency>
6468 <groupId>org.apache.commons</groupId>
3636 import org.apache.log4j.spi.HierarchyEventListener;
3737 import org.apache.log4j.spi.LoggerRepository;
3838 import org.apache.log4j.spi.LoggingEvent;
39 import org.apache.logging.log4j.core.config.LoggerConfig;
4039 import org.apache.logging.log4j.message.LocalizedMessage;
4140 import org.apache.logging.log4j.message.MapMessage;
4241 import org.apache.logging.log4j.message.Message;
173172 protected Category(final LoggerContext context, final String name) {
174173 this.name = name;
175174 this.logger = context.getLogger(name);
176 this.repository = LogManager.getLoggerRepository();
177 // this.rendererMap = ((RendererSupport) repository).getRendererMap();
178175 }
179176
180177 Category(final org.apache.logging.log4j.Logger logger) {
181178 this.logger = logger;
182 // rendererMap = ((RendererSupport) LogManager.getLoggerRepository()).getRendererMap();
183179 }
184180
185181 /**
429425 }
430426
431427 /**
432 * Gets the the {@link LoggerRepository} where this <code>Category</code> instance is attached.
428 * Gets the {@link LoggerRepository} where this <code>Category</code> instance is attached.
433429 *
434430 * @deprecated Please use {@link #getLoggerRepository()} instead.
435431 * @since 1.1
452448 }
453449
454450 /**
455 * Gets the the {@link LoggerRepository} where this <code>Category</code> is attached.
451 * Gets the {@link LoggerRepository} where this <code>Category</code> is attached.
456452 *
457453 * @since 1.2
458454 */
474470 return null;
475471 }
476472 final ConcurrentMap<String, Logger> loggers = Hierarchy.getLoggersMap(loggerContext);
477 final Logger parentLogger = loggers.get(parent.getName());
478 return parentLogger == null ? new Category(parent) : parentLogger;
473 Category parentLogger = loggers.get(parent.getName());
474 if (parentLogger == null) {
475 parentLogger = new Category(parent);
476 parentLogger.setHierarchy(getLoggerRepository());
477 }
478 return parentLogger;
479479 }
480480
481481 public final Level getPriority() {
9898 return PrivateLogManager.getContext();
9999 }
100100
101 static Logger getInstance(final LoggerContext context, final String name) {
101 private Logger getInstance(final LoggerContext context, final String name) {
102102 return getInstance(context, name, LOGGER_ADAPTER);
103103 }
104104
105 static Logger getInstance(final LoggerContext context, final String name, final LoggerFactory factory) {
106 return getLoggersMap(context).computeIfAbsent(name, k -> factory.makeNewLoggerInstance(name));
107 }
108
109 static Logger getInstance(final LoggerContext context, final String name, final PrivateLoggerAdapter factory) {
110 return getLoggersMap(context).computeIfAbsent(name, k -> factory.newLogger(name, context));
105 private Logger getInstance(final LoggerContext context, final String name, final LoggerFactory factory) {
106 return getLoggersMap(context).computeIfAbsent(name, k -> {
107 final Logger logger = factory.makeNewLoggerInstance(name);
108 logger.setHierarchy(this);
109 return logger;
110 });
111 }
112
113 private Logger getInstance(final LoggerContext context, final String name, final PrivateLoggerAdapter factory) {
114 return getLoggersMap(context).computeIfAbsent(name, k -> {
115 final Logger logger = factory.newLogger(name, context);
116 logger.setHierarchy(this);
117 return logger;
118 });
111119 }
112120
113121 static ConcurrentMap<String, Logger> getLoggersMap(final LoggerContext context) {
114122 synchronized (CONTEXT_MAP) {
115123 return CONTEXT_MAP.computeIfAbsent(context, k -> new ConcurrentHashMap<>());
116124 }
117 }
118
119 static Logger getRootLogger(final LoggerContext context) {
120 return getInstance(context, org.apache.logging.log4j.LogManager.ROOT_LOGGER_NAME);
121125 }
122126
123127 private final LoggerFactory defaultFactory;
526530 }
527531 }
528532
529 /**
530 * We update the links for all the children that placed themselves in the provision node 'pn'. The second argument 'cat'
531 * is a reference for the newly created Logger, parent of all the children in 'pn'
532 *
533 * We loop on all the children 'c' in 'pn':
534 *
535 * If the child 'c' has been already linked to a child of 'cat' then there is no need to update 'c'.
536 *
537 * Otherwise, we set cat's parent field to c's parent and set c's parent field to cat.
538 *
539 */
540 final private void updateChildren(final ProvisionNode pn, final Logger logger) {
541 // System.out.println("updateChildren called for " + logger.name);
542 final int last = pn.size();
543
544 for (int i = 0; i < last; i++) {
545 final Logger l = (Logger) pn.elementAt(i);
546 // System.out.println("Updating child " +p.name);
547
548 // Unless this child already points to a correct (lower) parent,
549 // make cat.parent point to l.parent and l.parent to cat.
550 if (!l.parent.name.startsWith(logger.name)) {
551 logger.parent = l.parent;
552 l.parent = logger;
553 }
554 }
555 }
556
557 /**
558 * This method loops through all the *potential* parents of 'cat'. There 3 possible cases:
559 *
560 * 1) No entry for the potential parent of 'cat' exists
561 *
562 * We create a ProvisionNode for this potential parent and insert 'cat' in that provision node.
563 *
564 * 2) There entry is of type Logger for the potential parent.
565 *
566 * The entry is 'cat's nearest existing parent. We update cat's parent field with this entry. We also break from the
567 * loop because updating our parent's parent is our parent's responsibility.
568 *
569 * 3) There entry is of type ProvisionNode for this potential parent.
570 *
571 * We add 'cat' to the list of children for this potential parent.
572 */
573 final private void updateParents(final Logger cat) {
574 final String name = cat.name;
575 final int length = name.length();
576 boolean parentFound = false;
577
578 // System.out.println("UpdateParents called for " + name);
579
580 // if name = "w.x.y.z", loop thourgh "w.x.y", "w.x" and "w", but not "w.x.y.z"
581 for (int i = name.lastIndexOf('.', length - 1); i >= 0; i = name.lastIndexOf('.', i - 1)) {
582 final String substr = name.substring(0, i);
583
584 // System.out.println("Updating parent : " + substr);
585 final CategoryKey key = new CategoryKey(substr); // simple constructor
586 final Object o = ht.get(key);
587 // Create a provision node for a future parent.
588 if (o == null) {
589 // System.out.println("No parent "+substr+" found. Creating ProvisionNode.");
590 final ProvisionNode pn = new ProvisionNode(cat);
591 ht.put(key, pn);
592 } else if (o instanceof Category) {
593 parentFound = true;
594 cat.parent = (Category) o;
595 // System.out.println("Linking " + cat.name + " -> " + ((Category) o).name);
596 break; // no need to update the ancestors of the closest ancestor
597 } else if (o instanceof ProvisionNode) {
598 ((ProvisionNode) o).addElement(cat);
599 } else {
600 final Exception e = new IllegalStateException("unexpected object type " + o.getClass() + " in ht.");
601 e.printStackTrace();
602 }
603 }
604 // If we could not find any existing parents, then link with root.
605 if (!parentFound) {
606 cat.parent = root;
607 }
608 }
609
610533 }
556556 * </p>
557557 *
558558 * <p>
559 * Case of <code>value</code> is insignificant for the level level, but is
559 * Case of <code>value</code> is insignificant for the level, but is
560560 * significant for the class name part, if present.
561561 * </p>
562562 *
4747
4848 /**
4949 * Returns <code>true</code> if the specified appender is in list of
50 * attached attached, <code>false</code> otherwise.
50 * attached, <code>false</code> otherwise.
5151 * @param appender The Appender to check.
5252 * @return true if the Appender is attached.
5353 *
9393 public void testForcedLog() {
9494 final MockCategory category = new MockCategory("org.example.foo");
9595 category.setAdditivity(false);
96 category.setHierarchy(LogManager.getHierarchy());
9697 ((org.apache.logging.log4j.core.Logger) category.getLogger()).addAppender(appender);
9798 // Logging a String
9899 category.info("Hello, World");
1919 import org.apache.log4j.Level;
2020
2121 /**
22 * This class introduces a new level level called TRACE. TRACE has lower level than DEBUG.
22 * This class introduces a new level called TRACE. TRACE has lower level than DEBUG.
2323 */
2424 public class XLevel extends Level {
2525 private static final long serialVersionUID = 7288304330257085144L;
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-api</artifactId>
2525 <packaging>jar</packaging>
4646 <dependency>
4747 <groupId>org.junit.vintage</groupId>
4848 <artifactId>junit-vintage-engine</artifactId>
49 <scope>test</scope>
4950 </dependency>
5051 <dependency>
5152 <groupId>org.junit.jupiter</groupId>
5253 <artifactId>junit-jupiter-migrationsupport</artifactId>
54 <scope>test</scope>
5355 </dependency>
5456 <dependency>
5557 <groupId>org.junit.jupiter</groupId>
5658 <artifactId>junit-jupiter-params</artifactId>
59 <scope>test</scope>
5760 </dependency>
5861 <dependency>
5962 <groupId>org.junit.jupiter</groupId>
6063 <artifactId>junit-jupiter-engine</artifactId>
64 <scope>test</scope>
6165 </dependency>
6266 <dependency>
6367 <groupId>uk.org.webcompere</groupId>
6468 <artifactId>system-stubs-jupiter</artifactId>
69 <scope>test</scope>
6570 </dependency>
6671 <dependency>
6772 <groupId>org.assertj</groupId>
6873 <artifactId>assertj-core</artifactId>
74 <scope>test</scope>
6975 </dependency>
7076 <dependency>
7177 <groupId>org.eclipse.tycho</groupId>
97103 <dependency>
98104 <groupId>org.junit-pioneer</groupId>
99105 <artifactId>junit-pioneer</artifactId>
106 <scope>test</scope>
100107 </dependency>
101108 </dependencies>
102109 <build>
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j;
17
18 /**
19 * Extended interface to allow bridges between logging systems to convey the
20 * correct location information.
21 *
22 */
23 public interface BridgeAware {
24
25 /**
26 * Fully qualified class name of the entry point to the logging system. This
27 * class will not appear in the location information.
28 *
29 * @param fqcn
30 * @return this
31 */
32 public void setEntryPoint(final String fqcn);
33 }
1515 */
1616 package org.apache.logging.log4j.internal;
1717
18 import org.apache.logging.log4j.BridgeAware;
1819 import org.apache.logging.log4j.Level;
1920 import org.apache.logging.log4j.LogBuilder;
2021 import org.apache.logging.log4j.Logger;
3031 /**
3132 * Collects data for a log event and then logs it. This class should be considered private.
3233 */
33 public class DefaultLogBuilder implements LogBuilder {
34 public class DefaultLogBuilder implements BridgeAware, LogBuilder {
3435
3536 private static Message EMPTY_MESSAGE = new SimpleMessage("");
3637 private static final String FQCN = DefaultLogBuilder.class.getName();
4344 private StackTraceElement location;
4445 private volatile boolean inUse;
4546 private long threadId;
47 private String fqcn = FQCN;
4648
4749 public DefaultLogBuilder(Logger logger, Level level) {
4850 this.logger = logger;
5557 this.logger = logger;
5658 this.inUse = false;
5759 this.threadId = Thread.currentThread().getId();
60 }
61
62 @Override
63 public void setEntryPoint(String fqcn) {
64 this.fqcn = fqcn;
5865 }
5966
6067 /**
230237
231238 private void logMessage(Message message) {
232239 try {
233 logger.logMessage(level, marker, FQCN, location, message, throwable);
240 logger.logMessage(level, marker, fqcn, location, message, throwable);
234241 } finally {
235242 inUse = false;
236243 }
6363 @Override
6464 public CharSequence getNormalForm(final Iterable<? extends CharSequence> tokens) {
6565 final StringBuilder sb = new StringBuilder("LOG4J");
66 boolean empty = true;
6667 for (final CharSequence token : tokens) {
68 empty = false;
6769 sb.append('_');
6870 for (int i = 0; i < token.length(); i++) {
6971 sb.append(Character.toUpperCase(token.charAt(i)));
7072 }
7173 }
72 return sb.toString();
74 return empty ? null : sb.toString();
7375 }
7476
7577 @Override
5757
5858 @Override
5959 public CharSequence getNormalForm(final Iterable<? extends CharSequence> tokens) {
60 return PREFIX + Util.joinAsCamelCase(tokens);
60 final CharSequence camelCase = Util.joinAsCamelCase(tokens);
61 return camelCase.length() > 0 ? PREFIX + camelCase : null;
6162 }
6263
6364 @Override
2323 import java.time.temporal.ChronoUnit;
2424 import java.time.temporal.TemporalUnit;
2525 import java.util.ArrayList;
26 import java.util.Collections;
2726 import java.util.HashSet;
2827 import java.util.List;
2928 import java.util.Map;
3433 import java.util.Set;
3534 import java.util.TreeSet;
3635 import java.util.concurrent.ConcurrentHashMap;
36 import java.util.concurrent.ConcurrentSkipListSet;
3737
3838 /**
3939 * <em>Consider this class private.</em>
122122 }
123123
124124 /**
125 * Allows a PropertySource to be added after PropertiesUtil has been created.
126 * @param propertySource the PropertySource to add.
127 */
128 public void addPropertySource(PropertySource propertySource) {
129 if (environment != null) {
130 environment.addPropertySource(propertySource);
131 }
132 }
133
134 /**
125135 * Returns {@code true} if the specified property is defined, regardless of its value (it may not have a value).
126136 *
127137 * @param name the name of the property to verify
432442 */
433443 private static class Environment {
434444
435 private final Set<PropertySource> sources = new TreeSet<>(new PropertySource.Comparator());
445 private final Set<PropertySource> sources = new ConcurrentSkipListSet<>(new PropertySource.Comparator());
436446 /**
437447 * Maps a key to its value in the lowest priority source that contains it.
438448 */
461471 .forEach(sources::add);
462472
463473 reload();
474 }
475
476 /**
477 * Allow a PropertySource to be added.
478 * @param propertySource The PropertySource to add.
479 */
480 public void addPropertySource(PropertySource propertySource) {
481 sources.add(propertySource);
464482 }
465483
466484 private synchronized void reload() {
480498 .filter(Objects::nonNull)
481499 .forEach(key -> {
482500 final List<CharSequence> tokens = PropertySource.Util.tokenize(key);
501 final boolean hasTokens = !tokens.isEmpty();
483502 sources.forEach(source -> {
484 final String value = source.getProperty(key);
485 if (value != null) {
503 if (source.containsProperty(key)) {
504 final String value = source.getProperty(key);
486505 literal.putIfAbsent(key, value);
487 if (!tokens.isEmpty()) {
506 if (hasTokens) {
488507 tokenized.putIfAbsent(tokens, value);
489508 }
490509 }
491 final CharSequence normalKey = source.getNormalForm(tokens);
492 if (normalKey != null) {
493 final String normalValue = source.getProperty(normalKey.toString());
494 if (normalValue != null) {
495 normalized.putIfAbsent(key, normalValue);
510 if (hasTokens) {
511 final String normalKey = Objects.toString(source.getNormalForm(tokens), null);
512 if (normalKey != null && source.containsProperty(normalKey)) {
513 normalized.putIfAbsent(key, source.getProperty(normalKey));
496514 }
497515 }
498516 });
507525 return literal.get(key);
508526 }
509527 final List<CharSequence> tokens = PropertySource.Util.tokenize(key);
528 final boolean hasTokens = !tokens.isEmpty();
510529 for (final PropertySource source : sources) {
511 final String normalKey = Objects.toString(source.getNormalForm(tokens), null);
512 if (normalKey != null && source.containsProperty(normalKey)) {
513 final String normalValue = source.getProperty(normalKey);
514 // Caching previously unknown keys breaks many tests which set and unset system properties
515 // normalized.put(key, normalValue);
516 return normalValue;
530 if (hasTokens) {
531 final String normalKey = Objects.toString(source.getNormalForm(tokens), null);
532 if (normalKey != null && source.containsProperty(normalKey)) {
533 return source.getProperty(normalKey);
534 }
517535 }
518536 if (source.containsProperty(key)) {
519 final String value = source.getProperty(key);
520 // literal.put(key, value);
521 return value;
537 return source.getProperty(key);
522538 }
523539 }
524540 return tokenized.get(tokens);
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16
17 package org.apache.logging.log4j.util;
18
19 import java.util.Hashtable;
20
21 import org.apache.logging.log4j.spi.Provider;
22 import org.osgi.framework.BundleActivator;
23 import org.osgi.framework.BundleContext;
24 import org.osgi.framework.ServiceRegistration;
25
26 /**
27 * Utility class to register Log4j2 providers in an OSGI environment.
28 */
29 public abstract class ProviderActivator implements BundleActivator {
30
31 public static final String API_VERSION = "APIVersion";
32
33 private final Provider provider;
34 private ServiceRegistration<Provider> providerRegistration = null;
35
36 protected ProviderActivator(final Provider provider) {
37 this.provider = provider;
38 }
39
40 @Override
41 public void start(final BundleContext context) throws Exception {
42 final Hashtable<String, String> props = new Hashtable<>();
43 props.put(API_VERSION, provider.getVersions());
44 providerRegistration = context.registerService(Provider.class, provider, props);
45 }
46
47 @Override
48 public void stop(BundleContext context) throws Exception {
49 if (providerRegistration != null) {
50 providerRegistration.unregister();
51 }
52 }
53
54 }
1616
1717 package org.apache.logging.log4j.util;
1818
19 import java.lang.invoke.CallSite;
20 import java.lang.invoke.LambdaMetafactory;
1921 import java.lang.invoke.MethodHandle;
2022 import java.lang.invoke.MethodHandles.Lookup;
2123 import java.lang.invoke.MethodType;
24 import java.security.AccessController;
25 import java.security.PrivilegedAction;
2226 import java.util.Collections;
2327 import java.util.HashSet;
2428 import java.util.Iterator;
3741 * This class should be considered internal.
3842 */
3943 public final class ServiceLoaderUtil {
40
41 private static final MethodType LOAD_CLASS_CLASSLOADER = MethodType.methodType(ServiceLoader.class, Class.class,
42 ClassLoader.class);
4344
4445 private ServiceLoaderUtil() {
4546 }
101102 static <T> Iterable<T> callServiceLoader(Lookup lookup, Class<T> serviceType, ClassLoader classLoader,
102103 boolean verbose) {
103104 try {
104 final MethodHandle handle = lookup.findStatic(ServiceLoader.class, "load", LOAD_CLASS_CLASSLOADER);
105 final ServiceLoader<T> serviceLoader = (ServiceLoader<T>) handle.invokeExact(serviceType, classLoader);
105 // Creates a lambda in the caller's domain that calls `ServiceLoader`
106 final MethodHandle loadHandle = lookup.findStatic(ServiceLoader.class, "load",
107 MethodType.methodType(ServiceLoader.class, Class.class, ClassLoader.class));
108 final CallSite callSite = LambdaMetafactory.metafactory(lookup,
109 "run",
110 MethodType.methodType(PrivilegedAction.class, Class.class, ClassLoader.class),
111 MethodType.methodType(Object.class),
112 loadHandle,
113 MethodType.methodType(ServiceLoader.class));
114 final PrivilegedAction<ServiceLoader<T>> action = (PrivilegedAction<ServiceLoader<T>>) callSite
115 .getTarget()//
116 .bindTo(serviceType)
117 .bindTo(classLoader)
118 .invoke();
119 final ServiceLoader<T> serviceLoader;
120 if (System.getSecurityManager() == null) {
121 serviceLoader = action.run();
122 } else {
123 final MethodHandle privilegedHandle = lookup.findStatic(AccessController.class, "doPrivileged",
124 MethodType.methodType(Object.class, PrivilegedAction.class));
125 serviceLoader = (ServiceLoader<T>) privilegedHandle.invoke(action);
126 }
106127 return serviceLoader;
107128 } catch (Throwable e) {
108129 if (verbose) {
110131 }
111132 }
112133 return Collections.emptyList();
113
114134 }
115135
116136 private static class ServiceLoaderSpliterator<S> implements Spliterator<S> {
6161 * {@code null}, empty, or all characters are {@link Character#isWhitespace(char)}.
6262 *
6363 * @param s the String to check, may be {@code null}
64 * @return {@code true} if the String is {@code null}, empty, or or all characters are {@link Character#isWhitespace(char)}
64 * @return {@code true} if the String is {@code null}, empty, or all characters are {@link Character#isWhitespace(char)}
6565 */
6666 public static boolean isBlank(final String s) {
6767 if (s == null || s.isEmpty()) {
3434 {"LOG4J_FOO_BAR_PROPERTY", Arrays.asList("foo", "bar", "property")},
3535 {"LOG4J_EXACT", Collections.singletonList("EXACT")},
3636 {"LOG4J_TEST_PROPERTY_NAME", PropertySource.Util.tokenize("Log4jTestPropertyName")},
37 {null, Collections.emptyList()}
3738 };
3839 }
3940
4141 String value = resourceBundle.getString(key);
4242 assertTrue(
4343 Charset.isSupported(value),
44 String.format("The Charset %s is is not available and is mapped from %s", value, key));
44 String.format("The Charset %s is not available and is mapped from %s", value, key));
4545 }
4646 }
4747 }
3535 {"log4j2.fooBarProperty", Arrays.asList("foo", "bar", "property")},
3636 {"log4j2.EXACT", Collections.singletonList("EXACT")},
3737 {"log4j2.testPropertyName", PropertySource.Util.tokenize("Log4jTestPropertyName")},
38 {null, Collections.emptyList()}
3839 };
3940 }
4041
2222 import static org.junit.jupiter.api.Assertions.assertNull;
2323 import static org.junit.jupiter.api.Assertions.assertTrue;
2424
25 import java.io.InputStream;
2526 import java.util.Properties;
2627
2728 import org.junit.jupiter.api.BeforeEach;
5354
5455 @Override
5556 public CharSequence getNormalForm(Iterable<? extends CharSequence> tokens) {
56 return "log4j2." + PropertySource.Util.joinAsCamelCase(tokens);
57 final CharSequence camelCase = PropertySource.Util.joinAsCamelCase(tokens);
58 return camelCase.length() > 0 ? "log4j2." + camelCase : null;
5759 }
5860
5961 @Override
8183
8284 @BeforeEach
8385 public void setUp() throws Exception {
84 properties.load(ClassLoader.getSystemResourceAsStream("PropertiesUtilOrderTest.properties"));
85 }
86
87 @Test
88 public void normalizedOverrideLegacy() {
86 try (final InputStream is = ClassLoader.getSystemResourceAsStream("PropertiesUtilOrderTest.properties")) {
87 properties.load(is);
88 }
89 }
90
91 @Test
92 public void testNormalizedOverrideLegacy() {
8993 final PropertiesUtil util = new PropertiesUtil(properties);
9094 final String legacy = "props.legacy";
9195 final String normalized = "props.normalized";
104108 }
105109
106110 @Test
107 public void fallsBackToTokenMatching() {
111 public void testFallsBackToTokenMatching() {
108112 final PropertiesUtil util = new PropertiesUtil(properties);
109113 for (int i = 1; i <= 4; i++) {
110114 final String key = "log4j2.tokenBasedProperty" + i;
117121 }
118122
119123 @Test
120 public void orderOfNormalizedProperties(EnvironmentVariables env, SystemProperties sysProps) {
124 public void testOrderOfNormalizedProperties(EnvironmentVariables env, SystemProperties sysProps) {
121125 properties.remove("log4j2.normalizedProperty");
122126 properties.remove("LOG4J_normalized.property");
123127 final PropertiesUtil util = new PropertiesUtil(properties);
150154 }
151155
152156 @Test
153 public void highPriorityNonEnumerableSource(SystemProperties sysProps) {
157 public void testHighPriorityNonEnumerableSource(SystemProperties sysProps) {
154158 // In both datasources
155159 assertNotNull(properties.getProperty("log4j2.normalizedProperty"));
156160 assertNotNull(properties.getProperty("log4j.onlyLegacy"));
187191 * @param sysProps
188192 */
189193 @Test
190 public void nullChecks(SystemProperties sysProps) {
194 public void testNullChecks(SystemProperties sysProps) {
191195 sysProps.set("log4j2.someProperty", "sysProps");
192196 sysProps.set("Log4jLegacyProperty", "sysProps");
193197 final PropertiesUtil util = new PropertiesUtil(new NullPropertySource());
2121 import org.junit.jupiter.api.parallel.ResourceAccessMode;
2222 import org.junit.jupiter.api.parallel.ResourceLock;
2323 import org.junit.jupiter.api.parallel.Resources;
24 import org.junitpioneer.jupiter.ReadsSystemProperty;
25 import org.junitpioneer.jupiter.SetSystemProperty;
2426
2527 import java.nio.charset.Charset;
2628 import java.nio.charset.StandardCharsets;
147149 assertEquals(pair[0], util.getStringProperty(pair[1]));
148150 }
149151 }
152
153 /**
154 * LOG4J2-3559: the fix for LOG4J2-3413 returns the value of 'log4j2.' for each
155 * property not starting with 'log4j'.
156 */
157 @Test
158 @ReadsSystemProperty
159 public void testLog4jProperty() {
160 final Properties props = new Properties();
161 final String incorrect = "log4j2.";
162 final String correct = "not.starting.with.log4j";
163 props.setProperty(incorrect, incorrect);
164 props.setProperty(correct, correct);
165 final PropertiesUtil util = new PropertiesUtil(props);
166 assertEquals(correct, util.getStringProperty(correct));
167 }
150168 }
5252 private static class TestSecurityManager extends SecurityManager {
5353 @Override
5454 public void checkPermission(final Permission permission) {
55 if (permission instanceof PropertyPermission) {
56 throw new SecurityException();
55 if (permission instanceof PropertyPermission &&
56 !permission.getName().equals("java.util.secureRandomSeed")) {
57 throw new SecurityException("Unexpected permission: " + permission);
5758 }
5859 }
5960 }
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-api-java9</artifactId>
2525 <packaging>pom</packaging>
3434 <dependency>
3535 <groupId>org.junit.jupiter</groupId>
3636 <artifactId>junit-jupiter-engine</artifactId>
37 <scope>test</scope>
3738 </dependency>
3839 <dependency>
3940 <groupId>org.assertj</groupId>
4041 <artifactId>assertj-core</artifactId>
42 <scope>test</scope>
4143 </dependency>
4244 </dependencies>
4345 <build>
1616
1717 package org.apache.logging.log4j.util;
1818
19 import java.lang.invoke.CallSite;
20 import java.lang.invoke.LambdaMetafactory;
1921 import java.lang.invoke.MethodHandle;
2022 import java.lang.invoke.MethodHandles.Lookup;
2123 import java.lang.invoke.MethodType;
22 import java.util.Arrays;
24 import java.security.AccessController;
25 import java.security.PrivilegedAction;
2326 import java.util.HashSet;
2427 import java.util.Objects;
2528 import java.util.ServiceConfigurationError;
3033 import org.apache.logging.log4j.status.StatusLogger;
3134
3235 public final class ServiceLoaderUtil {
33
34 private static final MethodType LOAD_CLASS_CLASSLOADER = MethodType.methodType(ServiceLoader.class, Class.class,
35 ClassLoader.class);
3636
3737 private ServiceLoaderUtil() {
3838 }
8686 static <T> Stream<T> loadClassloaderServices(final Class<T> serviceType, final Lookup lookup,
8787 final ClassLoader classLoader, final boolean verbose) {
8888 try {
89 final MethodHandle handle = lookup.findStatic(ServiceLoader.class, "load", LOAD_CLASS_CLASSLOADER);
90 final ServiceLoader<T> serviceLoader = (ServiceLoader<T>) handle.invokeExact(serviceType, classLoader);
89 // Creates a lambda in the caller's domain that calls `ServiceLoader`
90 final MethodHandle loadHandle = lookup.findStatic(ServiceLoader.class, "load",
91 MethodType.methodType(ServiceLoader.class, Class.class, ClassLoader.class));
92 final CallSite callSite = LambdaMetafactory.metafactory(lookup,
93 "run",
94 MethodType.methodType(PrivilegedAction.class, Class.class, ClassLoader.class),
95 MethodType.methodType(Object.class),
96 loadHandle,
97 MethodType.methodType(ServiceLoader.class));
98 final PrivilegedAction<ServiceLoader<T>> action = (PrivilegedAction<ServiceLoader<T>>) callSite
99 .getTarget()//
100 .bindTo(serviceType)
101 .bindTo(classLoader)
102 .invoke();
103 final ServiceLoader<T> serviceLoader;
104 if (System.getSecurityManager() == null) {
105 serviceLoader = action.run();
106 } else {
107 final MethodHandle privilegedHandle = lookup.findStatic(AccessController.class, "doPrivileged",
108 MethodType.methodType(Object.class, PrivilegedAction.class));
109 serviceLoader = (ServiceLoader<T>) privilegedHandle.invoke(action);
110 }
91111 return serviceLoader.stream().map(provider -> {
92112 try {
93113 return provider.get();
2121 <parent>
2222 <artifactId>log4j</artifactId>
2323 <groupId>org.apache.logging.log4j</groupId>
24 <version>2.18.0</version>
24 <version>2.19.0</version>
2525 </parent>
2626
2727 <artifactId>log4j-appserver</artifactId>
3333 <log4jParentDir>${basedir}/..</log4jParentDir>
3434 <docLabel>Web Documentation</docLabel>
3535 <projectDir>/log4j-appserver</projectDir>
36 <tomcat-juli.version>10.0.21</tomcat-juli.version>
36 <tomcat-juli.version>10.0.23</tomcat-juli.version>
3737 <module.name>org.apache.logging.log4j.appserver</module.name>
3838 <maven.doap.skip>true</maven.doap.skip>
3939 </properties>
2525 <description>Apache Log4j Bill of Materials</description>
2626 <groupId>org.apache.logging.log4j</groupId>
2727 <artifactId>log4j-bom</artifactId>
28 <version>2.18.0</version>
28 <version>2.19.0</version>
2929 <packaging>pom</packaging>
3030
3131 <!-- `log4j-bom` doesn't inherit from the room POM, but `org.apache.logging:logging-parent`.
5252 <artifactId>log4j-core</artifactId>
5353 <version>${project.version}</version>
5454 </dependency>
55 <!-- SMTP appender -->
56 <dependency>
57 <groupId>org.apache.logging.log4j</groupId>
58 <artifactId>log4j-jakarta-smtp</artifactId>
59 <version>${project.version}</version>
60 </dependency>
5561 <!-- JSON template layout -->
5662 <dependency>
5763 <groupId>org.apache.logging.log4j</groupId>
94100 <artifactId>log4j-slf4j-impl</artifactId>
95101 <version>${project.version}</version>
96102 </dependency>
97 <!-- SLF4J 1.8.x Compatibility API -->
98 <dependency>
99 <groupId>org.apache.logging.log4j</groupId>
100 <artifactId>log4j-slf4j18-impl</artifactId>
103 <!-- SLF4J 2.0 Compatibility API -->
104 <dependency>
105 <groupId>org.apache.logging.log4j</groupId>
106 <artifactId>log4j-slf4j2-impl</artifactId>
101107 <version>${project.version}</version>
102108 </dependency>
103109 <!-- SLF4J Adapter -->
106112 <artifactId>log4j-to-slf4j</artifactId>
107113 <version>${project.version}</version>
108114 </dependency>
115 <!-- JUL Adapter -->
116 <dependency>
117 <groupId>org.apache.logging.log4j</groupId>
118 <artifactId>log4j-to-jul</artifactId>
119 <version>${project.version}</version>
120 </dependency>
109121 <!-- Application Service Support -->
110122 <dependency>
111123 <groupId>org.apache.logging.log4j</groupId>
116128 <dependency>
117129 <groupId>org.apache.logging.log4j</groupId>
118130 <artifactId>log4j-web</artifactId>
131 <version>${project.version}</version>
132 </dependency>
133 <dependency>
134 <groupId>org.apache.logging.log4j</groupId>
135 <artifactId>log4j-jakarta-web</artifactId>
119136 <version>${project.version}</version>
120137 </dependency>
121138 <!-- CouchDB Appender Plugin -->
227244 </build>
228245
229246 <scm>
230 <tag>log4j-2.18.0-rc1</tag>
247 <tag>log4j-2.19.0-rc2</tag>
231248 </scm>
232249 </project>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <modelVersion>4.0.0</modelVersion>
2525
5050 <dependency>
5151 <groupId>org.junit.vintage</groupId>
5252 <artifactId>junit-vintage-engine</artifactId>
53 <scope>test</scope>
5354 </dependency>
5455 <dependency>
5556 <groupId>org.junit.jupiter</groupId>
5657 <artifactId>junit-jupiter-engine</artifactId>
58 <scope>test</scope>
5759 </dependency>
5860 <dependency>
5961 <groupId>org.mockito</groupId>
379379 # to the number of cores.
380380 #memtable_flush_writers: 8
381381
382 # A fixed memory pool size in MB for for SSTable index summaries. If left
382 # A fixed memory pool size in MB for SSTable index summaries. If left
383383 # empty, this will default to 5% of the heap size. If the memory usage of
384384 # all index summaries exceeds this limit, SSTables with low read rates will
385385 # shrink their index summaries in order to meet this limit. However, this
548548
549549 # Uncomment to set socket buffer size for internode communication
550550 # Note that when setting this, the buffer size is limited by net.core.wmem_max
551 # and when not setting it it is defined by net.ipv4.tcp_wmem
551 # and when not setting it is defined by net.ipv4.tcp_wmem
552552 # See:
553553 # /proc/sys/net/core/wmem_max
554554 # /proc/sys/net/core/rmem_max
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-core</artifactId>
2525 <packaging>jar</packaging>
171171 <dependency>
172172 <groupId>org.jmdns</groupId>
173173 <artifactId>jmdns</artifactId>
174 <version>3.5.7</version>
174 <version>3.5.8</version>
175175 <scope>test</scope>
176176 </dependency>
177177 <!-- SLF4J tests -->
184184 <dependency>
185185 <groupId>org.junit.vintage</groupId>
186186 <artifactId>junit-vintage-engine</artifactId>
187 <scope>test</scope>
187188 </dependency>
188189 <dependency>
189190 <groupId>org.junit.jupiter</groupId>
190191 <artifactId>junit-jupiter-engine</artifactId>
192 <scope>test</scope>
191193 </dependency>
192194 <dependency>
193195 <groupId>org.junit.jupiter</groupId>
194196 <artifactId>junit-jupiter-params</artifactId>
197 <scope>test</scope>
195198 </dependency>
196199 <dependency>
197200 <groupId>org.junit.platform</groupId>
199202 <scope>test</scope>
200203 </dependency>
201204 <dependency>
205 <groupId>org.assertj</groupId>
206 <artifactId>assertj-core</artifactId>
207 <scope>test</scope>
208 </dependency>
209 <dependency>
202210 <groupId>org.hamcrest</groupId>
203211 <artifactId>hamcrest</artifactId>
204212 <scope>test</scope>
206214 <dependency>
207215 <groupId>org.junit-pioneer</groupId>
208216 <artifactId>junit-pioneer</artifactId>
217 <scope>test</scope>
209218 </dependency>
210219 <!-- Mocking framework for use with JUnit -->
211220 <dependency>
212221 <groupId>org.mockito</groupId>
213222 <artifactId>mockito-core</artifactId>
223 <scope>test</scope>
214224 </dependency>
215225 <dependency>
216226 <groupId>org.mockito</groupId>
217227 <artifactId>mockito-junit-jupiter</artifactId>
228 <scope>test</scope>
218229 </dependency>
219230 <!-- Embedded JDBC drivers for database appender tests -->
220231 <dependency>
1919 import org.apache.logging.log4j.Level;
2020 import org.apache.logging.log4j.Marker;
2121 import org.apache.logging.log4j.message.Message;
22 import org.apache.logging.log4j.util.Constants;
2223 import org.apache.logging.log4j.util.EnglishEnums;
2324
2425 /**
300301
301302 /**
302303 * Filter an event.
304 * @param logger The Logger.
305 * @param level The event logging Level.
306 * @param marker The Marker for the event or null.
307 * @param msg The Message
308 * @return the Result.
309 */
310 default Result filter(Logger logger, Level level, Marker marker, String msg) {
311 return filter(logger, level, marker, msg, Constants.EMPTY_OBJECT_ARRAY);
312 }
313
314 /**
315 * Filter an event.
303316 * @param event The Event to filter on.
304317 * @return the Result.
305318 */
1818 import java.io.ObjectStreamException;
1919 import java.io.Serializable;
2020 import java.util.ArrayList;
21 import java.util.Collections;
2122 import java.util.Iterator;
2223 import java.util.List;
2324 import java.util.Map;
298299 public Iterator<Filter> getFilters() {
299300 final Filter filter = privateConfig.loggerConfig.getFilter();
300301 if (filter == null) {
301 return new ArrayList<Filter>().iterator();
302 return Collections.emptyIterator();
302303 } else if (filter instanceof CompositeFilter) {
303304 return ((CompositeFilter) filter).iterator();
304305 } else {
6464 for (final Node childNode : children) {
6565 final String key = childNode.getAttributes().get("name");
6666 if (key == null) {
67 LOGGER.error("The attribute 'name' is missing from from the node {} in AppenderSet {}",
67 LOGGER.error("The attribute 'name' is missing from the node {} in AppenderSet {}",
6868 childNode, children);
6969 } else {
7070 map.put(key, childNode);
5656 private String id;
5757
5858 @PluginBuilderAttribute(value = "enterpriseNumber")
59 private String enterpriseNumber = Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER;
59 private String enterpriseNumber = String.valueOf(Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER);
6060
6161 @PluginBuilderAttribute(value = "includeMdc")
6262 private boolean includeMdc = true;
138138 protected synchronized void writeToDestination(final byte[] bytes, final int offset, final int length) {
139139 try {
140140 if (randomAccessFile == null) {
141 final String fileName = getFileName();
142 final File file = new File(fileName);
143 FileUtils.makeParentDirs(file);
144 createFileAfterRollover(fileName);
141 createFileAfterRollover();
145142 }
146143 randomAccessFile.write(bytes, offset, length);
147144 size += length;
153150
154151 @Override
155152 protected void createFileAfterRollover() throws IOException {
156 createFileAfterRollover(getFileName());
153 final String fileName = getFileName();
154 final File file = new File(fileName);
155 FileUtils.makeParentDirs(file);
156 createFileAfterRollover(fileName);
157157 }
158158
159159 private void createFileAfterRollover(final String fileName) throws IOException {
421421 * LOG4J2-2629: PurgePolicy implementations can invoke {@link #deleteAppender(String)} after we have looked up
422422 * an instance of a target appender but before events are appended, which could result in events not being
423423 * recorded to any appender.
424 * This extension of {@link AppenderControl} allows to to mark usage of an appender, allowing deferral of
424 * This extension of {@link AppenderControl} allows to mark usage of an appender, allowing deferral of
425425 * {@link Appender#stop()} until events have successfully been recorded.
426426 * Alternative approaches considered:
427427 * - More aggressive synchronization: Appenders may do expensive I/O that shouldn't block routing.
2828 /**
2929 * Returns either this Thread's context or the default {@link AsyncLoggerContext}.
3030 * Single-application instances should prefer this implementation over the {@link AsyncLoggerContextSelector}
31 * due the the reduced overhead avoiding classloader lookups.
31 * due to the reduced overhead avoiding classloader lookups.
3232 */
3333 public class BasicAsyncLoggerContextSelector implements ContextSelector {
3434
131131 private ConcurrentMap<String, LoggerConfig> loggerConfigs = new ConcurrentHashMap<>();
132132 private List<CustomLevelConfig> customLevels = Collections.emptyList();
133133 private final ConcurrentMap<String, String> propertyMap = new ConcurrentHashMap<>();
134 private final StrLookup tempLookup = new Interpolator(propertyMap);
134 private final Interpolator tempLookup = new Interpolator(propertyMap);
135135 private final StrSubstitutor runtimeStrSubstitutor = new RuntimeStrSubstitutor(tempLookup);
136136 private final StrSubstitutor configurationStrSubstitutor = new ConfigurationStrSubstitutor(runtimeStrSubstitutor);
137137 private LoggerConfig root = new LoggerConfig();
149149 */
150150 protected AbstractConfiguration(final LoggerContext loggerContext, final ConfigurationSource configurationSource) {
151151 this.loggerContext = new WeakReference<>(loggerContext);
152 tempLookup.setLoggerContext(loggerContext);
152153 // The loggerContext is null for the NullConfiguration class.
153154 // this.loggerContext = new WeakReference(Objects.requireNonNull(loggerContext, "loggerContext is null"));
154155 this.configurationSource = Objects.requireNonNull(configurationSource, "configurationSource is null");
635636 createConfiguration(first, null);
636637 if (first.getObject() != null) {
637638 StrLookup lookup = (StrLookup) first.getObject();
639 if (lookup instanceof LoggerContextAware) {
640 ((LoggerContextAware) lookup).setLoggerContext(loggerContext.get());
641 }
638642 runtimeStrSubstitutor.setVariableResolver(lookup);
639643 configurationStrSubstitutor.setVariableResolver(lookup);
640644 }
642646 final Map<String, String> map = this.getComponent(CONTEXT_PROPERTIES);
643647 final StrLookup lookup = map == null ? null : new PropertiesLookup(map);
644648 Interpolator interpolator = new Interpolator(lookup, pluginPackages);
649 interpolator.setLoggerContext(loggerContext.get());
645650 runtimeStrSubstitutor.setVariableResolver(interpolator);
646651 configurationStrSubstitutor.setVariableResolver(interpolator);
647652 }
409409 }
410410
411411 /**
412 * Allows callers to determine the Level assigned to this LoggerConfig.
413 * @return the Level associated with this LoggerConfig or null if none is set.
414 */
415 public Level getExplicitLevel() {
416 return level;
417 }
418
419 /**
412420 * Returns the LogEventFactory.
413421 *
414422 * @return the LogEventFactory.
941949 } else {
942950 LOGGER.warn("levelAndRefs are only allowed in a properties configuration. The value is ignored.");
943951 result.level = level;
944 result.refs = Arrays.asList(refs);
952 result.refs = refs != null ? Arrays.asList(refs) : new ArrayList<>();
945953 }
946954 } else {
947955 result.level = level;
948 result.refs = Arrays.asList(refs);
956 result.refs = refs != null ? Arrays.asList(refs) : new ArrayList<>();
949957 }
950958 return result;
951959 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16
17 package org.apache.logging.log4j.core.config;
18
19 import org.apache.logging.log4j.core.LoggerContext;
20
21 /**
22 * Indicates that a class requests the current LoggerContext to be injected.
23 *
24 * @since 2.19.0
25 */
26 public interface LoggerContextAware {
27
28 /**
29 * Injects the current LoggerContext into this object.
30 *
31 * @param loggerContext the current LoggerContext
32 */
33 void setLoggerContext(LoggerContext loggerContext);
34 }
7373
7474 /**
7575 * Sets the Property Value.
76 * @param propertyValue the property name.
76 * @param propertyValue the property value.
7777 * @return this
7878 */
7979 public Builder setPropertyValue(final String propertyValue) {
80 this.propertyName = propertyValue;
80 this.propertyValue = propertyValue;
8181 return asBuilder();
8282 }
8383
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j.core.config.plugins;
17
18 import java.lang.annotation.Documented;
19 import java.lang.annotation.ElementType;
20 import java.lang.annotation.Retention;
21 import java.lang.annotation.RetentionPolicy;
22 import java.lang.annotation.Target;
23
24 import org.apache.logging.log4j.core.config.plugins.visitors.PluginLoggerContextVisitor;
25
26 /**
27 * Identifies a parameter or field as a LoggerContext.
28 * @see org.apache.logging.log4j.core.LoggerContext
29 */
30 @Documented
31 @Retention(RetentionPolicy.RUNTIME)
32 @Target({ElementType.PARAMETER, ElementType.FIELD})
33 @PluginVisitorStrategy(PluginLoggerContextVisitor.class)
34 public @interface PluginLoggerContext {
35 // empty
36 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16
17 package org.apache.logging.log4j.core.config.plugins.visitors;
18
19 import org.apache.logging.log4j.core.LogEvent;
20 import org.apache.logging.log4j.core.LoggerContext;
21 import org.apache.logging.log4j.core.config.Configuration;
22 import org.apache.logging.log4j.core.config.Node;
23 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
24
25 /**
26 * PluginVisitor implementation for {@link PluginConfiguration}.
27 */
28 public class PluginLoggerContextVisitor extends AbstractPluginVisitor<PluginConfiguration> {
29 public PluginLoggerContextVisitor() {
30 super(PluginConfiguration.class);
31 }
32
33 @Override
34 public Object visit(final Configuration configuration, final Node node, final LogEvent event,
35 final StringBuilder log) {
36 if (this.conversionType.isAssignableFrom(LoggerContext.class)) {
37 if (configuration.getLoggerContext() != null) {
38 return configuration.getLoggerContext();
39 } else {
40 LOGGER.warn("Configuration {} is not assigned a LoggerContext", configuration.getName());
41 }
42 }
43 LOGGER.warn("Variable annotated with @PluginLoggerContext does not reference a LoggerContext");
44 return null;
45 }
46 }
7272 /**
7373 * The default example enterprise number from RFC5424.
7474 */
75 public static final String DEFAULT_ENTERPRISE_NUMBER = "32473";
75 public static final int DEFAULT_ENTERPRISE_NUMBER = 32473;
7676 /**
7777 * The default event id.
7878 */
615615 // @formatter:off
616616 @PluginAttribute(value = "facility", defaultString = "LOCAL0") final Facility facility,
617617 @PluginAttribute("id") final String id,
618 @PluginAttribute(value = "enterpriseNumber", defaultInt = -1)
618 @PluginAttribute(value = "enterpriseNumber", defaultInt = DEFAULT_ENTERPRISE_NUMBER)
619619 final int enterpriseNumber,
620620 @PluginAttribute(value = "includeMDC", defaultBoolean = true) final boolean includeMDC,
621621 @PluginAttribute(value = "mdcId", defaultString = DEFAULT_MDCID) final String mdcId,
646646
647647 public static class Rfc5424LayoutBuilder {
648648 private Configuration config;
649 private Facility facility;
649 private Facility facility = Facility.LOCAL0;
650650 private String id;
651 private String ein;
652 private boolean includeMDC;
651 private String ein = String.valueOf(DEFAULT_ENTERPRISE_NUMBER);
652 private boolean includeMDC = true;
653653 private boolean includeNL;
654654 private String escapeNL;
655 private String mdcId;
655 private String mdcId = DEFAULT_MDCID;
656656 private String mdcPrefix;
657657 private String eventPrefix;
658658 private String appName;
842842 public Facility getFacility() {
843843 return facility;
844844 }
845
846 public String getDefaultId() {
847 return defaultId;
848 }
849
850 public String getEnterpriseNumber() {
851 return enterpriseNumber;
852 }
853
854 public boolean isIncludeMdc() {
855 return includeMdc;
856 }
857
858 public String getMdcId() {
859 return mdcId;
860 }
861
845862 }
4747 }
4848
4949 /**
50 * Looks up the the current date or the date in the LogEvent.
50 * Looks up d the current date or the date in the LogEvent.
5151 * @param event The LogEvent for which the date is returned. If null, current date is returned.
5252 * @param key the format to use. If null, the default DateFormat will be used.
5353 * @return The formatted date, never null.
1515 */
1616 package org.apache.logging.log4j.core.lookup;
1717
18 import java.lang.ref.WeakReference;
1819 import java.util.Collections;
1920 import java.util.HashMap;
2021 import java.util.List;
2324
2425 import org.apache.logging.log4j.Logger;
2526 import org.apache.logging.log4j.core.LogEvent;
27 import org.apache.logging.log4j.core.LoggerContext;
2628 import org.apache.logging.log4j.core.config.ConfigurationAware;
29 import org.apache.logging.log4j.core.config.LoggerContextAware;
2730 import org.apache.logging.log4j.core.config.plugins.util.PluginManager;
2831 import org.apache.logging.log4j.core.config.plugins.util.PluginType;
2932 import org.apache.logging.log4j.core.net.JndiManager;
3336 /**
3437 * Proxies all the other {@link StrLookup}s.
3538 */
36 public class Interpolator extends AbstractConfigurationAwareLookup {
39 public class Interpolator extends AbstractConfigurationAwareLookup implements LoggerContextAware {
3740
3841 /** Constant for the prefix separator. */
3942 public static final char PREFIX_SEPARATOR = ':';
5558 private final Map<String, StrLookup> strLookupMap = new HashMap<>();
5659
5760 private final StrLookup defaultLookup;
61
62 protected WeakReference<LoggerContext> loggerContext;
5863
5964 public Interpolator(final StrLookup defaultLookup) {
6065 this(defaultLookup, null);
184189 if (lookup instanceof ConfigurationAware) {
185190 ((ConfigurationAware) lookup).setConfiguration(configuration);
186191 }
192 if (lookup instanceof LoggerContextAware) {
193 ((LoggerContextAware) lookup).setLoggerContext(loggerContext.get());
194 }
187195 LookupResult value = null;
188196 if (lookup != null) {
189197 value = event == null ? lookup.evaluate(name) : lookup.evaluate(event, name);
198206 return event == null ? defaultLookup.evaluate(var) : defaultLookup.evaluate(event, var);
199207 }
200208 return null;
209 }
210
211 @Override
212 public void setLoggerContext(LoggerContext loggerContext) {
213 if (loggerContext == null) {
214 return;
215 }
216 this.loggerContext = new WeakReference<>(loggerContext);
201217 }
202218
203219 @Override
3232 * Configuration of the KeyStore
3333 */
3434 public class AbstractKeyStoreConfiguration extends StoreConfiguration<KeyStore> {
35 static final char[] DEFAULT_PASSWORD = "changeit".toCharArray();
3635
3736 private final KeyStore keyStore;
3837 private final String keyStoreType;
6564 @Override
6665 protected KeyStore load() throws StoreConfigurationException {
6766 final String loadLocation = this.getLocation();
67 final char[] password = this.getPasswordAsCharArray();
6868 LOGGER.debug("Loading keystore from location {}", loadLocation);
6969 try {
70 final KeyStore ks = KeyStore.getInstance(this.keyStoreType);
7071 if (loadLocation == null) {
71 throw new IOException("The location is null");
72 if (keyStoreType.equalsIgnoreCase(JKS) || keyStoreType.equalsIgnoreCase(PKCS12)) {
73 throw new IOException("The location is null");
74 }
75 ks.load(null, password);
76 LOGGER.debug("KeyStore successfully loaded");
77 return ks;
7278 }
7379 try (final InputStream fin = openInputStream(loadLocation)) {
74 final KeyStore ks = KeyStore.getInstance(this.keyStoreType);
75 final char[] password = this.getPasswordAsCharArray();
76 try {
77 ks.load(fin, password != null ? password : DEFAULT_PASSWORD);
78 } finally {
79 if (password != null) {
80 Arrays.fill(password, '\0');
81 }
82 }
80 ks.load(fin, password);
8381 LOGGER.debug("KeyStore successfully loaded from location {}", loadLocation);
8482 return ks;
8583 }
9896 } catch (final IOException e) {
9997 LOGGER.error("Something is wrong with the format of the keystore or the given password for location {}", loadLocation, e);
10098 throw new StoreConfigurationException(loadLocation, e);
99 } finally {
100 if (password != null) {
101 Arrays.fill(password, '\0');
102 }
101103 }
102104 }
103105
168168 final KeyManagerFactory kmFactory = KeyManagerFactory.getInstance(this.keyManagerFactoryAlgorithm);
169169 final char[] password = this.getPasswordAsCharArray();
170170 try {
171 kmFactory.init(this.getKeyStore(), password != null ? password : DEFAULT_PASSWORD);
171 kmFactory.init(this.getKeyStore(), password);
172172 } finally {
173173 if (password != null) {
174174 Arrays.fill(password, '\0');
1818 import org.apache.logging.log4j.Logger;
1919 import org.apache.logging.log4j.status.StatusLogger;
2020 import org.apache.logging.log4j.util.PropertiesUtil;
21 import org.apache.logging.log4j.util.Strings;
2122
2223 /**
2324 * Creates an SSL configuration from Log4j properties.
4546 KeyStoreConfiguration keyStoreConfiguration = null;
4647 TrustStoreConfiguration trustStoreConfiguration = null;
4748 String location = props.getStringProperty(trustStorelocation);
48 if (location != null) {
49 String storeType = props.getStringProperty(trustStoreKeyStoreType);
50 if (Strings.isNotEmpty(location) || storeType != null) {
4951 String password = props.getStringProperty(trustStorePassword);
50 char[] passwordChars = null;
51 if (password != null) {
52 passwordChars = password.toCharArray();
53 }
52 char[] passwordChars = getPassword(password, storeType);
5453 try {
55 trustStoreConfiguration = TrustStoreConfiguration.createKeyStoreConfiguration(location, passwordChars,
54 trustStoreConfiguration = TrustStoreConfiguration.createKeyStoreConfiguration(Strings.trimToNull(location), passwordChars,
5655 props.getStringProperty(trustStorePasswordEnvVar), props.getStringProperty(trustStorePasswordFile),
57 props.getStringProperty(trustStoreKeyStoreType), props.getStringProperty(trustStoreKeyManagerFactoryAlgorithm));
56 storeType, props.getStringProperty(trustStoreKeyManagerFactoryAlgorithm));
5857 } catch (Exception ex) {
5958 LOGGER.warn("Unable to create trust store configuration due to: {} {}", ex.getClass().getName(),
6059 ex.getMessage());
6160 }
6261 }
6362 location = props.getStringProperty(keyStoreLocation);
64 if (location != null) {
63 storeType = props.getStringProperty(keyStoreType);
64 if (Strings.isNotEmpty(location) || storeType != null) {
6565 String password = props.getStringProperty(keyStorePassword);
66 char[] passwordChars = null;
67 if (password != null) {
68 passwordChars = password.toCharArray();
69 }
66 char[] passwordChars = getPassword(password, storeType);
7067 try {
71 keyStoreConfiguration = KeyStoreConfiguration.createKeyStoreConfiguration(location, passwordChars,
68 keyStoreConfiguration = KeyStoreConfiguration.createKeyStoreConfiguration(Strings.trimToNull(location), passwordChars,
7269 props.getStringProperty(keyStorePasswordEnvVar), props.getStringProperty(keyStorePasswordFile),
73 props.getStringProperty(keyStoreType), props.getStringProperty(keyStoreKeyManagerFactoryAlgorithm));
70 storeType, props.getStringProperty(keyStoreKeyManagerFactoryAlgorithm));
7471 } catch (Exception ex) {
7572 LOGGER.warn("Unable to create key store configuration due to: {} {}", ex.getClass().getName(),
7673 ex.getMessage());
8481 return null;
8582 }
8683
84 private static char[] getPassword(final String password, final String keyStoreType) {
85 // Note from Tomcat's SSLUtiBase#getStore:
86 //
87 // JKS key stores treat null and "" interchangeably.
88 // PKCS12 key stores don't return the cert if null is used.
89 // Key stores that do not use passwords expect null
90 // Therefore:
91 // - generally use null if pass is null or ""
92 // - for JKS or PKCS12 only use null if pass is null
93 // (because JKS will auto-switch to PKCS12)
94 if (keyStoreType.equals(StoreConfiguration.JKS) || keyStoreType.equals(StoreConfiguration.PKCS12)) {
95 return password != null ? password.toCharArray() : null;
96 }
97 return Strings.isEmpty(password) ? null : password.toCharArray();
98 }
99
87100 public static SslConfiguration getSslConfiguration() {
88101 return sslConfiguration;
89102 }
2424 *
2525 */
2626 public class StoreConfiguration<T> {
27
28 static final String PKCS12 = "PKCS12";
29 static final String JKS = "JKS";
2730 protected static final StatusLogger LOGGER = StatusLogger.getLogger();
2831
2932 private String location;
1717 package org.apache.logging.log4j.core.osgi;
1818
1919 import java.util.Collection;
20 import java.util.Hashtable;
2120 import java.util.concurrent.atomic.AtomicReference;
2221
2322 import org.apache.logging.log4j.LogManager;
2827 import org.apache.logging.log4j.core.impl.ThreadContextDataProvider;
2928 import org.apache.logging.log4j.core.util.Constants;
3029 import org.apache.logging.log4j.core.util.ContextDataProvider;
31 import org.apache.logging.log4j.spi.Provider;
3230 import org.apache.logging.log4j.status.StatusLogger;
3331 import org.apache.logging.log4j.util.PropertiesUtil;
32 import org.apache.logging.log4j.util.ProviderActivator;
3433 import org.osgi.framework.Bundle;
35 import org.osgi.framework.BundleActivator;
3634 import org.osgi.framework.BundleContext;
3735 import org.osgi.framework.BundleEvent;
3836 import org.osgi.framework.InvalidSyntaxException;
4442 /**
4543 * OSGi BundleActivator.
4644 */
47 public final class Activator implements BundleActivator, SynchronousBundleListener {
45 public final class Activator extends ProviderActivator implements SynchronousBundleListener {
4846
4947 private static final Logger LOGGER = StatusLogger.getLogger();
5048
5149 private final AtomicReference<BundleContext> contextRef = new AtomicReference<>();
5250
53 ServiceRegistration provideRegistration = null;
54 ServiceRegistration contextDataRegistration = null;
51 private ServiceRegistration<ContextDataProvider> contextDataRegistration = null;
52
53 public Activator() {
54 super(new Log4jProvider());
55 }
5556
5657 @Override
5758 public void start(final BundleContext context) throws Exception {
58 final Provider provider = new Log4jProvider();
59 final Hashtable<String, String> props = new Hashtable<>();
60 props.put("APIVersion", "2.60");
59 super.start(context);
6160 final ContextDataProvider threadContextProvider = new ThreadContextDataProvider();
62 provideRegistration = context.registerService(Provider.class.getName(), provider, props);
63 contextDataRegistration = context.registerService(ContextDataProvider.class.getName(), threadContextProvider,
64 null);
61 contextDataRegistration = context.registerService(ContextDataProvider.class, threadContextProvider, null);
6562 loadContextProviders(context);
6663 // allow the user to override the default ContextSelector (e.g., by using BasicContextSelector for a global cfg)
6764 if (PropertiesUtil.getProperties().getStringProperty(Constants.LOG4J_CONTEXT_SELECTOR) == null) {
113110
114111 @Override
115112 public void stop(final BundleContext context) throws Exception {
116 provideRegistration.unregister();
117113 contextDataRegistration.unregister();
118114 this.contextRef.compareAndSet(context, null);
119115 LogManager.shutdown();
116 super.stop(context);
120117 }
121118
122119 @Override
9292 }
9393 final PatternParser parser = PatternLayout.createPatternParser(config);
9494 final List<PatternFormatter> formatters = parser.parse(options[0]);
95 final String style = AnsiEscape.createSequence(options[1].split(Patterns.COMMA_SEPARATOR));
95 final String style = AnsiEscape.createSequence(options[1].split(Patterns.COMMA_SPACE_SEPARATOR));
9696 final boolean disableAnsi = Arrays.toString(options).contains(PatternParser.DISABLE_ANSI + "=true");
9797 final boolean noConsoleNoAnsi = Arrays.toString(options).contains(PatternParser.NO_CONSOLE_NO_ANSI + "=true");
9898 final boolean hideAnsi = disableAnsi || (noConsoleNoAnsi && System.console() == null);
7979 * class ({@code Loader}). Under JDK 1.1, only the class
8080 * loader that loaded this class ({@code Loader}) is used.</li>
8181 * <li>Try one last time with
82 * {@code ClassLoader.getSystemResource(resource)}, that is is
82 * {@code ClassLoader.getSystemResource(resource)}, that is
8383 * using the system class loader in JDK 1.2 and virtual machine's
8484 * built-in class loader in JDK 1.1.</li>
8585 * </ol>
141141 * class ({@code Loader}). Under JDK 1.1, only the class
142142 * loader that loaded this class ({@code Loader}) is used.</li>
143143 * <li>Try one last time with
144 * {@code ClassLoader.getSystemResource(resource)}, that is is
144 * {@code ClassLoader.getSystemResource(resource)}, that is
145145 * using the system class loader in JDK 1.2 and virtual machine's
146146 * built-in class loader in JDK 1.1.</li>
147147 * </ol>
2828 public static final String COMMA_SEPARATOR = toWhitespaceSeparator(",");
2929
3030 /**
31 * A pattern string for lists separated by commas with optional whitespace or just whitespace.
32 */
33 public static final String COMMA_SPACE_SEPARATOR = toWhitespaceSeparator("[,\\s]");
34
35 /**
3136 * The whitespace pattern string.
3237 */
3338 public static final String WHITESPACE = "\\s*";
144144 * Constructs a new {@code Source} from the specified URL.
145145 *
146146 * @param url the URL where the input stream originated
147 * @throws IllegalArgumentException if this URL is not formatted strictly according to to RFC2396 and cannot be
147 * @throws IllegalArgumentException if this URL is not formatted strictly according to RFC2396 and cannot be
148148 * converted to a URI.
149149 */
150150 public Source(final URL url) {
1717
1818 import com.google.monitoring.runtime.instrumentation.AllocationRecorder;
1919 import com.google.monitoring.runtime.instrumentation.Sampler;
20 import org.apache.logging.log4j.Level;
2021 import org.apache.logging.log4j.LogManager;
2122 import org.apache.logging.log4j.Marker;
2223 import org.apache.logging.log4j.MarkerManager;
5657 final Marker testGrandParent = MarkerManager.getMarker("testGrandParent");
5758 final Marker testParent = MarkerManager.getMarker("testParent").setParents(testGrandParent);
5859 final Marker test = MarkerManager.getMarker("test").setParents(testParent); // initial creation, value is cached
60 final StringMapMessage mapMessage = new StringMapMessage().with("eventId", "Login");
5961
6062 // initialize LoggerContext etc.
6163 // This is not steady-state logging and will allocate objects.
6870 logger.error("Sample error message");
6971 logger.error("Test parameterized message {}", "param");
7072 logger.error(new StringMapMessage().with("eventId", "Login")); // initialize GelfLayout's messageStringBuilder
73 singleLoggingIteration(logger, myCharSeq, mapMessage);
7174 for (int i = 0; i < 256; i++) {
7275 logger.debug("ensure all ringbuffer slots have been used once"); // allocate MutableLogEvent.messageText
7376 }
99102 new RuntimeException().printStackTrace();
100103 };
101104 Thread.sleep(500);
102 final StringMapMessage mapMessage = new StringMapMessage().with("eventId", "Login");
103105 AllocationRecorder.addSampler(sampler);
104106
105107 // now do some steady-state logging
109111
110112 final int ITERATIONS = 5;
111113 for (int i = 0; i < ITERATIONS; i++) {
112 logger.error(myCharSeq);
113 logger.error(MarkerManager.getMarker("test"), myCharSeq);
114 logger.error("Test message");
115 logger.error("Test parameterized message {}", "param");
116 logger.error("Test parameterized message {}{}", "param", "param2");
117 logger.error("Test parameterized message {}{}{}", "param", "param2", "abc");
118 logger.error(mapMessage); // LOG4J2-1683
114 singleLoggingIteration(logger, myCharSeq, mapMessage);
119115 ThreadContext.remove("aKey");
120116 ThreadContext.put("aKey", "value1");
121117 }
123119 samplingEnabled.set(false); // reliably ignore all allocations from now on
124120 AllocationRecorder.removeSampler(sampler);
125121 Thread.sleep(100);
122 }
123
124 private static void singleLoggingIteration(
125 final org.apache.logging.log4j.Logger logger,
126 final MyCharSeq myCharSeq,
127 final StringMapMessage mapMessage) {
128 logger.isEnabled(Level.TRACE);
129 logger.isEnabled(Level.TRACE, MarkerManager.getMarker("test"));
130 logger.isTraceEnabled();
131 logger.isTraceEnabled(MarkerManager.getMarker("test"));
132 logger.trace(myCharSeq);
133 logger.trace(MarkerManager.getMarker("test"), myCharSeq);
134 logger.trace("Test message");
135 logger.trace("Test parameterized message {}", "param");
136 logger.trace("Test parameterized message {}{}", "param", "param2");
137 logger.trace("Test parameterized message {}{}{}", "param", "param2", "abc");
138 logger.trace(MarkerManager.getMarker("test"), "Test parameterized message {}{}{}", "param", "param2", "abc");
139 logger.trace(mapMessage); // LOG4J2-1683
140
141 logger.isEnabled(Level.DEBUG);
142 logger.isEnabled(Level.DEBUG, MarkerManager.getMarker("test"));
143 logger.isDebugEnabled();
144 logger.isDebugEnabled(MarkerManager.getMarker("test"));
145 logger.debug(myCharSeq);
146 logger.debug(MarkerManager.getMarker("test"), myCharSeq);
147 logger.debug("Test message");
148 logger.debug("Test parameterized message {}", "param");
149 logger.debug("Test parameterized message {}{}", "param", "param2");
150 logger.debug("Test parameterized message {}{}{}", "param", "param2", "abc");
151 logger.debug(MarkerManager.getMarker("test"), "Test parameterized message {}{}{}", "param", "param2", "abc");
152 logger.debug(mapMessage); // LOG4J2-1683
153
154 logger.isEnabled(Level.INFO);
155 logger.isEnabled(Level.INFO, MarkerManager.getMarker("test"));
156 logger.isInfoEnabled();
157 logger.isInfoEnabled(MarkerManager.getMarker("test"));
158 logger.info(myCharSeq);
159 logger.info(MarkerManager.getMarker("test"), myCharSeq);
160 logger.info("Test message");
161 logger.info("Test parameterized message {}", "param");
162 logger.info("Test parameterized message {}{}", "param", "param2");
163 logger.info("Test parameterized message {}{}{}", "param", "param2", "abc");
164 logger.info(MarkerManager.getMarker("test"), "Test parameterized message {}{}{}", "param", "param2", "abc");
165 logger.info(mapMessage); // LOG4J2-1683
166
167 logger.isEnabled(Level.WARN);
168 logger.isEnabled(Level.WARN, MarkerManager.getMarker("test"));
169 logger.isWarnEnabled();
170 logger.isWarnEnabled(MarkerManager.getMarker("test"));
171 logger.warn(myCharSeq);
172 logger.warn(MarkerManager.getMarker("test"), myCharSeq);
173 logger.warn("Test message");
174 logger.warn("Test parameterized message {}", "param");
175 logger.warn("Test parameterized message {}{}", "param", "param2");
176 logger.warn("Test parameterized message {}{}{}", "param", "param2", "abc");
177 logger.warn(MarkerManager.getMarker("test"), "Test parameterized message {}{}{}", "param", "param2", "abc");
178 logger.warn(mapMessage); // LOG4J2-1683
179
180 logger.isEnabled(Level.ERROR);
181 logger.isEnabled(Level.ERROR, MarkerManager.getMarker("test"));
182 logger.isErrorEnabled();
183 logger.isErrorEnabled(MarkerManager.getMarker("test"));
184 logger.error(myCharSeq);
185 logger.error(MarkerManager.getMarker("test"), myCharSeq);
186 logger.error("Test message");
187 logger.error("Test parameterized message {}", "param");
188 logger.error("Test parameterized message {}{}", "param", "param2");
189 logger.error("Test parameterized message {}{}{}", "param", "param2", "abc");
190 logger.error(MarkerManager.getMarker("test"), "Test parameterized message {}{}{}", "param", "param2", "abc");
191 logger.error(mapMessage); // LOG4J2-1683
192
193 logger.isEnabled(Level.FATAL);
194 logger.isEnabled(Level.FATAL, MarkerManager.getMarker("test"));
195 logger.isFatalEnabled();
196 logger.isFatalEnabled(MarkerManager.getMarker("test"));
197 logger.fatal(myCharSeq);
198 logger.fatal(MarkerManager.getMarker("test"), myCharSeq);
199 logger.fatal("Test message");
200 logger.fatal("Test parameterized message {}", "param");
201 logger.fatal("Test parameterized message {}{}", "param", "param2");
202 logger.fatal("Test parameterized message {}{}{}", "param", "param2", "abc");
203 logger.fatal(MarkerManager.getMarker("test"), "Test parameterized message {}{}{}", "param", "param2", "abc");
204 logger.fatal(mapMessage); // LOG4J2-1683
126205 }
127206
128207 public static void runTest(final Class<?> cls) throws Exception {
3434 import static org.junit.jupiter.api.Assertions.assertTrue;
3535
3636 /**
37 * Tests that logged strings appear in the file, that the initial file size is the specified specified region length,
37 * Tests that logged strings appear in the file, that the initial file size is the specified region length,
3838 * that the file is extended by region length when necessary, and that the file is shrunk to its actual usage when done.
3939 *
4040 * @since 2.1
4545 this.createAndAddAppender();
4646
4747 // let's write something to the logger to ensure the output stream is opened.
48 // We expect this call to create a a new output stream (which is does).
48 // We expect this call to create a new output stream (which is does).
4949 // see OutputStreamManager.writeToDestination(...).
5050 Logger logger = (Logger)LogManager.getLogger(this.getClass());
5151 logger.info("test message 1");
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j.core.appender.rolling;
17
18 import java.io.File;
19 import java.util.Arrays;
20 import java.util.regex.Pattern;
21
22 import org.apache.logging.log4j.Logger;
23 import org.apache.logging.log4j.core.appender.RollingFileAppender;
24 import org.apache.logging.log4j.junit.LoggerContextRule;
25 import org.junit.Rule;
26 import org.junit.Test;
27 import org.junit.rules.RuleChain;
28
29 import static org.junit.Assert.assertEquals;
30 import static org.junit.Assert.assertTrue;
31 import static org.junit.Assert.fail;
32 import static org.junit.jupiter.api.Assertions.assertNotNull;
33
34 /**
35 *
36 */
37 public class RollingAppenderDirectCustomDeleteActionTest implements RolloverListener {
38
39 private static final String CONFIG = "log4j-rolling-direct-with-custom-delete.xml";
40 private static final String DIR = "target/rolling-direct-with-delete/test";
41
42 private final LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG);
43
44 @Rule
45 public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR);
46
47 private boolean fileFound = false;
48
49 @Test
50 public void testAppender() throws Exception {
51 final Logger logger = loggerContextRule.getLogger();
52 RollingFileAppender app = loggerContextRule.getAppender("RollingFile");
53 assertNotNull(app,"No RollingFileAppender");
54 app.getManager().addRolloverListener(this);
55 // Trigger the rollover
56 for (int i = 0; i < 10; ++i) {
57 // 30 chars per message: each message triggers a rollover
58 logger.debug("This is a test message number " + i); // 30 chars:
59 }
60 Thread.sleep(100); // Allow time for rollover to complete
61
62 final File dir = new File(DIR);
63 assertTrue("Dir " + DIR + " should exist", dir.exists());
64 assertTrue("Dir " + DIR + " should contain files", dir.listFiles().length > 0);
65
66 final File[] files = dir.listFiles();
67 assertNotNull(files, "No fiels");
68 System.out.println(files[0].getName());
69 long count = Arrays.stream(files).filter((f) -> f.getName().endsWith("test-4.log")).count();
70 assertTrue("Deleted file was not created", fileFound);
71 assertEquals("File count expected: 0, actual: " + count, 0, count);
72 }
73
74 public static void main(final String[] args) {
75 final Pattern p = Pattern.compile("test-.?[2,4,6,8,0]\\.log\\.gz");
76 for (int i = 0; i < 16; i++) {
77 final String str = "test-" + i + ".log.gz";
78 final java.util.regex.Matcher m = p.matcher(str);
79 System.out.println(m.matches() + ": " + str);
80 }
81 }
82
83 @Override
84 public void rolloverTriggered(String fileName) {
85 if (fileName.endsWith("test-4.log")) {
86 fileFound = true;
87 }
88 }
89
90 @Override
91 public void rolloverComplete(String fileName) {
92
93 }
94 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j.core.appender.rolling;
17
18 import org.apache.logging.log4j.core.Logger;
19 import org.apache.logging.log4j.core.LoggerContext;
20 import org.apache.logging.log4j.junit.CleanUpDirectories;
21 import org.apache.logging.log4j.junit.LoggerContextSource;
22 import org.junit.jupiter.api.Test;
23
24 import java.io.File;
25 import java.time.LocalTime;
26
27 import static org.junit.jupiter.api.Assertions.assertTrue;
28
29 @CleanUpDirectories(RollingRandomAppenderDirectWriteAndSwitchDirectorTest.DIR)
30 public class RollingRandomAppenderDirectWriteAndSwitchDirectorTest {
31 public static final String DIR = "target/rolling-random-direct-switch-director";
32 @Test
33 @LoggerContextSource(value= "log4j-rolling-random-direct-switch-director.xml", timeout = 10)
34 public void testAppender(final LoggerContext context) throws Exception {
35 Logger logger = context.getLogger(RollingRandomAppenderDirectWriteAndSwitchDirectorTest.class.getName());
36 LocalTime start = LocalTime.now();
37 LocalTime end;
38 do {
39 end = LocalTime.now();
40 logger.info("test log");
41 Thread.sleep(100);
42 } while (start.getSecond() == end.getSecond());
43
44 File nextLogFile = new File(String.format("%s/%d/%d.log", DIR, end.getSecond(), end.getSecond()));
45 assertTrue(nextLogFile.exists(), "nextLogFile not created");
46 }
47 }
8686 assertEquals(value, actualList.get(i).getValue(), "value[" + i + "]");
8787 }
8888 }
89
90 @Test
91 public void testLevel() {
92 Configuration configuration = new DefaultConfiguration();
93 LoggerConfig config1 = LoggerConfig.newBuilder()
94 .withLoggerName("org.apache.logging.log4j.test")
95 .withLevel(Level.ERROR)
96 .withAdditivity(false)
97 .withConfig(configuration)
98 .build();
99 LoggerConfig config2 = LoggerConfig.newBuilder()
100 .withLoggerName("org.apache.logging.log4j")
101 .withAdditivity(false)
102 .withConfig(configuration)
103 .build();
104 config1.setParent(config2);
105 assertEquals(config1.getLevel(), Level.ERROR, "Unexpected Level");
106 assertEquals(config1.getExplicitLevel(), Level.ERROR, "Unexpected explicit level");
107 assertEquals(config2.getLevel(), Level.ERROR, "Unexpected Level");
108 assertNull(config2.getExplicitLevel(),"Unexpected explicit level");
109 }
89110 }
1515 */
1616 package org.apache.logging.log4j.core.layout;
1717
18 import com.fasterxml.jackson.core.io.JsonStringEncoder;
18 import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals;
19 import static org.assertj.core.api.Assertions.assertThat;
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.util.List;
26 import java.util.zip.GZIPInputStream;
27 import java.util.zip.InflaterInputStream;
28
1929 import org.apache.commons.io.IOUtils;
2030 import org.apache.logging.log4j.Level;
2131 import org.apache.logging.log4j.ThreadContext;
3242 import org.apache.logging.log4j.junit.UsingAnyThreadContext;
3343 import org.apache.logging.log4j.test.appender.EncodingListAppender;
3444 import org.apache.logging.log4j.test.appender.ListAppender;
45 import org.apache.logging.log4j.util.Chars;
3546 import org.junit.jupiter.api.AfterAll;
3647 import org.junit.jupiter.api.BeforeAll;
3748 import org.junit.jupiter.api.Test;
3849
39 import java.io.ByteArrayInputStream;
40 import java.io.IOException;
41 import java.io.InputStream;
42 import java.util.List;
43 import java.util.zip.GZIPInputStream;
44 import java.util.zip.InflaterInputStream;
45
46 import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals;
47 import static org.junit.jupiter.api.Assertions.*;
50 import com.fasterxml.jackson.core.io.JsonStringEncoder;
4851
4952 @UsingAnyThreadContext
5053 public class GelfLayoutTest {
140143 final String threadName = Thread.currentThread().getName();
141144
142145 //@formatter:off
146 String message = messages.get(0);
147 if (includeNullDelimiter) {
148 assertThat(message.indexOf(Chars.NUL)).isEqualTo(message.length() - 1);
149 message = message.replace(Chars.NUL, Chars.LF);
150 }
143151 assertJsonEquals("{" +
144152 "\"version\": \"1.1\"," +
145153 "\"host\": \"" + host + "\"," +
151159 "\"_" + KEY1 + "\": \"" + VALUE1 + "\"," +
152160 "\"_" + KEY2 + "\": \"" + javaLookup.getRuntime() + "\"" +
153161 "}",
154 messages.get(0));
155
162 message);
163
164 message = messages.get(1);
165 if (includeNullDelimiter) {
166 assertThat(message.indexOf(Chars.NUL)).isEqualTo(message.length() - 1);
167 message = message.replace(Chars.NUL, Chars.LF);
168 }
156169 assertJsonEquals("{" +
157170 "\"version\": \"1.1\"," +
158171 "\"host\": \"" + host + "\"," +
169182 "\"_" + KEY1 + "\": \"" + VALUE1 + "\"," +
170183 "\"_" + KEY2 + "\": \"" + javaLookup.getRuntime() + "\"" +
171184 "}",
172 messages.get(1));
185 message);
173186 //@formatter:on
174187 final byte[] compressed = raw.get(2);
175188 final byte[] compressed2 = raw2.get(2);
197210 final byte[] uncompressed2 = IOUtils.toByteArray(inflaterStream2);
198211 inflaterStream.close();
199212 inflaterStream2.close();
200 final String uncompressedString = new String(uncompressed, layout.getCharset());
201 final String uncompressedString2 = new String(uncompressed2, layout.getCharset());
213 String uncompressedString = new String(uncompressed, layout.getCharset());
214 String uncompressedString2 = new String(uncompressed2, layout.getCharset());
202215 //@formatter:off
203216 final String expected = "{" +
204217 "\"version\": \"1.1\"," +
218231 "\"_" + KEY2 + "\": \"" + javaLookup.getRuntime() + "\"" +
219232 "}";
220233 //@formatter:on
234 if (includeNullDelimiter) {
235 assertEquals(uncompressedString.indexOf(Chars.NUL), uncompressedString.length() - 1);
236 assertEquals(uncompressedString2.indexOf(Chars.NUL), uncompressedString2.length() - 1);
237 uncompressedString = uncompressedString.replace(Chars.NUL, Chars.LF);
238 uncompressedString2 = uncompressedString2.replace(Chars.NUL, Chars.LF);
239 }
240 if (includeNewLineDelimiter) {
241 assertEquals(uncompressedString.indexOf(Chars.LF), uncompressedString.length() - 1);
242 assertEquals(uncompressedString2.indexOf(Chars.LF), uncompressedString2.length() - 1);
243 }
221244 assertJsonEquals(expected, uncompressedString);
222245 assertJsonEquals(expected, uncompressedString2);
223 if (includeNullDelimiter) {
224 assertEquals(uncompressedString.indexOf('\0'), uncompressedString.length() - 1);
225 assertEquals(uncompressedString2.indexOf('\0'), uncompressedString2.length() - 1);
226 }
227 if (includeNewLineDelimiter) {
228 assertEquals(uncompressedString.indexOf('\n'), uncompressedString.length() - 1);
229 assertEquals(uncompressedString2.indexOf('\n'), uncompressedString2.length() - 1);
230 }
231246 }
232247
233248 @Test
3636 import org.apache.logging.log4j.core.Logger;
3737 import org.apache.logging.log4j.core.LoggerContext;
3838 import org.apache.logging.log4j.core.config.ConfigurationFactory;
39 import org.apache.logging.log4j.core.config.DefaultConfiguration;
40 import org.apache.logging.log4j.core.config.Node;
41 import org.apache.logging.log4j.core.config.plugins.util.PluginBuilder;
42 import org.apache.logging.log4j.core.config.plugins.util.PluginManager;
43 import org.apache.logging.log4j.core.config.plugins.util.PluginType;
3944 import org.apache.logging.log4j.core.net.Facility;
4045 import org.apache.logging.log4j.core.util.Integers;
4146 import org.apache.logging.log4j.core.util.KeyValuePair;
568573 }
569574 }
570575
576 @Test
577 public void testLayoutBuilderDefaultValues() {
578 final Rfc5424Layout layout = new Rfc5424Layout.Rfc5424LayoutBuilder().build();
579 checkDefaultValues(layout);
580
581 final PluginManager manager = new PluginManager(Node.CATEGORY);
582 manager.collectPlugins();
583 final Object obj = new PluginBuilder(manager.getPluginType("Rfc5424Layout")).withConfigurationNode(new Node())
584 .withConfiguration(new DefaultConfiguration())
585 .build();
586 assertTrue(obj instanceof Rfc5424Layout);
587 checkDefaultValues((Rfc5424Layout) obj);
588 }
589
590 private void checkDefaultValues(final Rfc5424Layout layout) {
591 assertNotNull(layout);
592 assertEquals(Facility.LOCAL0, layout.getFacility());
593 assertEquals(String.valueOf(Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER), layout.getEnterpriseNumber());
594 assertEquals(true, layout.isIncludeMdc());
595 assertEquals(Rfc5424Layout.DEFAULT_MDCID, layout.getMdcId());
596 assertEquals(Rfc5424Layout.DEFAULT_ID, layout.getDefaultId());
597 }
598
571599 @ParameterizedTest
572600 @ValueSource(strings = { "123456789", "0", "2147483647", "123.45.6.78.9", "0.0.0.0.0.0.0.0.0.0.0.0.0.0" })
573601 void testLayoutBuilderValidEids(String eid) {
1515 */
1616 package org.apache.logging.log4j.core.net.ssl;
1717
18 import org.junit.jupiter.api.Test;
18 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
19 import static org.junit.jupiter.api.Assertions.assertNotNull;
20 import static org.junit.jupiter.api.Assertions.assertSame;
21 import static org.junit.jupiter.api.Assertions.assertThrows;
1922
2023 import java.security.KeyStore;
24 import java.util.Collections;
25 import java.util.function.Supplier;
26 import java.util.stream.Stream;
2127
22 import static org.junit.jupiter.api.Assertions.*;
28 import org.junit.jupiter.api.Test;
29 import org.junit.jupiter.api.condition.OS;
30 import org.junit.jupiter.params.ParameterizedTest;
31 import org.junit.jupiter.params.provider.Arguments;
32 import org.junit.jupiter.params.provider.MethodSource;
33 import org.junitpioneer.jupiter.SetSystemProperty;
2334
35 @SetSystemProperty(key = "sun.security.mscapi.keyStoreCompatibilityMode", value = "false")
2436 public class KeyStoreConfigurationTest {
37
2538 @SuppressWarnings("deprecation")
2639 @Test
2740 public void loadEmptyConfigurationDeprecated() {
4255 TestConstants.KEYSTORE_TYPE, null);
4356 final KeyStore ks = ksc.getKeyStore();
4457 assertNotNull(ks);
58 checkKeystoreConfiguration(ksc);
4559 }
4660
47 @Test
48 public void loadNotEmptyConfiguration() throws StoreConfigurationException {
49 final KeyStoreConfiguration ksc = new KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, new MemoryPasswordProvider(TestConstants.KEYSTORE_PWD()),
50 TestConstants.KEYSTORE_TYPE, null);
61 static Stream<Arguments> configurations() {
62 final Stream.Builder<Arguments> builder = Stream.builder();
63 builder.add(Arguments.of(TestConstants.KEYSTORE_FILE, (Supplier<char[]>) TestConstants::KEYSTORE_PWD,
64 TestConstants.KEYSTORE_TYPE))
65 .add(Arguments.of(TestConstants.KEYSTORE_PKCS12_FILE,
66 (Supplier<char[]>) TestConstants::KEYSTORE_PKCS12_PWD, TestConstants.KEYSTORE_PKCS12_TYPE))
67 .add(Arguments.of(TestConstants.KEYSTORE_EMPTYPASS_FILE,
68 (Supplier<char[]>) TestConstants::KEYSTORE_EMPTYPASS_PWD,
69 TestConstants.KEYSTORE_EMPTYPASS_TYPE));
70 if (OS.WINDOWS.isCurrentOs()) {
71 builder.add(Arguments.of(null, (Supplier<char[]>) () -> null, "Windows-MY"))
72 .add(Arguments.of(null, (Supplier<char[]>) () -> null, "Windows-ROOT"));
73 }
74 return builder.build();
75 }
76
77 @ParameterizedTest
78 @MethodSource("configurations")
79 public void loadNotEmptyConfiguration(final String keystoreFile, final Supplier<char[]> password,
80 final String keystoreType) throws StoreConfigurationException {
81 final KeyStoreConfiguration ksc = new KeyStoreConfiguration(keystoreFile,
82 new MemoryPasswordProvider(password.get()), keystoreType, null);
5183 final KeyStore ks = ksc.getKeyStore();
5284 assertNotNull(ks);
85 checkKeystoreConfiguration(ksc);
5386 }
5487
5588 @Test
78111 () -> new KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, "wrongPassword!", null, null));
79112 }
80113
81 @Test
82 public void wrongPassword() {
83 assertThrows(StoreConfigurationException.class, () -> new KeyStoreConfiguration(TestConstants.KEYSTORE_FILE,
84 new MemoryPasswordProvider("wrongPassword!".toCharArray()), null, null));
114 static Stream<Arguments> wrongConfigurations() {
115 final Stream.Builder<Arguments> builder = Stream.builder();
116 builder.add(Arguments.of(TestConstants.KEYSTORE_FILE, (Supplier<char[]>) TestConstants::KEYSTORE_EMPTYPASS_PWD,
117 TestConstants.KEYSTORE_TYPE))
118 .add(Arguments.of(TestConstants.KEYSTORE_FILE, (Supplier<char[]>) () -> "wrongPassword!".toCharArray(),
119 TestConstants.KEYSTORE_TYPE))
120 .add(Arguments.of(TestConstants.KEYSTORE_PKCS12_FILE,
121 (Supplier<char[]>) TestConstants::KEYSTORE_EMPTYPASS_PWD, TestConstants.KEYSTORE_PKCS12_TYPE))
122 .add(Arguments.of(TestConstants.KEYSTORE_PKCS12_FILE,
123 (Supplier<char[]>) TestConstants::KEYSTORE_EMPTYPASS_PWD, TestConstants.KEYSTORE_PKCS12_TYPE));
124 if (OS.WINDOWS.isCurrentOs()) {
125 builder.add(Arguments.of(null, (Supplier<char[]>) () -> new char[0], "Windows-MY"))
126 .add(Arguments.of(null, (Supplier<char[]>) () -> new char[0], "Windows-ROOT"));
127 }
128 return builder.build();
129 }
130
131 @ParameterizedTest
132 @MethodSource("wrongConfigurations")
133 public void wrongPassword(final String keystoreFile, final Supplier<char[]> password, final String keystoreType) {
134 assertThrows(StoreConfigurationException.class, () -> new KeyStoreConfiguration(keystoreFile,
135 new MemoryPasswordProvider(password.get()), keystoreType, null));
136 }
137
138 static void checkKeystoreConfiguration(final AbstractKeyStoreConfiguration config) {
139 // Not all keystores throw immediately if the password is wrong
140 assertDoesNotThrow(() -> {
141 final KeyStore ks = config.load();
142 for (final String alias : Collections.list(ks.aliases())) {
143 if (ks.isCertificateEntry(alias)) {
144 ks.getCertificate(alias);
145 }
146 if (ks.isKeyEntry(alias)) {
147 ks.getKey(alias, config.getPasswordAsCharArray());
148 }
149 }
150 });
85151 }
86152 }
1919 import static org.junit.jupiter.api.Assertions.assertNull;
2020
2121 import java.util.Properties;
22 import java.util.stream.Stream;
2223
2324 import org.apache.logging.log4j.util.PropertiesUtil;
2425 import org.junit.jupiter.api.Test;
26 import org.junit.jupiter.api.condition.EnabledOnOs;
27 import org.junit.jupiter.api.condition.OS;
28 import org.junit.jupiter.params.ParameterizedTest;
29 import org.junit.jupiter.params.provider.Arguments;
30 import org.junit.jupiter.params.provider.MethodSource;
2531
2632 public class SslConfigurationFactoryTest {
2733
34 private static final String trustStorelocation = "log4j2.trustStoreLocation";
35 private static final String trustStorePassword = "log4j2.trustStorePassword";
36 private static final String trustStoreKeyStoreType = "log4j2.trustStoreKeyStoreType";
37 private static final String keyStoreLocation = "log4j2.keyStoreLocation";
38 private static final String keyStorePassword = "log4j2.keyStorePassword";
39 private static final String keyStoreType = "log4j2.keyStoreType";
40
2841 private static void addKeystoreConfiguration(Properties props) {
29 props.setProperty("log4j2.keyStoreLocation", TestConstants.KEYSTORE_FILE_RESOURCE);
30 props.setProperty("log4j2.keyStoreKeyStoreType", TestConstants.KEYSTORE_TYPE);
42 props.setProperty(keyStoreLocation, TestConstants.KEYSTORE_FILE_RESOURCE);
43 props.setProperty(keyStoreType, TestConstants.KEYSTORE_TYPE);
3144 }
3245
3346 private static void addTruststoreConfiguration(Properties props) {
34 props.setProperty("log4j2.trustStoreLocation", TestConstants.TRUSTSTORE_FILE_RESOURCE);
35 props.setProperty("log4j2.trustStoreKeyStoreType", TestConstants.TRUSTSTORE_TYPE);
47 props.setProperty(trustStorelocation, TestConstants.TRUSTSTORE_FILE_RESOURCE);
48 props.setProperty(trustStoreKeyStoreType, TestConstants.TRUSTSTORE_TYPE);
3649 }
3750
3851 @Test
6881 assertNotNull(sslConfiguration.getKeyStoreConfig());
6982 assertNotNull(sslConfiguration.getTrustStoreConfig());
7083 }
84
85 static Stream<Arguments> windowsKeystoreConfigs() {
86 final String[] emptyOrNull = { "", null };
87 final Stream.Builder<Arguments> builder = Stream.builder();
88 for (final String location : emptyOrNull) {
89 for (final String password : emptyOrNull) {
90 builder.add(Arguments.of(location, password));
91 }
92 }
93 return builder.build();
94 }
95
96 @EnabledOnOs(OS.WINDOWS)
97 @ParameterizedTest
98 @MethodSource("windowsKeystoreConfigs")
99 public void testPasswordLessStores(final String location, final String password) {
100 final Properties props = new Properties();
101 props.setProperty(keyStoreType, "Windows-MY");
102 props.setProperty(trustStoreKeyStoreType, "Windows-ROOT");
103 if (location != null) {
104 props.setProperty(keyStoreLocation, location);
105 props.setProperty(trustStorelocation, location);
106 }
107 if (password != null) {
108 props.setProperty(keyStorePassword, password);
109 props.setProperty(trustStorePassword, password);
110 }
111 final PropertiesUtil util = new PropertiesUtil(props);
112 final SslConfiguration config = SslConfigurationFactory.createSslConfiguration(util);
113 assertNotNull(config);
114 final KeyStoreConfiguration keyStoreConfig = config.getKeyStoreConfig();
115 assertNotNull(keyStoreConfig);
116 KeyStoreConfigurationTest.checkKeystoreConfiguration(keyStoreConfig);
117 final TrustStoreConfiguration trustStoreConfig = config.getTrustStoreConfig();
118 assertNotNull(trustStoreConfig);
119 KeyStoreConfigurationTest.checkKeystoreConfiguration(trustStoreConfig);
120 }
71121 }
3535 public static final char[] KEYSTORE_PWD() { return "changeit".toCharArray(); }
3636 public static final String KEYSTORE_TYPE = "JKS";
3737
38 public static final String KEYSTORE_PKCS12_PATH = PATH;
39 public static final String KEYSTORE_PKCS12_RESOURCE = RESOURCE_ROOT;
40 public static final String KEYSTORE_PKCS12_FILE = KEYSTORE_PKCS12_PATH + "client.log4j2-keystore.p12";
41 public static final String KEYSTORE_PKCS12_FILE_RESOURCE = KEYSTORE_PKCS12_RESOURCE + "client.log4j2-keystore.p12";
42 public static final char[] KEYSTORE_PKCS12_PWD() { return "changeit".toCharArray(); }
43 public static final String KEYSTORE_PKCS12_TYPE = "PKCS12";
44
45 public static final String KEYSTORE_EMPTYPASS_PATH = PATH;
46 public static final String KEYSTORE_EMPTYPASS_RESOURCE = RESOURCE_ROOT;
47 public static final String KEYSTORE_EMPTYPASS_FILE = KEYSTORE_EMPTYPASS_PATH + "client.log4j2-keystore-nopass.p12";
48 public static final String KEYSTORE_EMPTYPASS_FILE_RESOURCE = KEYSTORE_EMPTYPASS_RESOURCE + "client.log4j-keystore-nopass.p12";
49 public static final char[] KEYSTORE_EMPTYPASS_PWD() { return new char[0]; }
50 public static final String KEYSTORE_EMPTYPASS_TYPE = "PKCS12";
51
3852 public static final char[] NULL_PWD = null;
3953 }
1919 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
2020 import org.apache.logging.log4j.message.SimpleMessage;
2121 import org.junit.jupiter.api.Test;
22 import org.junit.jupiter.params.ParameterizedTest;
23 import org.junit.jupiter.params.provider.Arguments;
24 import org.junit.jupiter.params.provider.MethodSource;
2225
2326 import static org.junit.jupiter.api.Assertions.*;
27
28 import java.util.stream.Stream;
2429
2530 /**
2631 * Tests the HighlightConverter.
7580 assertEquals(AnsiEscape.createSequence(colorName), converter.getLevelStyle(Level.DEBUG));
7681 }
7782
78 private void testLevelNames(final String colorName, final String expectedOutput) {
79 final String[] options = {"%-5level: %msg", PatternParser.NO_CONSOLE_NO_ANSI + "=false, "
80 + PatternParser.DISABLE_ANSI + "=false, " + "INFO=" + colorName};
83 static Stream<Arguments> colors() {
84 return Stream.of(
85 Arguments.of("bright red","\u001B[1;31m"),
86 Arguments.of("red bright", "\u001B[31;1m"),
87 Arguments.of("bright_red", "\u001B[91m"),
88 Arguments.of("#1cd42b", "\u001B[38;2;28;212;43m"),
89 Arguments.of("fg_bright_red bg_bright_blue bold", "\u001B[91;104;1m"),
90 Arguments.of("FG_#1cd42b BG_#000000", "\u001B[38;2;28;212;43;48;2;0;0;0m"));
91 }
92
93 @ParameterizedTest
94 @MethodSource("colors")
95 public void testColors(final String colorName, final String escape) {
96 final String[] options = { "%-5level: %msg", PatternParser.NO_CONSOLE_NO_ANSI + "=false, "
97 + PatternParser.DISABLE_ANSI + "=false, " + "INFO=" + colorName };
8198 final HighlightConverter converter = HighlightConverter.newInstance(null, options);
8299 assertNotNull(converter);
83100
84 final LogEvent event = Log4jLogEvent.newBuilder().setLevel(Level.INFO).setLoggerName("a.b.c").setMessage(
85 new SimpleMessage("")).build();
101 final LogEvent event = Log4jLogEvent.newBuilder().setLevel(Level.INFO).build();
86102 final StringBuilder buffer = new StringBuilder();
87103 converter.format(event, buffer);
88 assertEquals(expectedOutput, buffer.toString());
89 }
90
91 @Test
92 public void testLevelNamesBrightShort() {
93 testLevelNames("bright_red", "\u001B[91mINFO : \u001B[m");
94 }
95
96 public void testLevelNamesHexShort() {
97 testLevelNames("#1cd42b", "\u001B[38;2;28;212;43mINFO : \u001B[m");
98 }
99
100 @Test
101 public void testLevelNamesBrightFull() {
102 testLevelNames("fg_bright_red bg_bright_blue bold", "\u001B[91;104;1mINFO : \u001B[m");
103 }
104
105 @Test
106 public void testLevelNamesHexFull() {
107 testLevelNames("FG_#1cd42b BG_#000000", "\u001B[38;2;28;212;43;48;2;0;0;0mINFO : \u001B[m");
104 assertEquals(escape + "INFO : \u001B[m", buffer.toString());
108105 }
109106
110107 @Test
1717
1818 import java.util.List;
1919
20 import org.apache.logging.log4j.Level;
2021 import org.apache.logging.log4j.Logger;
22 import org.apache.logging.log4j.core.LogEvent;
2123 import org.apache.logging.log4j.core.LoggerContext;
24 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
2225 import org.apache.logging.log4j.junit.LoggerContextSource;
2326 import org.apache.logging.log4j.junit.Named;
2427 import org.apache.logging.log4j.test.appender.ListAppender;
2528 import org.apache.logging.log4j.util.Strings;
2629 import org.junit.jupiter.api.BeforeAll;
2730 import org.junit.jupiter.api.Test;
31 import org.junit.jupiter.params.ParameterizedTest;
32 import org.junit.jupiter.params.provider.MethodSource;
2833
2934 import static org.junit.jupiter.api.Assertions.*;
3035
5661 public void testNull() {
5762 assertNull(StyleConverter.newInstance(null, null));
5863 }
64
65 @ParameterizedTest
66 @MethodSource("org.apache.logging.log4j.core.pattern.HighlightConverterTest#colors")
67 public void testHighlightConverterCompatibility(final String color, final String escape) {
68 final StyleConverter converter = StyleConverter.newInstance(null, new String[] { "Hello!", color });
69 final StringBuilder sb = new StringBuilder();
70 final LogEvent event = Log4jLogEvent.newBuilder().setLevel(Level.INFO).build();
71 converter.format(event, sb);
72 assertEquals(escape + "Hello!" + AnsiEscape.getDefaultStyle(), sb.toString());
73 }
74
75 @ParameterizedTest
76 @MethodSource("org.apache.logging.log4j.core.pattern.HighlightConverterTest#colors")
77 public void testLegacyCommaSeparator(final String color, final String escape) {
78 final StyleConverter converter = StyleConverter.newInstance(null,
79 new String[] { "Hello!", color.replaceAll("\\s+", ",") });
80 final StringBuilder sb = new StringBuilder();
81 final LogEvent event = Log4jLogEvent.newBuilder().setLevel(Level.INFO).build();
82 converter.format(event, sb);
83 assertEquals(escape + "Hello!" + AnsiEscape.getDefaultStyle(), sb.toString());
84 }
5985 }
4242
4343 private static class Destination implements ByteBufferDestination {
4444 // JUnit 5 stack traces can start to get looooong
45 ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[8192]);
45 ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16384]);
4646
4747 @Override
4848 public ByteBuffer getByteBuffer() {
5151
5252 @Override
5353 public ByteBuffer drain(final ByteBuffer buf) {
54 throw new IllegalStateException("Unexpected message larger than 4096 bytes");
54 throw new IllegalStateException("Unexpected message larger than 16384 bytes");
5555 }
5656
5757 @Override
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!--
2 Licensed to the Apache Software Foundation (ASF) under one or more
3 contributor license agreements. See the NOTICE file distributed with
4 this work for additional information regarding copyright ownership.
5 The ASF licenses this file to You under the Apache License, Version 2.0
6 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16
17 -->
18 <Configuration status="WARN" name="RollingWithCustomDeleteTest">
19 <Properties>
20 <Property name="base">target/rolling-direct-with-delete/</Property>
21 </Properties>
22
23 <Appenders>
24 <RollingFile name="RollingFile" filePattern="${base}/test/test-%i.log">
25 <PatternLayout>
26 <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
27 </PatternLayout>
28 <Policies>
29 <SizeBasedTriggeringPolicy size="50" />
30 </Policies>
31 <DirectWriteRolloverStrategy maxFiles="100" stopCustomActionsOnError="true">
32 <Delete basePath="${base}/test" maxDepth="2" followLinks="false">
33 <IfFileName glob="test-4.log" /> <!-- only keep files 1, 2 and 3 -->
34 </Delete>
35 </DirectWriteRolloverStrategy>
36 </RollingFile>
37 </Appenders>
38
39 <Loggers>
40 <Root level="trace">
41 <AppenderRef ref="RollingFile" />
42 </Root>
43 </Loggers>
44
45 </Configuration>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!--
2 Licensed to the Apache Software Foundation (ASF) under one or more
3 contributor license agreements. See the NOTICE file distributed with
4 this work for additional information regarding copyright ownership.
5 The ASF licenses this file to You under the Apache License, Version 2.0
6 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16
17 -->
18 <Configuration status="WARN" name="XMLConfigTest">
19 <Properties>
20 <Property name="LOG_HEADER">start log4j-rolling-random-direct-switch-director test</Property>
21 <Property name="LOG_PATTERN">%d %p %C{1.} [%t] %m%n</Property>
22 <Property name="baseDir">target/rolling-random-direct-switch-director</Property>
23 </Properties>
24 <Appenders>
25 <Console name="STDOUT" target="SYSTEM_OUT" follow="true">
26 <PatternLayout header= "${LOG_HEADER}">
27 <Pattern>${LOG_PATTERN}</Pattern>
28 </PatternLayout>
29 </Console>
30 <RollingRandomAccessFile name="RollingFile" filePattern="${baseDir}/%d{s}/%d{s}.log">
31 <PatternLayout header= "${LOG_HEADER}">
32 <Pattern>${LOG_PATTERN}</Pattern>
33 </PatternLayout>
34 <Policies>
35 <TimeBasedTriggeringPolicy/>
36 </Policies>
37 </RollingRandomAccessFile>
38 </Appenders>
39
40 <Loggers>
41 <Logger name="org.apache.logging.log4j.core.appender.rolling" level="debug" additivity="false">
42 <AppenderRef ref="RollingFile"/>
43 </Logger>>
44 <Root level="error">
45 <AppenderRef ref="STDOUT" />
46 </Root>
47 </Loggers>
48 </Configuration>
0 mkdir tmp
1 # Create the CA key and certificate
2 openssl req -config rootca.conf -new -x509 -nodes -keyout tmp/log4j2-cacert.key -out tmp/log4j2-ca.crt -days 7302
3 # Create the trust store and import the certificate
4 keytool -keystore ../truststore.jks -storetype jks -importcert -file 'tmp/log4j2-ca.crt' -keypass changeit -storepass changeit -alias log4j2-cacert -noprompt
5 #Import the root certificate
6 keytool -keystore ../client.log4j2-keystore.jks -alias log4j2-ca -importcert -file tmp/log4j2-ca.crt -keypass changeit -storepass changeit -noprompt
7 # Create the client private key in the client key store
8 keytool -genkeypair -keyalg RSA -alias client -keystore ../client.log4j2-keystore.jks -storepass changeit -keypass changeit -validity 7302 -keysize 2048 -dname "CN=client.log4j2, C=US"
9 # Create a signing request for the client #
10 keytool -keystore ../client.log4j2-keystore.jks -alias client -certreq -file tmp/client.csr -keypass changeit -storepass changeit
11 # Sign the client certificate
12 openssl x509 -req -CA 'tmp/log4j2-ca.crt' -CAkey 'tmp/log4j2-cacert.key' -in tmp/client.csr -out tmp/client.crt_signed -days 7302 -CAcreateserial -passin pass:changeit
13 # Verify the signed certificate
14 openssl verify -CAfile 'tmp/log4j2-ca.crt' tmp/client.crt_signed
15 #Import the client's signed certificate
16 keytool -keystore ../client.log4j2-keystore.jks -alias client -importcert -file tmp/client.crt_signed -keypass changeit -storepass changeit -noprompt
17 #Verify the keystore
18 keytool -list -keystore ../client.log4j2-keystore.jks -storepass changeit
19 # Create the server private key in the server key store
20 keytool -genkeypair -keyalg RSA -alias server -keystore tmp/server.log4j2-keystore.p12 -storepass changeit -storetype PKCS12 -keypass changeit -validity 7302 -keysize 2048 -dname "CN=server.log4j2, C=US"
21 # Create a signing request for the server #
22 keytool -keystore tmp/server.log4j2-keystore.p12 -alias server -certreq -file tmp/server.csr -keypass changeit -storepass changeit
23 # Sign the server certificate
24 openssl x509 -req -CA 'tmp/log4j2-ca.crt' -CAkey 'tmp/log4j2-cacert.key' -in tmp/server.csr -out ../server.log4j2-crt.pem -days 7302 -CAcreateserial -passin pass:changeit
25 # Extract the private key
26 openssl pkcs12 -in tmp/server.log4j2-keystore.p12 -passin pass:changeit -nokeys -out ../server.log4j2.pem
27 rm -rf tmp
0 [ req ]
1 distinguished_name = CA_DN
2 prompt = no
3 output_password = changeit
4 default_bits = 2048
5
6 [ CA_DN ]
7 C = US
8 CN = log4j2-ca
0 [ req ]
1 distinguished_name = CA_DN
2 prompt = no
3 output_password = changeit
4 default_bits = 2048
5
6 [ CA_DN ]
7 C = US
8 CN = iserver.log4j2
+0
-32
log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/client.log4j2-crt.pem less more
0 -----BEGIN CERTIFICATE-----
1 MIIFmDCCA4CgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAhMQswCQYDVQQGEwJVUzES
2 MBAGA1UEAxMJbG9nNGoyLWNhMB4XDTEzMDgwNzE1MDA1M1oXDTIyMDgwNTE1MDA1
3 M1owJTELMAkGA1UEBhMCVVMxFjAUBgNVBAMTDWNsaWVudC5sb2c0ajIwggIiMA0G
4 CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCWTzL0JcyH78O1JBPhgAytdtauJr6a
5 azQyaCSUzNqrEPQFzmcafMjaRvmHzduTnSSS6c5HwqU6nrVTOTkLdmGIiv1R60T4
6 Jvhkvj2wX5SNSAn75T6C5Y9tvr6W0mPgKH0HovXMTOiwZ3rRp6FR8ivvhtVgd1/k
7 cBigxVR3rGpKO4eS84MRmWRnl/X/OEakE0DyKN15MwjrG/Vqw6ATApP1purYcWrc
8 Iw1pnL9rw6KcMUIftfvv0VHvJSh0Vlis3GVNTLcudrNtelW9bzc83HWLCUvu1JMx
9 HnMsYszVjZlQfH4z1Zwa/cnlEGn+YgxHL+QsYm3OW6kf5qT/JdH/nT1sTB0APErk
10 NSd0+gfR2cv/ijKpHJUJieIVN2NmTHQFnh18ZhXWRXQcwtAxtYsSlCJKNRoftYJ5
11 VJsm0Ol7urT2ZM1LbfULC8pYgUE38zwolC86yupemKUb/2ZZiWSvWYqNwphQwr2P
12 Byv3VdRuinQjqkJ4DFZW/o6uqUBYxkSCJa53pEJhlBFPyK5tUXrQC+FVtI/Ddwn7
13 Ajt5N9fEuxGLI9IBnaGAHpdTPhypJLhaJ+1sYI8h+t4C5OS1Tcy8549HGqVDEn1C
14 +mbBgiha+o4Pyayr44/8tis7WVHsG4b9OzzmqtyfZ3BSOQkIwgcpLqtV5RZh8eG6
15 elVMDcbJkEFEnwIDAQABo4HWMIHTMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQD
16 AgZAMCsGCWCGSAGG+EIBDQQeFhxUaW55Q0EgR2VuZXJhdGVkIENlcnRpZmljYXRl
17 MB0GA1UdDgQWBBSV6z9LMG/560CWaF17MPtb2kD0DzBRBgNVHSMESjBIgBTiibBz
18 IjuHGFCXQrPY1v9l0ckTBaElpCMwITELMAkGA1UEBhMCVVMxEjAQBgNVBAMTCWxv
19 ZzRqMi1jYYIJAIPJp0IKQBHEMAkGA1UdEgQCMAAwCQYDVR0RBAIwADANBgkqhkiG
20 9w0BAQsFAAOCAgEAPGSXD9Pp6RYMIvAxKuaNNzUwm8ol35WI5hWgPpxDq0yGJ9ER
21 W5U/V4K5xqFuum3Q94u6K23aSJYYsm3YIR5QOkg5q/1wibvFgGzyd+TfBEvGieHR
22 NZ1FPLCLWA1oia/oYJchEk8V1fBTqmIb3a++JmtUk0tYtBKIplwVeOxxWWyVzFkm
23 kZ07P4lVBPLkT1Xkff2Jb1g+1kBDz+Esh1b8sOd7z2Gu8BHeF4THwpSaTS3lD6Y1
24 2Jg4FOQ6/SYVoGghTBQp7+e8ROPeosNMUGrxhnjlITUyVsMPMszKBm5z4YGC25yj
25 vTzz311fTMm7ylhDIk0PAQHsNz2xntBy0/NiJxVaZI3DluwcfJR0/C5ZLZ7m4VvF
26 SnjNzedY1v8N/o1FD5x71bfvAJ97O46a7H80qPlTo5wxgYh0MwRle8xSJkD1JGvc
27 LPeLTifSsFDJ6N3lbkjc1McclIoG49sCFFShUftwxGBw4Urfmtg/wbj8FETEqBwp
28 buhxYYx+K91dwb+RDu/N1a6F0kbNwvnsH2Zi0SOmh1Otzif27ZUl++eqCxZxM7KO
29 ECI3NEhlbdxaYUwXnAc0rr/OTYV+rSsq5tmXXc+0PyMSFg9PhR/nyrDOXo2rkxg4
30 UVaU5TXuVvI6rIsh+sauSDKzO4/5n3GlZ3QBB+wpvdSeD+eXKMlI9Tw/i/M=
31 -----END CERTIFICATE-----
+0
-32
log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/log4j2-cacert.pem less more
0 -----BEGIN CERTIFICATE-----
1 MIIFhTCCA22gAwIBAgIJAIPJp0IKQBHEMA0GCSqGSIb3DQEBBQUAMCExCzAJBgNV
2 BAYTAlVTMRIwEAYDVQQDEwlsb2c0ajItY2EwHhcNMTMwODA3MTQ1MzA3WhcNMjMw
3 ODA1MTQ1MzA3WjAhMQswCQYDVQQGEwJVUzESMBAGA1UEAxMJbG9nNGoyLWNhMIIC
4 IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvlYBNYEtVS2Wy4YaZc+SSgft
5 TLi25vFtc5UH3kJ62EPrcOxynOJIWbBybPkpL27Vnz+t/KZWTDnxOD2QuwCskm/U
6 XfpQe6V6t0geM1u7HuKYT/X7z4l8WU7w6QzmGe/OWxYj3tE8M85f/HwhlDTVRG/g
7 npLzYCo/oJAvE+IM7FQFG4it/gkt3F/6ekUmc431wMLrKIDBEys78Mx6Ez+G1IAN
8 kSLv8e59XVeWsmgIIpI192VvsvuEPrqpICCE3PG2XKqmbRcDJOxlRRUHgOF8WzTw
9 WFnyGA20xcJ4L9+9+Z8HLTCLKL6+m60lqypdHnd3dp9iTfWVuYvM/7PLORaOEURb
10 WAVp1dXG01p2cuSbjw5+/0BRHFwdcBfW9Vl7R6b7uI1+O80xJK7g6DdYzSfIFpDO
11 88FfGaEwuz+bMVE7MI8wFqXMlwXV6zE9NwWIcl3lKhzgJNtU+lczLyHAEPR0/SRp
12 X3PGp4W4sml3/e4xAZs9Ae4njDzqBMod5EAG/F5WyrIAIwYDD3DGQfcdKrXSCH1K
13 38YFxmm+Awg5ijjr+Y+SbMTee3tKHzCEtDtbIpUXRPraODp00CNA+7qvMI/z+3eW
14 MP/b+84rI/GYkxykLratJ0tSOoJdn7ZOWKL4k/vAkIM43Ie4Paru8aurowi/xFIz
15 8Y94R1LPWqsB7iM2arECAwEAAaOBvzCBvDAdBgNVHQ4EFgQU4omwcyI7hxhQl0Kz
16 2Nb/ZdHJEwUwUQYDVR0jBEowSIAU4omwcyI7hxhQl0Kz2Nb/ZdHJEwWhJaQjMCEx
17 CzAJBgNVBAYTAlVTMRIwEAYDVQQDEwlsb2c0ajItY2GCCQCDyadCCkARxDAPBgNV
18 HRMBAf8EBTADAQH/MBEGCWCGSAGG+EIBAQQEAwIBBjAJBgNVHRIEAjAAMAkGA1Ud
19 EQQCMAAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4ICAQB0rkEVllwI
20 ajaqyDajCKxKAl2euPixzQh3w4Hauip0QwxHwV5lrQUixQ5Qu/7gCxTQL25/K6Zw
21 gwtQ+n6CESL+QTDgL34JOMXXoE+SfEGwcTlyeYKpPzs3fH5rKqzTzGeB4ZnoOzhZ
22 TiHvdUXvLjIKuBEnO8Ho9YG2BnGKCCsCQXaUrf1fT3yKcz4trb8AYzOdJVI93ykH
23 qaYgZGnvnPs8Nafdm8DLF3HloKsofdGjnB1UWtBBX6Rg+wCXS8/Twrc1YYEs2mrq
24 tyKOekvCJvNMZjlIiBN4OPG2N5jW03N3vW2fEsgALj37sI54x7PpNODcFutDWUvJ
25 UsvFofK8Ik2IreA6A6GO1kWEP6VIkYf9RePEVm6+d274AANEUzws2JAj4jKquiNf
26 foaUbuXLC7NIeZ85Jaw0QtNUPiR/jR5wYNZEhWtRZBlME4bH6wYUGywUXzIfInaz
27 NVIUkbyb7R1ljO461miZMxPZgnHy8MW6D2218/KQrERLDjrM/ggFTw7hv5gJWzUQ
28 h0R/VblnkZZPAwNYBM8Q11mCAtt/sU5wEQA6SFJpkqAxzQS438gFYC5QMo7Lb1vp
29 obY84mniOFcpCbY9O2DcXoZTXz22ixMvLu3t2rhLMe+O8RnjCZWh6ynFWa0zFb6E
30 9oCOdepDTGL48lxcOEpnfNYtkn7BG/pS0g==
31 -----END CERTIFICATE-----
00 -----BEGIN CERTIFICATE-----
1 MIIFmDCCA4CgAwIBAgIBATANBgkqhkiG9w0BAQUFADAhMQswCQYDVQQGEwJVUzES
2 MBAGA1UEAxMJbG9nNGoyLWNhMB4XDTEzMDgwNzE0NTcxMFoXDTIyMDgwNTE0NTcx
3 MFowJTELMAkGA1UEBhMCVVMxFjAUBgNVBAMMDXNlcnZlci5sb2c0ajIwggIiMA0G
4 CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ7tnl+byEnkJSePcj9XZ6y1C3eUOo
5 AsI70fgPIemUP+139VGCxa0uvYpE4tri4ZQV9zLq2VLPr9Cu5+ZBvA9ziEoeU3Rg
6 vWIFN1wm+iTJy8mfNI2x/q9W5NiUqjYWZVAJhdImO+wWfKXfhE07CLY/pUrv/QiY
7 EsBXQ3dWGussWu1mVS46B/ehHkNJUZCxbtwvaIZUJwBr0CPVIcv55hwAgD9pyXMn
8 Mfr1ze0iIpvH3gKZEi8Qzlj8HIxjnVOCBGU6r1DhvfNGaGMkmMwclxxhK19mam2t
9 AyscnJJ4HJ+uQZ6jT2CTj5xfeX5kwMy5Eb1gS0cwZrNQYSBdXI1/SNqNIsyI3uZd
10 plZ00X6D9cYTtc8pnSbaCbriDnod5o3e1GgKwhbYZfG92NWR5/XEh7YVqR8gGq+v
11 4I0Zd7ncGPVOkBRzQJpXxzrn+r8bbregqcbFlpR6xtSoJjsjLzl4965/BpipaT9S
12 txO4NS2G5ETmCDViRsmWhNvXPkbhzigNW95p5p33tX7fryWM3kw49qG1u24RbdC2
13 R49nH2xslrKo96IYCCakiu0RJI6kfES7VDukN5bt3kI7jOOzH1GD2TlTIXHKbTkr
14 XpMzl2T7QbmHy2vEtIoEOFNbme7QJ5s3fScyE9IveRfTPyYNDsWXWGSHqPlHUeD7
15 /EKkWaeniZlUIQIDAQABo4HWMIHTMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQD
16 AgZAMCsGCWCGSAGG+EIBDQQeFhxUaW55Q0EgR2VuZXJhdGVkIENlcnRpZmljYXRl
17 MB0GA1UdDgQWBBSOJ6srlIpZgJHLL23jrfzRgq5uvjBRBgNVHSMESjBIgBTiibBz
18 IjuHGFCXQrPY1v9l0ckTBaElpCMwITELMAkGA1UEBhMCVVMxEjAQBgNVBAMTCWxv
19 ZzRqMi1jYYIJAIPJp0IKQBHEMAkGA1UdEgQCMAAwCQYDVR0RBAIwADANBgkqhkiG
20 9w0BAQUFAAOCAgEAXxhzp8omz5kdHOgHTZF2a1QNVf1CiXjRjS/7WHKeykKrZNi0
21 vqdlJIrH62g2l4JC9JaBlVh38PsH/RLuabwWplT8yjos+Tqhh5Vp4Fipm9qEDZh9
22 htlGiitYQD3/H1vtEb2VGL2+pSsFYwCAaztrwO/edfIDjmL2hlA+9MA9YdmH6WhE
23 Vb+uth4vTYeW7VevvX8R4LHLP/sGA4XiMsMlJmuehRsdeRbec9BfmGFhZZ5qOOrL
24 rfBoFlYoyvIRBp1ed9sBmaSJyurwPuZq9uOmbv7QjbaYJmLu/0nBB9yA+loXVIxV
25 l1+y+OV6khatzNOf2hrvTpCwxtlBtyJ5IZXR2Up3tid5+2oaGYW++h5D1QnJ8WAB
26 ORF7IEXiMZCVEwi97IuajZnm5CxgVsKpuELnYQmWZrQvzYuQ8kFTZZ7DEElHgtCT
27 oHl0YSKbfYz5MWxF6cmZGUbePyXPDT4iyh+fl/lfQIt04JUd6EO6hfgTKmqY8iR+
28 RaVLlzGpSzwzNJ8rg4J8JN7IYr9VBX3o52xR9PmdomJBmNFqf17gfNgoulZORngZ
29 JnxgAXSv41k5w+cmi747YUHaGvy7lqb4rfSEoGiENuicQ7g+tDvb0TvhGO8A5jsy
30 kdlWKkvDeCZeG52ctwia5DuhF6KCskCq/F2XJS3qntwOEu0BV4lmmu4hxek=
1 MIICwjCCAaoCCQCZurToALecATANBgkqhkiG9w0BAQUFADAhMQswCQYDVQQGEwJV
2 UzESMBAGA1UEAwwJbG9nNGoyLWNhMB4XDTIyMDgyMjE2NDI0MFoXDTQyMDgxOTE2
3 NDI0MFowJTELMAkGA1UEBhMCVVMxFjAUBgNVBAMTDXNlcnZlci5sb2c0ajIwggEi
4 MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCOqJsHWe/IHWm2vGuZHkKccPeE
5 VsF6cQWzmqSAo29kWRWb7QYlJzoat9W++VnQ1M6x27tnphBBwnh9YTJ6eZpQ+y9h
6 +FnH8/8nIyB8pyP7VZTn993YvmpkdZwT7LMeANJFrPLmYUl0r0tHJEQWbULq8czF
7 B/57/hZVfYBs0/Hj1wnURmQ0RGaARhFYKg1TW2AFLUKrWNw0aiZbcjOcVf61Ysmh
8 99TK1IhL+aOByTB07x9t0xk9caeyfARmHvCh6SFzFGXAc8ov5omZqcBKZS6HS1Ym
9 kd7oqX1p/ZMugc9i35nn2tqQCQxg/+F31H82IhuTAFvRaHwrCJxXA+mApeI/AgMB
10 AAEwDQYJKoZIhvcNAQEFBQADggEBAES9R3yiKuFo901AOpR0EYGM8gPwujiUP4O2
11 whYqlBhPwhrYGlDUzxgt6VmPYaxuD9xhed99U/LThC6CjJFXnGKJL33BQksyjTM5
12 vphUyVXWUiMDhtLdijNOBoI6y3pEL6+k90pfDy8j6SqalukukNfSjNJvPXBpiDyh
13 aLgoixuul0jwZi7vu8k+IKXjRt0NzQaKPLmOFkoccSB0qFkTA+WTd2vzhgS0hH+C
14 k9gCS3XtJhPPWNS3JZ6+UWHbJiGLjm/SfhZifKIuoW5S394p78DIhBk3otopdPrk
15 gz0WZFCA/7m0AtOpmz9YZsS7JocJEvD3RLDZ0owl+9VobKa1kB8=
3116 -----END CERTIFICATE-----
+0
-51
log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/server.log4j2-key.pem less more
0 -----BEGIN RSA PRIVATE KEY-----
1 MIIJKgIBAAKCAgEAye7Z5fm8hJ5CUnj3I/V2estQt3lDqALCO9H4DyHplD/td/VR
2 gsWtLr2KROLa4uGUFfcy6tlSz6/QrufmQbwPc4hKHlN0YL1iBTdcJvokycvJnzSN
3 sf6vVuTYlKo2FmVQCYXSJjvsFnyl34RNOwi2P6VK7/0ImBLAV0N3VhrrLFrtZlUu
4 Ogf3oR5DSVGQsW7cL2iGVCcAa9Aj1SHL+eYcAIA/aclzJzH69c3tIiKbx94CmRIv
5 EM5Y/ByMY51TggRlOq9Q4b3zRmhjJJjMHJccYStfZmptrQMrHJySeByfrkGeo09g
6 k4+cX3l+ZMDMuRG9YEtHMGazUGEgXVyNf0jajSLMiN7mXaZWdNF+g/XGE7XPKZ0m
7 2gm64g56HeaN3tRoCsIW2GXxvdjVkef1xIe2FakfIBqvr+CNGXe53Bj1TpAUc0Ca
8 V8c65/q/G263oKnGxZaUesbUqCY7Iy85ePeufwaYqWk/UrcTuDUthuRE5gg1YkbJ
9 loTb1z5G4c4oDVveaead97V+368ljN5MOPahtbtuEW3QtkePZx9sbJayqPeiGAgm
10 pIrtESSOpHxEu1Q7pDeW7d5CO4zjsx9Rg9k5UyFxym05K16TM5dk+0G5h8trxLSK
11 BDhTW5nu0CebN30nMhPSL3kX0z8mDQ7Fl1hkh6j5R1Hg+/xCpFmnp4mZVCECAwEA
12 AQKCAgEAyXx6Du5RHEKNCp2Ie2jA/2U+9NMantmh1O59BRxhZHslBzzQSBvV4X1e
13 Kb3xidBrYj91nr+Z0YEsSFk7dvuerziePAQpax2MYIgMexe8/V1JoIFfoOrvKVTO
14 hggQT+hnJBlSxrOjrgxRteTc6rqWnorfavafTJ3pLSk0OcZCQc+4cRMtPNoWS71W
15 hiHMrj5flS5GWlFQKkNUfaVrUb440ockvvky3TkRn5IJurWtmo/7J6DtNWevgl85
16 9WtVl7WrDBNCMPzHcMlXo3ySrTRaLNqKJjarmKZArhvMSezFp6nyECFzy8jPzrP7
17 WazGmSMKQrraHYFcCiffk0h2JzsaVVI2trX/czU/rqk9WaJOJkMviaT/wSYoopG5
18 j/GCdYf1wjAWYvys5jLOsvpoPdgPHInbwZRf+BN+Hnp2H/M7tVzJfkOEjU1UVZm1
19 j+qRyEbYA3jel29ghg0YzbXptz47mR+UMt7/jesQL4RMDb2XGzpVSuR0LcGDO3BO
20 i0X8ftawVf6y83RDo1/ngh8zBXUnMNaMqSFoF3AtAqKzmodYWMC7Ihcgo8iKhh3i
21 PdyNGnHIYqB8MFP+O8n1GchOjXdyqzHNo9hLOMdwx075h/PSLSbA3fiVda5UQE/b
22 z36GarSGdRB+H8kUELsAbyK60u7ZVG77+hZFeqHA6s4zZ81VJcECggEBAPQA+W+a
23 BETE6ohHfQup39ii2UFfQX+aafb5sb5CtEw/M/DGQWrW+NTpX95jEdpEv0K4Il7G
24 cB4KgG1nC7hWWZhptuTsQyuV7GCAVz3J1ojFyyRzmQsBrjNeUCak31mNvo31JcSV
25 jJqOooMmgHMz3jcy2iBuTroFrhDcLbrmqZ1IzrMQDaxzIRsp5bS6gr5F7eVa5Q+s
26 cgH2hnsZA+L3tRf7DN/Zop0gKTm0bCP3ikA50vb8DGg4+BLMq9bwLHS8X8ZUyRmS
27 w3rCfuONP/631PPpyNMmobhjsEYEWebwTm6GewbT2ct3+LKThwuEsuq/nckoSxyD
28 Zv4qfk/9MwAJ02cCggEBANPcX/fjBO1dSPuPVbbHi607jBjYi+0eXi6RQ/ac0Wud
29 fkmrtyolWBbx/4QMXt3/seDjmGLFjzvAmfJAq8KqctX47Uoxbavcd+IcBwZkKd47
30 INbXeCJ0v4Rf0ek7il2ZnRmQtp4jrcQ1Tj1Z0vp5eb+oQCQa8WSLok4DDjFqlhe4
31 ki9yqIz+37MSQdnfvXRA0q5vYI1tpLOSSh/ytRO+FYmCs+T0ZSxx1ghieT4DcJjZ
32 tkiQitUgMJdGjkboLXbnLHbDuXVKQvxk+Vq0wKiwxFhsew954OM9mIU6E67i/2A9
33 daE+iYOUWkVZS69HspfwcRONrUa3xtLkTFAT2dHLLzcCggEAYQGuKT9bKRf8gheh
34 0CxGMTN1GjdLq/Zw4F6e2pxcX9/Uv4miYl566PKrSZerdlJUk6rvByzvUBIuws/v
35 6eZyklSdAOApSD+/jRIZHRiMcS3puGE43BZb8lIxnVt47Hqc4oUu8bve/WdtlqSM
36 9sANPXa7H5+bLvupG0zd5WtkzYIvoyLjvMa8x7bdev+XkRvuG3wKizOs07j1+CSW
37 1fpTBeiqUqiMrNknaqifQaFdVnFmvQixyhG0Fo1GWBp+Ih7uGMSGeuNNUhXXKpJy
38 ecsOH7a3P7MhIlSHtR5vu4+YLvrKGInLEchtmFlsnBiypP9vNJUPX5OiM7QjKZvp
39 Vb+SSwKCAQEAvIYn59/eLJKMNT5RGbrrshWBD0LzEOerC2k8vyDAwjB9hnUFIr3k
40 a1ag9xJDAO1dji85FPuT/6nd09J0hV9DnOBL12+wlfQzwcMLBUbwcs7O5B8Myix1
41 mAfkNNVExRHC2FMMDiDVqfl9S964fSbHjiLcIMTQ9ZXDsgPKB3M/aJBXlV1EW2Ma
42 ELE4Y/ZTEjX0xEBb/L4Kh7ivuUoylATcCWeDSUOpHCmYOhHWrbZF5d4l9OCaihiA
43 5LxmMva8Lkh8Kpr0V0jj3tDDi1G49uOFdOHjh9v+oHfZVwRdK4zXjv5hxEBwAeRr
44 h7Z0QN9eLxJIrQuvm3RBurxopAFmHOffdQKCAQEA24awG89Oydyr9DBSu1oMkdWz
45 mx9Kz8ppuDz/nx21CabAGh0J9yahEA8RvUqgWuLwaSMEMCJaSP+Ed9FSFhTHJMbU
46 LiGV5Xm9/GD5NO3L4o0hvCKmdRKmpoUD5t5IIx6cKsiW4/f3sQW+kTVlr/M488kb
47 Oc5VwnMPqNaP1dtbXhe9uJi6InRubMytkY3/xwPX7GjqrfFMOYyUGCkk7wt11d1h
48 4lm4dVfhPtlSzZnjAV1+YGwlaJzThFbCEpbg3WRXHu0yDKVQUPTijAC9XFUE1Og8
49 FuuRrp2B+lOAhVi/8OiDBwUZTZ/pSWysOzY20fWq2rKEqW19ov8hHN/NFDGhSw==
50 -----END RSA PRIVATE KEY-----
0 Bag Attributes
1 friendlyName: server
2 localKeyID: 54 69 6D 65 20 31 36 36 31 31 38 36 35 35 39 37 37 37
3 subject=/C=US/CN=server.log4j2
4 issuer=/C=US/CN=server.log4j2
5 -----BEGIN CERTIFICATE-----
6 MIIC6TCCAdGgAwIBAgIEdDynVTANBgkqhkiG9w0BAQsFADAlMQswCQYDVQQGEwJV
7 UzEWMBQGA1UEAxMNc2VydmVyLmxvZzRqMjAeFw0yMjA4MjIxNjQyMzlaFw00MjA4
8 MTkxNjQyMzlaMCUxCzAJBgNVBAYTAlVTMRYwFAYDVQQDEw1zZXJ2ZXIubG9nNGoy
9 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjqibB1nvyB1ptrxrmR5C
10 nHD3hFbBenEFs5qkgKNvZFkVm+0GJSc6GrfVvvlZ0NTOsdu7Z6YQQcJ4fWEyenma
11 UPsvYfhZx/P/JyMgfKcj+1WU5/fd2L5qZHWcE+yzHgDSRazy5mFJdK9LRyREFm1C
12 6vHMxQf+e/4WVX2AbNPx49cJ1EZkNERmgEYRWCoNU1tgBS1Cq1jcNGomW3IznFX+
13 tWLJoffUytSIS/mjgckwdO8fbdMZPXGnsnwEZh7woekhcxRlwHPKL+aJmanASmUu
14 h0tWJpHe6Kl9af2TLoHPYt+Z59rakAkMYP/hd9R/NiIbkwBb0Wh8KwicVwPpgKXi
15 PwIDAQABoyEwHzAdBgNVHQ4EFgQU0VkuBNTMtKknjRJcZ7IiU1UNOOAwDQYJKoZI
16 hvcNAQELBQADggEBAFCKDMn065xXejfo+lLEXenVIUn4moX/KCibGZwqhcYWXjrZ
17 BxSblxrLn3KSeuY3NBlaw/GTXLypNgZlr1skwhl4Zy4B1Yd97m5rHBmlxyWODL3g
18 ZgjSXWA8zc84wps196YJPP6mrP05bAgoRPEsXIBolFvC/M/NvzWukh5UbGGactJG
19 eMdVQ88HksimnWHrkWXMURqD/KqCwWvXc7Ppy9XZwb4+tEJ2S/6MgCOApSQU+uol
20 qxOrgg8rl74JF9/RXLode/KWdIPuYF+FIkXUt49S6s/diIwX6YkGLjAk8rFoaBmf
21 5sFkbGStttNaZfhkDGLwV9KWE++BbdYy5IpksP0=
22 -----END CERTIFICATE-----
+0
-33
log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/syslog-ng-sample.conf less more
0 source demo_tls_source {
1 tcp(ip(0.0.0.0) port(6515)
2 tls(
3 ca_dir("/etc/ssl/certs")
4 key_file("/home/btibi/ca/log4j2/server.log4j2-key.pem")
5 cert_file("/home/btibi/ca/log4j2/server.log4j2-crt.pem")
6 )
7 );
8 };
9
10 source demo_tls_syslog_source {
11 syslog(ip(0.0.0.0) port(6514)
12 transport("tls")
13 tls(
14 ca_dir("/etc/ssl/certs")
15 key_file("/home/btibi/ca/log4j2/server.log4j2-key.pem")
16 cert_file("/home/btibi/ca/log4j2/server.log4j2-crt.pem")
17 )
18 );
19 };
20
21 destination d_structuredOverTLS { file("/var/log/structuredOverTLS"); };
22 destination d_legacyOverTLS { file("/var/log/legacyOverTLS"); };
23
24 log {
25 source(demo_tls_source);
26 destination(d_legacyOverTLS);
27 };
28
29 log {
30 source(demo_tls_syslog_source);
31 destination(d_structuredOverTLS);
32 };
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-core-its</artifactId>
2525 <packaging>jar</packaging>
124124 <dependency>
125125 <groupId>org.junit.vintage</groupId>
126126 <artifactId>junit-vintage-engine</artifactId>
127 <scope>test</scope>
127128 </dependency>
128129 <dependency>
129130 <groupId>org.junit.jupiter</groupId>
130131 <artifactId>junit-jupiter-engine</artifactId>
132 <scope>test</scope>
131133 </dependency>
132134 <dependency>
133135 <groupId>org.hamcrest</groupId>
119119 * Add an observation to the histogram and increment the counter for the interval it matches.
120120 *
121121 * @param value for the observation to be added.
122 * @return return true if in the range of intervals and successfully added observation; otherwise false.
122 * @return true if in the range of intervals and successfully added observation; otherwise false.
123123 */
124124 public boolean addObservation(final long value)
125125 {
2020 *
2121 * <h3>Note regarding potential for TTSP(Time To Safe Point) issues</h3>
2222 *
23 * If the caller spins in a 'counted' loop, and the implementation does not include a a safepoint poll this may cause a TTSP
23 * If the caller spins in a 'counted' loop, and the implementation does not include a safepoint poll this may cause a TTSP
2424 * (Time To SafePoint) problem. If this is the case for your application you can solve it by preventing the idle method from
2525 * being inlined by using a Hotspot compiler command as a JVM argument e.g:
2626 * <code>-XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle</code>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-core-java9</artifactId>
2525 <packaging>pom</packaging>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <modelVersion>4.0.0</modelVersion>
2525
4949 <dependency>
5050 <groupId>org.junit.vintage</groupId>
5151 <artifactId>junit-vintage-engine</artifactId>
52 <scope>test</scope>
5253 </dependency>
5354 <dependency>
5455 <groupId>org.junit.jupiter</groupId>
5556 <artifactId>junit-jupiter-engine</artifactId>
57 <scope>test</scope>
5658 </dependency>
5759 <dependency>
5860 <groupId>org.mockito</groupId>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-distribution</artifactId>
2525 <packaging>pom</packaging>
170170 </dependency>
171171 <dependency>
172172 <groupId>org.apache.logging.log4j</groupId>
173 <artifactId>log4j-slf4j18-impl</artifactId>
174 <version>${project.version}</version>
175 </dependency>
176 <dependency>
177 <groupId>org.apache.logging.log4j</groupId>
178 <artifactId>log4j-slf4j18-impl</artifactId>
179 <version>${project.version}</version>
180 <classifier>sources</classifier>
181 </dependency>
182 <dependency>
183 <groupId>org.apache.logging.log4j</groupId>
184 <artifactId>log4j-slf4j18-impl</artifactId>
173 <artifactId>log4j-slf4j2-impl</artifactId>
174 <version>${project.version}</version>
175 </dependency>
176 <dependency>
177 <groupId>org.apache.logging.log4j</groupId>
178 <artifactId>log4j-slf4j2-impl</artifactId>
179 <version>${project.version}</version>
180 <classifier>sources</classifier>
181 </dependency>
182 <dependency>
183 <groupId>org.apache.logging.log4j</groupId>
184 <artifactId>log4j-slf4j2-impl</artifactId>
185185 <version>${project.version}</version>
186186 <classifier>javadoc</classifier>
187187 </dependency>
204204 </dependency>
205205 <dependency>
206206 <groupId>org.apache.logging.log4j</groupId>
207 <artifactId>log4j-to-jul</artifactId>
208 <version>${project.version}</version>
209 </dependency>
210 <dependency>
211 <groupId>org.apache.logging.log4j</groupId>
212 <artifactId>log4j-to-jul</artifactId>
213 <version>${project.version}</version>
214 <classifier>sources</classifier>
215 </dependency>
216 <dependency>
217 <groupId>org.apache.logging.log4j</groupId>
218 <artifactId>log4j-to-jul</artifactId>
219 <version>${project.version}</version>
220 <classifier>javadoc</classifier>
221 </dependency>
222 <dependency>
223 <groupId>org.apache.logging.log4j</groupId>
207224 <artifactId>log4j-jmx-gui</artifactId>
208225 <version>${project.version}</version>
209226 </dependency>
255272 </dependency>
256273 <dependency>
257274 <groupId>org.apache.logging.log4j</groupId>
275 <artifactId>log4j-jakarta-web</artifactId>
276 <version>${project.version}</version>
277 </dependency>
278 <dependency>
279 <groupId>org.apache.logging.log4j</groupId>
280 <artifactId>log4j-jakarta-web</artifactId>
281 <version>${project.version}</version>
282 <classifier>sources</classifier>
283 </dependency>
284 <dependency>
285 <groupId>org.apache.logging.log4j</groupId>
286 <artifactId>log4j-jakarta-web</artifactId>
287 <version>${project.version}</version>
288 <classifier>javadoc</classifier>
289 </dependency>
290 <dependency>
291 <groupId>org.apache.logging.log4j</groupId>
292 <artifactId>log4j-jakarta-smtp</artifactId>
293 <version>${project.version}</version>
294 </dependency>
295 <dependency>
296 <groupId>org.apache.logging.log4j</groupId>
297 <artifactId>log4j-jakarta-smtp</artifactId>
298 <version>${project.version}</version>
299 <classifier>sources</classifier>
300 </dependency>
301 <dependency>
302 <groupId>org.apache.logging.log4j</groupId>
303 <artifactId>log4j-jakarta-smtp</artifactId>
304 <version>${project.version}</version>
305 <classifier>javadoc</classifier>
306 </dependency>
307 <dependency>
308 <groupId>org.apache.logging.log4j</groupId>
258309 <artifactId>log4j-couchdb</artifactId>
259310 <version>${project.version}</version>
260311 </dependency>
335386 <dependency>
336387 <groupId>org.apache.logging.log4j</groupId>
337388 <artifactId>log4j-jpa</artifactId>
389 <version>${project.version}</version>
390 <classifier>javadoc</classifier>
391 </dependency>
392 <dependency>
393 <groupId>org.apache.logging.log4j</groupId>
394 <artifactId>log4j-jpl</artifactId>
395 <version>${project.version}</version>
396 </dependency>
397 <dependency>
398 <groupId>org.apache.logging.log4j</groupId>
399 <artifactId>log4j-jpl</artifactId>
400 <version>${project.version}</version>
401 <classifier>sources</classifier>
402 </dependency>
403 <dependency>
404 <groupId>org.apache.logging.log4j</groupId>
405 <artifactId>log4j-jpl</artifactId>
338406 <version>${project.version}</version>
339407 <classifier>javadoc</classifier>
340408 </dependency>
408476 </dependency>
409477 <dependency>
410478 <groupId>org.apache.logging.log4j</groupId>
479 <artifactId>log4j-kubernetes</artifactId>
480 <version>${project.version}</version>
481 </dependency>
482 <dependency>
483 <groupId>org.apache.logging.log4j</groupId>
484 <artifactId>log4j-kubernetes</artifactId>
485 <version>${project.version}</version>
486 <classifier>sources</classifier>
487 </dependency>
488 <dependency>
489 <groupId>org.apache.logging.log4j</groupId>
490 <artifactId>log4j-kubernetes</artifactId>
491 <version>${project.version}</version>
492 <classifier>javadoc</classifier>
493 </dependency>
494 <dependency>
495 <groupId>org.apache.logging.log4j</groupId>
496 <artifactId>log4j-layout-template-json</artifactId>
497 <version>${project.version}</version>
498 </dependency>
499 <dependency>
500 <groupId>org.apache.logging.log4j</groupId>
501 <artifactId>log4j-layout-template-json</artifactId>
502 <version>${project.version}</version>
503 <classifier>sources</classifier>
504 </dependency>
505 <dependency>
506 <groupId>org.apache.logging.log4j</groupId>
507 <artifactId>log4j-layout-template-json</artifactId>
508 <version>${project.version}</version>
509 <classifier>javadoc</classifier>
510 </dependency>
511 <dependency>
512 <groupId>org.apache.logging.log4j</groupId>
411513 <artifactId>log4j-spring-boot</artifactId>
412514 <version>${project.version}</version>
413515 </dependency>
439541 <artifactId>log4j-spring-cloud-config-client</artifactId>
440542 <version>${project.version}</version>
441543 <classifier>javadoc</classifier>
544 </dependency>
545 <dependency>
546 <groupId>org.apache.logging.log4j</groupId>
547 <artifactId>log4j-osgi</artifactId>
548 <version>${project.version}</version>
549 </dependency>
550 <dependency>
551 <groupId>org.apache.logging.log4j</groupId>
552 <artifactId>log4j-osgi</artifactId>
553 <version>${project.version}</version>
554 <classifier>sources</classifier>
442555 </dependency>
443556 </dependencies>
444557 <build>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-docker</artifactId>
2525 <packaging>jar</packaging>
3434 import com.fasterxml.jackson.databind.ObjectMapper;
3535
3636 /**
37 * Lookups up keys for for a Docker container.
37 * Lookups up keys for a Docker container.
3838 */
3939 @Plugin(name = "docker", category = StrLookup.CATEGORY)
4040 public class DockerLookup extends AbstractLookup {
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-flume-ng</artifactId>
2525 <packaging>jar</packaging>
6969 <dependency>
7070 <groupId>org.junit.vintage</groupId>
7171 <artifactId>junit-vintage-engine</artifactId>
72 <scope>test</scope>
7273 </dependency>
7374 <dependency>
7475 <groupId>org.junit.jupiter</groupId>
7576 <artifactId>junit-jupiter-engine</artifactId>
77 <scope>test</scope>
7678 </dependency>
7779 <dependency>
7880 <groupId>org.apache.flume</groupId>
248248 final int delayMillis = Integers.parseInt(maxDelayMillis, DEFAULT_MAX_DELAY);
249249
250250 if (layout == null) {
251 final String enterpriseNumber = Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER;
251 final int enterpriseNumber = Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER;
252252 layout = new Rfc5424Layout.Rfc5424LayoutBuilder()
253253 .setFacility(Facility.LOCAL0)
254 .setEin(enterpriseNumber)
254 .setEin(String.valueOf(enterpriseNumber))
255255 .setIncludeMDC(true)
256256 .setMdcId(Rfc5424Layout.DEFAULT_MDCID)
257257 .setMdcPrefix(mdcPrefix)
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-iostreams</artifactId>
2525 <packaging>jar</packaging>
5555 <dependency>
5656 <groupId>org.junit.vintage</groupId>
5757 <artifactId>junit-vintage-engine</artifactId>
58 <scope>test</scope>
5859 </dependency>
5960 <dependency>
6061 <groupId>org.junit.jupiter</groupId>
6162 <artifactId>junit-jupiter-engine</artifactId>
63 <scope>test</scope>
6264 </dependency>
6365 <dependency>
6466 <groupId>org.hamcrest</groupId>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424
2525 <artifactId>log4j-jakarta-smtp</artifactId>
6868 <dependency>
6969 <groupId>org.junit.vintage</groupId>
7070 <artifactId>junit-vintage-engine</artifactId>
71 <scope>test</scope>
7172 </dependency>
7273 <dependency>
7374 <groupId>org.junit.jupiter</groupId>
7475 <artifactId>junit-jupiter-engine</artifactId>
76 <scope>test</scope>
7577 </dependency>
7678 <dependency>
7779 <groupId>org.hamcrest</groupId>
1919 <parent>
2020 <artifactId>log4j</artifactId>
2121 <groupId>org.apache.logging.log4j</groupId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <modelVersion>4.0.0</modelVersion>
2525
6060 <scope>test</scope>
6161 </dependency>
6262 <dependency>
63 <groupId>org.hamcrest</groupId>
64 <artifactId>hamcrest</artifactId>
63 <groupId>org.hamcrest</groupId>
64 <artifactId>hamcrest</artifactId>
6565 </dependency>
6666 <dependency>
6767 <groupId>org.junit.jupiter</groupId>
6868 <artifactId>junit-jupiter-engine</artifactId>
69 <scope>test</scope>
6970 </dependency>
7071 <dependency>
7172 <groupId>org.mockito</groupId>
7273 <artifactId>mockito-junit-jupiter</artifactId>
73 </dependency>
74 </dependency>
7475 <dependency>
7576 <groupId>org.springframework</groupId>
7677 <artifactId>spring-test</artifactId>
3434 */
3535 public class Log4jServletContextListener implements ServletContextListener {
3636
37 private static final int DEFAULT_STOP_TIMEOUT = 30;
37 private static final int DEFAULT_STOP_TIMEOUT = 30;
3838 private static final TimeUnit DEFAULT_STOP_TIMEOUT_TIMEUNIT = TimeUnit.SECONDS;
3939
40 private static final String KEY_STOP_TIMEOUT = "log4j.stop.timeout";
41 private static final String KEY_STOP_TIMEOUT_TIMEUNIT = "log4j.stop.timeout.timeunit";
40 private static final String KEY_STOP_TIMEOUT = "log4j.stop.timeout";
41 private static final String KEY_STOP_TIMEOUT_TIMEUNIT = "log4j.stop.timeout.timeunit";
4242
43 private static final Logger LOGGER = StatusLogger.getLogger();
43 private static final Logger LOGGER = StatusLogger.getLogger();
4444
4545 private ServletContext servletContext;
4646 private Log4jWebLifeCycle initializer;
5252
5353 if ("true".equalsIgnoreCase(servletContext.getInitParameter(
5454 Log4jWebSupport.IS_LOG4J_AUTO_SHUTDOWN_DISABLED))) {
55 throw new IllegalStateException("Do not use " + getClass().getSimpleName() + " when "
56 + Log4jWebSupport.IS_LOG4J_AUTO_SHUTDOWN_DISABLED + " is true. Please use "
57 + Log4jShutdownOnContextDestroyedListener.class.getSimpleName() + " instead of "
58 + getClass().getSimpleName() + ".");
55 throw new IllegalStateException("Do not use " + getClass().getSimpleName() + " when "
56 + Log4jWebSupport.IS_LOG4J_AUTO_SHUTDOWN_DISABLED + " is true. Please use "
57 + Log4jShutdownOnContextDestroyedListener.class.getSimpleName() + " instead of "
58 + getClass().getSimpleName() + ".");
5959 }
6060
6161 this.initializer = WebLoggerContextUtils.getWebLifeCycle(this.servletContext);
6868 }
6969
7070 @Override
71 public void contextDestroyed(final ServletContextEvent event) {
72 if (this.servletContext == null || this.initializer == null) {
73 LOGGER.warn("Context destroyed before it was initialized.");
74 return;
75 }
76 LOGGER.debug("Log4jServletContextListener ensuring that Log4j shuts down properly.");
71 public void contextDestroyed(final ServletContextEvent event) {
72 if (this.servletContext == null || this.initializer == null) {
73 LOGGER.warn("Context destroyed before it was initialized.");
74 return;
75 }
76 LOGGER.debug("Log4jServletContextListener ensuring that Log4j shuts down properly.");
7777
78 this.initializer.clearLoggerContext(); // the application is finished
79 // shutting down now
80 if (initializer instanceof LifeCycle2) {
81 final String stopTimeoutStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT);
82 final long stopTimeout = Strings.isEmpty(stopTimeoutStr) ? DEFAULT_STOP_TIMEOUT
83 : Long.parseLong(stopTimeoutStr);
84 final String timeoutTimeUnitStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT_TIMEUNIT);
85 final TimeUnit timeoutTimeUnit = Strings.isEmpty(timeoutTimeUnitStr) ? DEFAULT_STOP_TIMEOUT_TIMEUNIT
86 : TimeUnit.valueOf(timeoutTimeUnitStr.toUpperCase(Locale.ROOT));
87 ((LifeCycle2) this.initializer).stop(stopTimeout, timeoutTimeUnit);
88 } else {
89 this.initializer.stop();
90 }
91 }
78 this.initializer.clearLoggerContext(); // the application is finished
79 // shutting down now
80 if (initializer instanceof LifeCycle2) {
81 final String stopTimeoutStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT);
82 final long stopTimeout = Strings.isEmpty(stopTimeoutStr) ? DEFAULT_STOP_TIMEOUT
83 : Long.parseLong(stopTimeoutStr);
84 final String timeoutTimeUnitStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT_TIMEUNIT);
85 final TimeUnit timeoutTimeUnit = Strings.isEmpty(timeoutTimeUnitStr) ? DEFAULT_STOP_TIMEOUT_TIMEUNIT
86 : TimeUnit.valueOf(timeoutTimeUnitStr.toUpperCase(Locale.ROOT));
87 ((LifeCycle2) this.initializer).stop(stopTimeout, timeoutTimeUnit);
88 } else {
89 this.initializer.stop();
90 }
91 }
9292 }
7070 chain.doFilter(request, response);
7171 } finally {
7272 this.initializer.clearLoggerContext();
73 // Execute once per thread
74 request.removeAttribute(ALREADY_FILTERED_ATTRIBUTE);
7375 }
7476 }
7577 }
4343 @Override
4444 public void contextInitialized(final ServletContextEvent event) {
4545 LOGGER.debug(Log4jShutdownOnContextDestroyedListener.class.getSimpleName() +
46 " ensuring that Log4j started up properly.");
46 " ensuring that Log4j started up properly.");
4747 servletContext = event.getServletContext();
4848 if (null == servletContext.getAttribute(Log4jWebSupport.SUPPORT_ATTRIBUTE)) {
49 throw new IllegalStateException(
50 "Context did not contain required Log4jWebLifeCycle in the "
51 + Log4jWebSupport.SUPPORT_ATTRIBUTE + " attribute.");
49 throw new IllegalStateException(
50 "Context did not contain required Log4jWebLifeCycle in the "
51 + Log4jWebSupport.SUPPORT_ATTRIBUTE + " attribute.");
5252 }
5353 this.initializer = WebLoggerContextUtils.getWebLifeCycle(servletContext);
5454 }
6060 return;
6161 }
6262 LOGGER.debug(Log4jShutdownOnContextDestroyedListener.class.getSimpleName() +
63 " ensuring that Log4j shuts down properly.");
63 " ensuring that Log4j shuts down properly.");
6464
6565 this.initializer.clearLoggerContext(); // the application is finished
6666 // shutting down now
3737 @Plugin(name = "Servlet", category = "Core", elementType = "appender", printObject = true)
3838 public class ServletAppender extends AbstractAppender {
3939
40 public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
41 implements org.apache.logging.log4j.core.util.Builder<ServletAppender> {
40 public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
41 implements org.apache.logging.log4j.core.util.Builder<ServletAppender> {
4242
4343 @PluginBuilderAttribute
4444 private boolean logThrowables;
4545
46 @Override
47 public ServletAppender build() {
48 final String name = getName();
49 if (name == null) {
50 LOGGER.error("No name provided for ServletAppender");
51 }
52 final ServletContext servletContext = WebLoggerContextUtils.getServletContext();
53 if (servletContext == null) {
54 LOGGER.error("No servlet context is available");
55 return null;
56 }
57 Layout<? extends Serializable> layout = getOrCreateLayout();
58 if (!(layout instanceof StringLayout)) {
59 LOGGER.error("Layout must be a StringLayout to log to ServletContext");
60 return null;
61 }
62 return new ServletAppender(name, layout, getFilter(), servletContext, isIgnoreExceptions(), logThrowables);
63 }
46 @Override
47 public ServletAppender build() {
48 final String name = getName();
49 if (name == null) {
50 LOGGER.error("No name provided for ServletAppender");
51 }
52 final ServletContext servletContext = WebLoggerContextUtils.getServletContext();
53 if (servletContext == null) {
54 LOGGER.error("No servlet context is available");
55 return null;
56 }
57 Layout<? extends Serializable> layout = getOrCreateLayout();
58 if (!(layout instanceof StringLayout)) {
59 LOGGER.error("Layout must be a StringLayout to log to ServletContext");
60 return null;
61 }
62 return new ServletAppender(name, layout, getFilter(), servletContext, isIgnoreExceptions(), logThrowables);
63 }
6464
6565 /**
6666 * Logs with {@link ServletContext#log(String, Throwable)} if true and with {@link ServletContext#log(String)} if false.
7878 this.logThrowables = logThrowables;
7979 }
8080
81 }
81 }
8282
8383 @PluginBuilderFactory
8484 public static <B extends Builder<B>> B newBuilder() {
119119 public static ServletAppender createAppender(final Layout<? extends Serializable> layout, final Filter filter,
120120 final String name, final boolean ignoreExceptions) {
121121 // @formatter:off
122 return newBuilder().setFilter(filter).setIgnoreExceptions(ignoreExceptions).setLayout(layout).setName(name)
123 .build();
124 // @formatter:on
122 return newBuilder().setFilter(filter).setIgnoreExceptions(ignoreExceptions).setLayout(layout).setName(name)
123 .build();
124 // @formatter:on
125125 }
126126
127127 }
3333
3434 @ExtendWith(MockitoExtension.class)
3535 public class Log4jServletContextListenerTest {
36 /* event and servletContext are marked lenient because they aren't used in the
37 * testDestroyWithNoInit but are only accessed during initialization
38 */
39 @Mock(lenient = true)
40 private ServletContextEvent event;
41 @Mock(lenient = true)
36 /* event and servletContext are marked lenient because they aren't used in the
37 * testDestroyWithNoInit but are only accessed during initialization
38 */
39 @Mock(lenient = true)
40 private ServletContextEvent event;
41 @Mock(lenient = true)
4242 private ServletContext servletContext;
4343 @Mock
4444 private Log4jWebLifeCycle initializer;
7171
7272 @Test
7373 public void testDestroy() {
74 assertThrows(IllegalStateException.class, () -> {
75 this.filter.destroy();
76 });
74 assertThrows(IllegalStateException.class, () -> {
75 this.filter.destroy();
76 });
7777 }
7878
7979 @Test
9292 then(chain).should().doFilter(same(request), same(response));
9393 then(chain).shouldHaveNoMoreInteractions();
9494 then(initializer).should().clearLoggerContext();
95 then(request).should().removeAttribute(Log4jServletFilter.ALREADY_FILTERED_ATTRIBUTE);
9596 }
9697
9798 @Test
4242 public void setUp(boolean mockInitializer) {
4343 this.listener = new Log4jShutdownOnContextDestroyedListener();
4444 given(event.getServletContext()).willReturn(servletContext);
45 if (mockInitializer) {
46 given(servletContext.getAttribute(Log4jWebSupport.SUPPORT_ATTRIBUTE))
47 .willReturn(initializer);
45 if (mockInitializer) {
46 given(servletContext.getAttribute(Log4jWebSupport.SUPPORT_ATTRIBUTE))
47 .willReturn(initializer);
4848 }
4949 }
50
50
5151 @Test
5252 public void testInitAndDestroy() throws Exception {
53 setUp(true);
53 setUp(true);
5454 this.listener.contextInitialized(this.event);
5555
5656 then(initializer).should(never()).start();
6464
6565 @Test
6666 public void testDestroy() throws Exception {
67 setUp(true);
67 setUp(true);
6868 this.listener.contextDestroyed(this.event);
6969
7070 then(initializer).should(never()).clearLoggerContext();
7373
7474 @Test
7575 public void whenNoInitializerInContextTheContextInitializedShouldThrowAnException() {
76 setUp(false);
77
78 assertThrows(IllegalStateException.class, () -> {
79 this.listener.contextInitialized(this.event);
80 });
76 setUp(false);
77
78 assertThrows(IllegalStateException.class, () -> {
79 this.listener.contextInitialized(this.event);
80 });
8181 }
8282 }
4444
4545 @ExtendWith(MockitoExtension.class)
4646 public class Log4jWebInitializerImplTest {
47 /* Marking servletContext lenient because otherwise testCompositeLocationParameterWithEmptyUriListSetsDefaultConfiguration fails
48 * when null is passed in as the initial param because Mockito deciced null isn't a String rather than the absence of a string.
49 */
50 @Mock(lenient = true)
51 private ServletContext servletContext;
47 /* Marking servletContext lenient because otherwise testCompositeLocationParameterWithEmptyUriListSetsDefaultConfiguration fails
48 * when null is passed in as the initial param because Mockito deciced null isn't a String rather than the absence of a string.
49 */
50 @Mock(lenient = true)
51 private ServletContext servletContext;
5252 @Captor
5353 private ArgumentCaptor<Log4jWebLifeCycle> initializerCaptor;
5454 @Captor
7272
7373 @Test
7474 public void testDeinitializeBeforeInitialize() {
75 assertThrows(IllegalStateException.class, () -> {
76 this.initializerImpl.stop();
77 });
75 assertThrows(IllegalStateException.class, () -> {
76 this.initializerImpl.stop();
77 });
7878 }
7979
8080 @Test
213213
214214 then(servletContext).should().removeAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE));
215215
216 assertThrows(IllegalStateException.class, () -> {
217 this.initializerImpl.start();
218 });
216 assertThrows(IllegalStateException.class, () -> {
217 this.initializerImpl.start();
218 });
219219 }
220220
221221 @Test
247247 given(servletContext.getResourcePaths("/WEB-INF/")).willReturn(null);
248248 assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null.");
249249
250 assertThrows(IllegalStateException.class, () -> {
251 this.initializerImpl.start();
252 });
250 assertThrows(IllegalStateException.class, () -> {
251 this.initializerImpl.start();
252 });
253253 }
254254
255255 @Test
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-jcl</artifactId>
2525 <packaging>jar</packaging>
3636 <dependency>
3737 <groupId>org.junit.vintage</groupId>
3838 <artifactId>junit-vintage-engine</artifactId>
39 <scope>test</scope>
3940 </dependency>
4041 <dependency>
4142 <groupId>org.junit.jupiter</groupId>
4243 <artifactId>junit-jupiter-engine</artifactId>
44 <scope>test</scope>
4345 </dependency>
4446 <dependency>
4547 <groupId>org.hamcrest</groupId>
8991 <configuration>
9092 <instructions>
9193 <Export-Package>org.apache.logging.log4j.jcl</Export-Package>
94 <Require-Capability>osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional</Require-Capability>
95 <Provide-Capability>osgi.serviceloader;osgi.serviceloader=org.apache.commons.logging.LogFactory</Provide-Capability>
9296 </instructions>
9397 </configuration>
9498 </plugin>
1010 <parent>
1111 <groupId>org.apache.logging.log4j</groupId>
1212 <artifactId>log4j</artifactId>
13 <version>2.18.0</version>
13 <version>2.19.0</version>
1414 </parent>
1515 <modelVersion>4.0.0</modelVersion>
1616
4040 <dependency>
4141 <groupId>org.junit.vintage</groupId>
4242 <artifactId>junit-vintage-engine</artifactId>
43 <scope>test</scope>
4344 </dependency>
4445 <dependency>
4546 <groupId>org.junit.jupiter</groupId>
4647 <artifactId>junit-jupiter-engine</artifactId>
48 <scope>test</scope>
4749 </dependency>
4850 <dependency>
4951 <groupId>org.apache.logging.log4j</groupId>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-jmx-gui</artifactId>
2525 <packaging>jar</packaging>
1010 <parent>
1111 <groupId>org.apache.logging.log4j</groupId>
1212 <artifactId>log4j</artifactId>
13 <version>2.18.0</version>
13 <version>2.19.0</version>
1414 </parent>
1515 <modelVersion>4.0.0</modelVersion>
1616
4949 <dependency>
5050 <groupId>org.junit.vintage</groupId>
5151 <artifactId>junit-vintage-engine</artifactId>
52 <scope>test</scope>
5253 </dependency>
5354 <dependency>
5455 <groupId>org.junit.jupiter</groupId>
5556 <artifactId>junit-jupiter-engine</artifactId>
57 <scope>test</scope>
5658 </dependency>
5759 <dependency>
5860 <groupId>org.apache.logging.log4j</groupId>
1919 <parent>
2020 <artifactId>log4j</artifactId>
2121 <groupId>org.apache.logging.log4j</groupId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <modelVersion>4.0.0</modelVersion>
2525
5757 <dependency>
5858 <groupId>org.junit.vintage</groupId>
5959 <artifactId>junit-vintage-engine</artifactId>
60 <scope>test</scope>
6061 </dependency>
6162 <dependency>
6263 <groupId>org.junit.jupiter</groupId>
6364 <artifactId>junit-jupiter-engine</artifactId>
65 <scope>test</scope>
6466 </dependency>
6567 </dependencies>
6668
1919 <parent>
2020 <artifactId>log4j</artifactId>
2121 <groupId>org.apache.logging.log4j</groupId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <modelVersion>4.0.0</modelVersion>
2525
6262 <dependency>
6363 <groupId>junit</groupId>
6464 <artifactId>junit</artifactId>
65 <scope>test</scope>
6566 </dependency>
6667 <!-- Required for AsyncLogger testing -->
6768 <dependency>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-kubernetes</artifactId>
2525 <packaging>jar</packaging>
5151 <dependency>
5252 <groupId>org.junit.vintage</groupId>
5353 <artifactId>junit-vintage-engine</artifactId>
54 <scope>test</scope>
5455 </dependency>
5556 <dependency>
5657 <groupId>org.junit.jupiter</groupId>
5758 <artifactId>junit-jupiter-engine</artifactId>
59 <scope>test</scope>
5860 </dependency>
5961 </dependencies>
6062 <build>
2121 <parent>
2222 <groupId>org.apache.logging.log4j</groupId>
2323 <artifactId>log4j</artifactId>
24 <version>2.18.0</version>
24 <version>2.19.0</version>
2525 </parent>
2626
2727 <artifactId>log4j-layout-template-json</artifactId>
7070 * first.
7171 * <p>
7272 * If a stringified stack trace truncation takes place, it will be indicated
73 * with <tt>suffix</tt>, which by default is set to the configured
73 * with a <tt>suffix</tt>, which by default is set to the configured
7474 * <tt>truncatedStringSuffix</tt> in the layout, unless explicitly provided.
75 * Every truncation suffix is prefixed with a newline.
76 * <p>
77 * Stringified stack trace truncation operates in <tt>Caused by:</tt> and
78 * <tt>Suppressed:</tt> label blocks. That is, matchers are executed against
79 * each label in isolation.
7580 * <p>
7681 * <tt>elementTemplate</tt> is an object describing the template to be used
7782 * while resolving the {@link StackTraceElement} array. If <tt>stringified</tt>
137142 * "stackTrace": {
138143 * "stringified": {
139144 * "truncation": {
140 * "suffix": ">",
145 * "suffix": "... [truncated]",
141146 * "pointMatcherStrings": ["at javax.servlet.http.HttpServlet.service"]
142147 * }
143148 * }
1515 */
1616 package org.apache.logging.log4j.layout.template.json.resolver;
1717
18 import org.apache.logging.log4j.layout.template.json.util.TruncatingBufferedPrintWriter;
19 import org.apache.logging.log4j.layout.template.json.util.JsonWriter;
20 import org.apache.logging.log4j.layout.template.json.util.Recycler;
18 import org.apache.logging.log4j.layout.template.json.util.*;
2119
2220 import java.util.List;
2321 import java.util.function.Supplier;
3028 */
3129 final class StackTraceStringResolver implements StackTraceResolver {
3230
33 private final Recycler<TruncatingBufferedPrintWriter> writerRecycler;
31 private final Recycler<TruncatingBufferedPrintWriter> srcWriterRecycler;
32
33 private final Recycler<TruncatingBufferedPrintWriter> dstWriterRecycler;
34
35 private final Recycler<CharSequencePointer> sequencePointerRecycler;
3436
3537 private final boolean truncationEnabled;
3638
4850 final Supplier<TruncatingBufferedPrintWriter> writerSupplier =
4951 () -> TruncatingBufferedPrintWriter.ofCapacity(
5052 context.getMaxStringByteCount());
51 this.writerRecycler = context
52 .getRecyclerFactory()
53 .create(writerSupplier, TruncatingBufferedPrintWriter::close);
53 final RecyclerFactory recyclerFactory = context.getRecyclerFactory();
54 this.srcWriterRecycler =
55 recyclerFactory.create(
56 writerSupplier, TruncatingBufferedPrintWriter::close);
57 this.dstWriterRecycler =
58 recyclerFactory.create(
59 writerSupplier, TruncatingBufferedPrintWriter::close);
60 this.sequencePointerRecycler =
61 recyclerFactory.create(CharSequencePointer::new);
5462 this.truncationEnabled =
5563 !truncationPointMatcherStrings.isEmpty() ||
5664 !truncationPointMatcherRegexes.isEmpty();
6573 return regexes
6674 .stream()
6775 .map(regex -> Pattern.compile(
68 "^.*(" + regex + ")(.*)$",
69 Pattern.MULTILINE | Pattern.DOTALL))
76 ".*?" + // Make `.*` lazy with `?` suffix, since we want to find the _first_ match of `regex`.
77 regex + // Match the user input.
78 "(.*)", // Group that is to be truncated.
79 Pattern.DOTALL))
7080 .collect(Collectors.toList());
7181 }
7282
7484 public void resolve(
7585 final Throwable throwable,
7686 final JsonWriter jsonWriter) {
77 final TruncatingBufferedPrintWriter writer = writerRecycler.acquire();
87 final TruncatingBufferedPrintWriter srcWriter = srcWriterRecycler.acquire();
7888 try {
79 throwable.printStackTrace(writer);
80 truncate(writer);
81 jsonWriter.writeString(writer.buffer(), 0, writer.position());
89 throwable.printStackTrace(srcWriter);
90 final TruncatingBufferedPrintWriter dstWriter = truncate(srcWriter);
91 jsonWriter.writeString(dstWriter);
8292 } finally {
83 writerRecycler.release(writer);
84 }
85 }
86
87 private void truncate(final TruncatingBufferedPrintWriter writer) {
93 srcWriterRecycler.release(srcWriter);
94 }
95 }
96
97 private TruncatingBufferedPrintWriter truncate(
98 final TruncatingBufferedPrintWriter srcWriter) {
8899
89100 // Short-circuit if truncation is not enabled.
90101 if (!truncationEnabled) {
91 return;
92 }
102 return srcWriter;
103 }
104
105 // Allocate temporary buffers and truncate the input.
106 final TruncatingBufferedPrintWriter dstWriter =
107 dstWriterRecycler.acquire();
108 try {
109 final CharSequencePointer sequencePointer =
110 sequencePointerRecycler.acquire();
111 try {
112 truncate(srcWriter, dstWriter, sequencePointer);
113 } finally {
114 sequencePointerRecycler.release(sequencePointer);
115 }
116 } finally {
117 dstWriterRecycler.release(dstWriter);
118 }
119 return dstWriter;
120
121 }
122
123 private void truncate(
124 final TruncatingBufferedPrintWriter srcWriter,
125 final TruncatingBufferedPrintWriter dstWriter,
126 final CharSequencePointer sequencePointer) {
127 int startIndex = 0;
128 for (;;) {
129
130 // Find the next label start, if present.
131 final int labeledLineStartIndex =
132 findLabeledLineStartIndex(
133 srcWriter, startIndex, srcWriter.length());
134 final int endIndex = labeledLineStartIndex >= 0
135 ? labeledLineStartIndex
136 : srcWriter.length();
137
138 // Copy up to the truncation point, if it matches.
139 final int truncationPointIndex = findTruncationPointIndex(
140 srcWriter, startIndex, endIndex, sequencePointer);
141 if (truncationPointIndex > 0) {
142 dstWriter.append(srcWriter, startIndex, truncationPointIndex);
143 dstWriter.append(System.lineSeparator());
144 dstWriter.append(truncationSuffix);
145 }
146
147 // Otherwise, copy the entire labeled block.
148 else {
149 dstWriter.append(srcWriter, startIndex, endIndex);
150 }
151
152 // Copy the label to avoid stepping over it again.
153 if (labeledLineStartIndex > 0) {
154 dstWriter.append(System.lineSeparator());
155 startIndex = labeledLineStartIndex;
156 for (;;) {
157 final char c = srcWriter.charAt(startIndex++);
158 dstWriter.append(c);
159 if (c == ':') {
160 break;
161 }
162 }
163 }
164
165 // Otherwise, the source is exhausted, stop.
166 else {
167 break;
168 }
169
170 }
171 }
172
173 private int findTruncationPointIndex(
174 final TruncatingBufferedPrintWriter writer,
175 final int startIndex,
176 final int endIndex,
177 final CharSequencePointer sequencePointer) {
93178
94179 // Check for string matches.
95180 // noinspection ForLoopReplaceableByForEach (avoid iterator allocation)
96181 for (int i = 0; i < truncationPointMatcherStrings.size(); i++) {
97182 final String matcher = truncationPointMatcherStrings.get(i);
98 final int matchIndex = writer.indexOf(matcher);
183 final int matchIndex = findMatchingIndex(
184 matcher, writer, startIndex, endIndex);
99185 if (matchIndex > 0) {
100 final int truncationPointIndex = matchIndex + matcher.length();
101 truncate(writer, truncationPointIndex);
102 return;
186 // No need for `Math.addExact()`, since we have a match:
187 return matchIndex + matcher.length();
103188 }
104189 }
105190
106191 // Check for regex matches.
192 CharSequence sequence;
193 if (startIndex == 0 && endIndex == writer.length()) {
194 sequence = writer;
195 } else {
196 sequencePointer.reset(writer, startIndex, writer.length());
197 sequence = sequencePointer;
198 }
107199 // noinspection ForLoopReplaceableByForEach (avoid iterator allocation)
108200 for (int i = 0; i < groupedTruncationPointMatcherRegexes.size(); i++) {
109201 final Pattern pattern = groupedTruncationPointMatcherRegexes.get(i);
110 final Matcher matcher = pattern.matcher(writer);
202 final Matcher matcher = pattern.matcher(sequence);
111203 final boolean matched = matcher.matches();
112204 if (matched) {
113205 final int lastGroup = matcher.groupCount();
114 final int truncationPointIndex = matcher.start(lastGroup);
115 truncate(writer, truncationPointIndex);
116 return;
117 }
118 }
119
120 }
121
122 private void truncate(
123 final TruncatingBufferedPrintWriter writer,
124 final int index) {
125 writer.position(index);
126 writer.print(truncationSuffix);
206 return matcher.start(lastGroup);
207 }
208 }
209
210 // No matches.
211 return -1;
212
213 }
214
215 private static int findLabeledLineStartIndex(
216 final CharSequence buffer,
217 final int startIndex,
218 final int endIndex) {
219 // Note that the index arithmetic in this method is not guarded.
220 // That is, there are no `Math.addExact()` or `Math.subtractExact()` usages.
221 // Since we know a priori that we are already operating within buffer limits.
222 for (int bufferIndex = startIndex; bufferIndex < endIndex;) {
223
224 // Find the next line start, if exists.
225 final int lineStartIndex = findLineStartIndex(buffer, bufferIndex, endIndex);
226 if (lineStartIndex < 0) {
227 break;
228 }
229 bufferIndex = lineStartIndex;
230
231 // Skip tabs.
232 while (bufferIndex < endIndex && '\t' == buffer.charAt(bufferIndex)) {
233 bufferIndex++;
234 }
235
236 // Search for the `Caused by: ` occurrence.
237 if (bufferIndex < (endIndex - 11) &&
238 buffer.charAt(bufferIndex) == 'C' &&
239 buffer.charAt(bufferIndex + 1) == 'a' &&
240 buffer.charAt(bufferIndex + 2) == 'u' &&
241 buffer.charAt(bufferIndex + 3) == 's' &&
242 buffer.charAt(bufferIndex + 4) == 'e' &&
243 buffer.charAt(bufferIndex + 5) == 'd' &&
244 buffer.charAt(bufferIndex + 6) == ' ' &&
245 buffer.charAt(bufferIndex + 7) == 'b' &&
246 buffer.charAt(bufferIndex + 8) == 'y' &&
247 buffer.charAt(bufferIndex + 9) == ':' &&
248 buffer.charAt(bufferIndex + 10) == ' ') {
249 return lineStartIndex;
250 }
251
252 // Search for the `Suppressed: ` occurrence.
253 else if (bufferIndex < (endIndex - 12) &&
254 buffer.charAt(bufferIndex) == 'S' &&
255 buffer.charAt(bufferIndex + 1) == 'u' &&
256 buffer.charAt(bufferIndex + 2) == 'p' &&
257 buffer.charAt(bufferIndex + 3) == 'p' &&
258 buffer.charAt(bufferIndex + 4) == 'r' &&
259 buffer.charAt(bufferIndex + 5) == 'e' &&
260 buffer.charAt(bufferIndex + 6) == 's' &&
261 buffer.charAt(bufferIndex + 7) == 's' &&
262 buffer.charAt(bufferIndex + 8) == 'e' &&
263 buffer.charAt(bufferIndex + 9) == 'd' &&
264 buffer.charAt(bufferIndex + 10) == ':' &&
265 buffer.charAt(bufferIndex + 11) == ' ') {
266 return lineStartIndex;
267 }
268
269 }
270 return -1;
271 }
272
273 private static int findLineStartIndex(
274 final CharSequence buffer,
275 final int startIndex,
276 final int endIndex) {
277 char prevChar = '-';
278 for (int i = startIndex; i <= endIndex; i++) {
279 if (prevChar == '\n') {
280 return i;
281 }
282 prevChar = buffer.charAt(i);
283 }
284 return -1;
285 }
286
287 private static int findMatchingIndex(
288 final CharSequence matcher,
289 final CharSequence buffer,
290 final int bufferStartIndex,
291 final int bufferEndIndex) {
292
293 // Note that the index arithmetic in this method is not guarded.
294 // That is, there are no `Math.addExact()` or `Math.subtractExact()` usages.
295 // Since we know a priori that we are already operating within buffer limits.
296
297 // While searching for an input of length `n`, no need to traverse the last `n-1` characters.
298 final int effectiveBufferEndIndex = bufferEndIndex - matcher.length() + 1;
299
300 // Perform the search.
301 for (int bufferIndex = bufferStartIndex; bufferIndex <= effectiveBufferEndIndex; bufferIndex++) {
302 boolean found = true;
303 for (int matcherIndex = 0; matcherIndex < matcher.length(); matcherIndex++) {
304 final char matcherChar = matcher.charAt(matcherIndex);
305 final char bufferChar = buffer.charAt(bufferIndex + matcherIndex);
306 if (matcherChar != bufferChar) {
307 found = false;
308 break;
309 }
310 }
311 if (found) {
312 return bufferIndex;
313 }
314 }
315 return -1;
316
127317 }
128318
129319 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j.layout.template.json.util;
17
18 import java.util.Objects;
19 import java.util.stream.IntStream;
20
21 /**
22 * A {@link CharSequence} wrapper that allows mutation of the pointed delegate sequence.
23 */
24 public final class CharSequencePointer implements CharSequence {
25
26 private CharSequence delegate;
27
28 private int startIndex;
29
30 private int length = -1;
31
32 public void reset(
33 final CharSequence delegate,
34 final int startIndex,
35 final int endIndex) {
36
37 // Check & set the delegate.
38 Objects.requireNonNull(delegate, "delegate");
39 this.delegate = delegate;
40
41 // Check & set the start.
42 if (startIndex < 0) {
43 throw new IndexOutOfBoundsException("invalid start: " + startIndex);
44 }
45
46 // Check & set length.
47 if (endIndex > delegate.length()) {
48 throw new IndexOutOfBoundsException("invalid end: " + endIndex);
49 }
50 this.length = Math.subtractExact(endIndex, startIndex);
51 if (length < 0) {
52 throw new IndexOutOfBoundsException("invalid length: " + length);
53 }
54
55 // Set fields.
56 this.delegate = delegate;
57 this.startIndex = startIndex;
58
59 }
60
61 @Override
62 public int length() {
63 requireReset();
64 return length;
65 }
66
67 @Override
68 public char charAt(final int startIndex) {
69 requireReset();
70 final int delegateStartIndex = Math.addExact(this.startIndex, startIndex);
71 return delegate.charAt(delegateStartIndex);
72 }
73
74 @Override
75 public CharSequence subSequence(final int startIndex, final int endIndex) {
76 throw new UnsupportedOperationException(
77 "operation requires allocation, contradicting with the purpose of the class");
78 }
79
80 @Override
81 public IntStream chars() {
82 throw new UnsupportedOperationException(
83 "operation requires allocation, contradicting with the purpose of the class");
84 }
85
86 @Override
87 public IntStream codePoints() {
88 throw new UnsupportedOperationException(
89 "operation requires allocation, contradicting with the purpose of the class");
90 }
91
92 @Override
93 public String toString() {
94 requireReset();
95 final int endIndex = Math.addExact(startIndex, length);
96 return delegate.toString().substring(startIndex, endIndex);
97 }
98
99 private void requireReset() {
100 if (length < 0) {
101 throw new IllegalStateException("pointer must be reset first");
102 }
103 }
104
105 }
5858 return writer.truncated();
5959 }
6060
61 public int indexOf(final CharSequence seq) {
62 Objects.requireNonNull(seq, "seq");
63 return writer.indexOf(seq);
64 }
65
6661 @Override
6762 public int length() {
6863 return writer.length();
7166 @Override
7267 public char charAt(final int index) {
7368 return writer.charAt(index);
69 }
70
71 @Override
72 public PrintWriter append(final CharSequence seq) {
73 writer.append(seq);
74 return this;
75 }
76
77 @Override
78 public PrintWriter append(final CharSequence seq, final int startIndex, final int endIndex) {
79 writer.append(seq, startIndex, endIndex);
80 return this;
7481 }
7582
7683 @Override
1717
1818 import java.io.Writer;
1919 import java.util.Objects;
20 import java.util.stream.IntStream;
2021
2122 final class TruncatingBufferedWriter extends Writer implements CharSequence {
2223
202203
203204 }
204205
205 int indexOf(final CharSequence seq) {
206
207 // Short-circuit if there is nothing to match.
208 final int seqLength = seq.length();
209 if (seqLength == 0) {
210 return 0;
211 }
212
213 // Short-circuit if the given input is longer than the buffer.
214 if (seqLength > position) {
215 return -1;
216 }
217
218 // Perform the search.
219 for (int bufferIndex = 0; bufferIndex < position; bufferIndex++) {
220 boolean found = true;
221 for (int seqIndex = 0; seqIndex < seqLength; seqIndex++) {
222 final char s = seq.charAt(seqIndex);
223 final char b = buffer[bufferIndex + seqIndex];
224 if (s != b) {
225 found = false;
226 break;
227 }
228 }
229 if (found) {
230 return bufferIndex;
231 }
232 }
233 return -1;
234
235 }
236
237206 @Override
238207 public int length() {
239 return position + 1;
208 return position;
240209 }
241210
242211 @Override
246215
247216 @Override
248217 public String subSequence(final int startIndex, final int endIndex) {
249 return new String(buffer, startIndex, endIndex - startIndex);
218 throw new UnsupportedOperationException(
219 "operation requires allocation, contradicting with the purpose of the class");
220 }
221
222 @Override
223 public IntStream chars() {
224 throw new UnsupportedOperationException(
225 "operation requires allocation, contradicting with the purpose of the class");
226 }
227
228 @Override
229 public IntStream codePoints() {
230 throw new UnsupportedOperationException(
231 "operation requires allocation, contradicting with the purpose of the class");
250232 }
251233
252234 @Override
3333 import org.apache.logging.log4j.core.net.Severity;
3434 import org.apache.logging.log4j.core.time.MutableInstant;
3535 import org.apache.logging.log4j.layout.template.json.JsonTemplateLayout.EventTemplateAdditionalField;
36 import org.apache.logging.log4j.layout.template.json.resolver.EventResolver;
37 import org.apache.logging.log4j.layout.template.json.resolver.EventResolverContext;
38 import org.apache.logging.log4j.layout.template.json.resolver.EventResolverFactory;
39 import org.apache.logging.log4j.layout.template.json.resolver.TemplateResolver;
40 import org.apache.logging.log4j.layout.template.json.resolver.TemplateResolverConfig;
41 import org.apache.logging.log4j.layout.template.json.resolver.TemplateResolverFactory;
36 import org.apache.logging.log4j.layout.template.json.resolver.*;
4237 import org.apache.logging.log4j.layout.template.json.util.JsonWriter;
43 import org.apache.logging.log4j.message.Message;
44 import org.apache.logging.log4j.message.MessageFactory;
45 import org.apache.logging.log4j.message.ObjectMessage;
46 import org.apache.logging.log4j.message.ParameterizedMessageFactory;
47 import org.apache.logging.log4j.message.ReusableMessageFactory;
48 import org.apache.logging.log4j.message.SimpleMessage;
49 import org.apache.logging.log4j.message.StringMapMessage;
38 import org.apache.logging.log4j.message.*;
5039 import org.apache.logging.log4j.test.AvailablePortFinder;
5140 import org.apache.logging.log4j.util.Strings;
52 import org.assertj.core.api.Assertions;
5341 import org.junit.jupiter.api.Test;
5442
55 import java.io.ByteArrayOutputStream;
56 import java.io.EOFException;
57 import java.io.IOException;
58 import java.io.InputStream;
59 import java.io.PrintStream;
60 import java.io.UnsupportedEncodingException;
43 import java.io.*;
6144 import java.math.BigDecimal;
6245 import java.net.ServerSocket;
6346 import java.net.Socket;
6649 import java.time.Instant;
6750 import java.time.temporal.ChronoField;
6851 import java.time.temporal.TemporalAccessor;
69 import java.util.ArrayList;
70 import java.util.Arrays;
71 import java.util.Collections;
72 import java.util.List;
73 import java.util.Map;
52 import java.util.*;
7453 import java.util.concurrent.ArrayBlockingQueue;
7554 import java.util.concurrent.BlockingQueue;
7655 import java.util.concurrent.TimeUnit;
8059
8160 import static org.apache.logging.log4j.layout.template.json.TestHelpers.*;
8261 import static org.assertj.core.api.Assertions.assertThat;
62 import static org.assertj.core.api.Assertions.assertThatThrownBy;
8363
8464 @SuppressWarnings("DoubleBraceInitialization")
8565 class JsonTemplateLayoutTest {
769749
770750 }
771751
772 private static final class NonAsciiUtf8MethodNameContainingException extends RuntimeException {
773
774 public static final long serialVersionUID = 0;
775
776 private static final String NON_ASCII_UTF8_TEXT = "அஆஇฬ๘";
777
778 private static final NonAsciiUtf8MethodNameContainingException INSTANCE =
779 createInstance();
780
781 private static NonAsciiUtf8MethodNameContainingException createInstance() {
782 try {
783 throwException_அஆஇฬ๘();
784 throw new IllegalStateException("should not have reached here");
785 } catch (final NonAsciiUtf8MethodNameContainingException exception) {
786 return exception;
787 }
788 }
789
790 @SuppressWarnings("NonAsciiCharacters")
791 private static void throwException_அஆஇฬ๘() {
792 throw new NonAsciiUtf8MethodNameContainingException(
793 "exception with non-ASCII UTF-8 method name");
794 }
795
796 private NonAsciiUtf8MethodNameContainingException(final String message) {
797 super(message);
798 }
799
800 }
801
802 @Test
803 void test_exception_with_nonAscii_utf8_method_name() {
752 @Test
753 void test_event_template_additional_fields() {
804754
805755 // Create the log event.
806756 final SimpleMessage message = new SimpleMessage("Hello, World!");
807 final RuntimeException exception = NonAsciiUtf8MethodNameContainingException.INSTANCE;
808 final LogEvent logEvent = Log4jLogEvent
809 .newBuilder()
810 .setLoggerName(LOGGER_NAME)
811 .setLevel(Level.ERROR)
812 .setMessage(message)
813 .setThrown(exception)
814 .build();
815
816 // Create the event template.
817 final String eventTemplate = writeJson(asMap(
818 "ex_stacktrace", asMap(
819 "$resolver", "exception",
820 "field", "stackTrace",
821 "stringified", true)));
822
823 // Create the layout.
824 final JsonTemplateLayout layout = JsonTemplateLayout
825 .newBuilder()
826 .setConfiguration(CONFIGURATION)
827 .setStackTraceEnabled(true)
828 .setEventTemplate(eventTemplate)
829 .build();
830
831 // Check the serialized event.
832 usingSerializedLogEventAccessor(layout, logEvent, accessor ->
833 assertThat(accessor.getString("ex_stacktrace"))
834 .contains(NonAsciiUtf8MethodNameContainingException.NON_ASCII_UTF8_TEXT));
835
836 }
837
838 @Test
839 void test_event_template_additional_fields() {
840
841 // Create the log event.
842 final SimpleMessage message = new SimpleMessage("Hello, World!");
843 final RuntimeException exception = NonAsciiUtf8MethodNameContainingException.INSTANCE;
844757 final Level level = Level.ERROR;
845758 final LogEvent logEvent = Log4jLogEvent
846759 .newBuilder()
847760 .setLoggerName(LOGGER_NAME)
848761 .setLevel(level)
849762 .setMessage(message)
850 .setThrown(exception)
851763 .build();
852764
853765 // Create the event template.
970882 // Verify the test case.
971883 usingSerializedLogEventAccessor(layout, logEvent, accessor ->
972884 testCase.forEach((key, expectedValue) ->
973 Assertions
974 .assertThat(accessor.getObject(key))
885 assertThat(accessor.getObject(key))
975886 .describedAs("key=%s", key)
976887 .isEqualTo(expectedValue)));
977888
11391050 }
11401051
11411052 @Test
1142 void test_stringified_exception_resolver_with_maxStringLength() {
1143
1144 // Create the event template.
1145 final String eventTemplate = writeJson(asMap(
1146 "stackTrace", asMap(
1147 "$resolver", "exception",
1148 "field", "stackTrace",
1149 "stringified", true)));
1150
1151 // Create the layout.
1152 final int maxStringLength = eventTemplate.length();
1153 final JsonTemplateLayout layout = JsonTemplateLayout
1154 .newBuilder()
1155 .setConfiguration(CONFIGURATION)
1156 .setEventTemplate(eventTemplate)
1157 .setMaxStringLength(maxStringLength)
1158 .setStackTraceEnabled(true)
1159 .build();
1160
1161 // Create the log event.
1162 final SimpleMessage message = new SimpleMessage("foo");
1163 final LogEvent logEvent = Log4jLogEvent
1164 .newBuilder()
1165 .setLoggerName(LOGGER_NAME)
1166 .setMessage(message)
1167 .setThrown(NonAsciiUtf8MethodNameContainingException.INSTANCE)
1168 .build();
1169
1170 // Check the serialized event.
1171 usingSerializedLogEventAccessor(layout, logEvent, accessor -> {
1172 final int expectedLength = maxStringLength +
1173 JsonTemplateLayoutDefaults.getTruncatedStringSuffix().length();
1174 assertThat(accessor.getString("stackTrace").length()).isEqualTo(expectedLength);
1175 });
1176
1177 }
1178
1179 @Test
1180 void test_stack_trace_truncation() {
1181
1182 // Create the exception to be logged.
1183 final Exception childError =
1184 new Exception("unique child exception message");
1185 final Exception parentError =
1186 new Exception("unique parent exception message", childError);
1187
1188 // Create the event template.
1189 final String truncationSuffix = "~";
1190 final String eventTemplate = writeJson(asMap(
1191 // Raw exception.
1192 "ex", asMap(
1193 "$resolver", "exception",
1194 "field", "stackTrace",
1195 "stackTrace", asMap(
1196 "stringified", true)),
1197 // Exception matcher using strings.
1198 "stringMatchedEx", asMap(
1199 "$resolver", "exception",
1200 "field", "stackTrace",
1201 "stackTrace", asMap(
1202 "stringified", asMap(
1203 "truncation", asMap(
1204 "suffix", truncationSuffix,
1205 "pointMatcherStrings", Arrays.asList(
1206 "this string shouldn't match with anything",
1207 parentError.getMessage()))))),
1208 // Exception matcher using regexes.
1209 "regexMatchedEx", asMap(
1210 "$resolver", "exception",
1211 "field", "stackTrace",
1212 "stackTrace", asMap(
1213 "stringified", asMap(
1214 "truncation", asMap(
1215 "suffix", truncationSuffix,
1216 "pointMatcherRegexes", Arrays.asList(
1217 "this string shouldn't match with anything",
1218 parentError
1219 .getMessage()
1220 .replace("unique", "[xu]n.que")))))),
1221 // Raw exception root cause.
1222 "rootEx", asMap(
1223 "$resolver", "exceptionRootCause",
1224 "field", "stackTrace",
1225 "stackTrace", asMap(
1226 "stringified", true)),
1227 // Exception root cause matcher using strings.
1228 "stringMatchedRootEx", asMap(
1229 "$resolver", "exceptionRootCause",
1230 "field", "stackTrace",
1231 "stackTrace", asMap(
1232 "stringified", asMap(
1233 "truncation", asMap(
1234 "suffix", truncationSuffix,
1235 "pointMatcherStrings", Arrays.asList(
1236 "this string shouldn't match with anything",
1237 childError.getMessage()))))),
1238 // Exception root cause matcher using regexes.
1239 "regexMatchedRootEx", asMap(
1240 "$resolver", "exceptionRootCause",
1241 "field", "stackTrace",
1242 "stackTrace", asMap(
1243 "stringified", asMap(
1244 "truncation", asMap(
1245 "suffix", truncationSuffix,
1246 "pointMatcherRegexes", Arrays.asList(
1247 "this string shouldn't match with anything",
1248 childError
1249 .getMessage()
1250 .replace("unique", "[xu]n.que"))))))));
1251
1252 // Create the layout.
1253 final JsonTemplateLayout layout = JsonTemplateLayout
1254 .newBuilder()
1255 .setConfiguration(CONFIGURATION)
1256 .setEventTemplate(eventTemplate)
1257 .setStackTraceEnabled(true)
1258 .build();
1259
1260 // Create the log event.
1261 final LogEvent logEvent = Log4jLogEvent
1262 .newBuilder()
1263 .setLoggerName(LOGGER_NAME)
1264 .setThrown(parentError)
1265 .build();
1266
1267 // Check the serialized event.
1268 final String expectedMatchedExEnd =
1269 parentError.getMessage() + truncationSuffix;
1270 final String expectedMatchedRootExEnd =
1271 childError.getMessage() + truncationSuffix;
1272 usingSerializedLogEventAccessor(layout, logEvent, accessor -> {
1273
1274 // Check the serialized exception.
1275 assertThat(accessor.getString("ex"))
1276 .doesNotEndWith(expectedMatchedExEnd)
1277 .doesNotEndWith(expectedMatchedRootExEnd);
1278 assertThat(accessor.getString("stringMatchedEx"))
1279 .endsWith(expectedMatchedExEnd);
1280 assertThat(accessor.getString("regexMatchedEx"))
1281 .endsWith(expectedMatchedExEnd);
1282
1283 // Check the serialized exception root cause.
1284 assertThat(accessor.getString("rootEx"))
1285 .doesNotEndWith(expectedMatchedExEnd)
1286 .doesNotEndWith(expectedMatchedRootExEnd);
1287 assertThat(accessor.getString("stringMatchedRootEx"))
1288 .endsWith(expectedMatchedRootExEnd);
1289 assertThat(accessor.getString("regexMatchedRootEx"))
1290 .endsWith(expectedMatchedRootExEnd);
1291
1292 });
1293
1294 }
1295
1296 @Test
12971053 void test_inline_stack_trace_element_template() {
12981054
12991055 // Create the event template.
13251081
13261082 // Check the serialized log event.
13271083 final String expectedClassName = JsonTemplateLayoutTest.class.getCanonicalName();
1328 usingSerializedLogEventAccessor(layout, logEvent, accessor -> Assertions
1329 .assertThat(accessor.getList("stackTrace", String.class))
1330 .contains(expectedClassName));
1084 usingSerializedLogEventAccessor(layout, logEvent, accessor ->
1085 assertThat(accessor.getList("stackTrace", String.class))
1086 .contains(expectedClassName));
13311087
13321088 }
13331089
13541110 .build();
13551111
13561112 // Check the serialized log event.
1357 usingSerializedLogEventAccessor(layout, logEvent, accessor -> Assertions
1358 .assertThat(accessor.getString("customField"))
1359 .matches("CustomValue-[0-9]+"));
1113 usingSerializedLogEventAccessor(layout, logEvent, accessor ->
1114 assertThat(accessor.getString("customField"))
1115 .matches("CustomValue-[0-9]+"));
13601116
13611117 }
13621118
14211177 .newBuilder()
14221178 .setLoggerName(LOGGER_NAME)
14231179 .setMessage(message)
1424 .setThrown(NonAsciiUtf8MethodNameContainingException.INSTANCE)
14251180 .build();
14261181
14271182 // Check the serialized event.
18131568 final String expectedSerializedLogEventJson =
18141569 "{}" + JsonTemplateLayoutDefaults.getEventDelimiter();
18151570 final String actualSerializedLogEventJson = layout.toSerializable(logEvent);
1816 Assertions
1817 .assertThat(actualSerializedLogEventJson)
1818 .isEqualTo(expectedSerializedLogEventJson);
1571 assertThat(actualSerializedLogEventJson).isEqualTo(expectedSerializedLogEventJson);
18191572
18201573 }
18211574
18461599 .build();
18471600
18481601 // Check the serialized event.
1849 Assertions
1850 .assertThatThrownBy(() -> layout.toSerializable(logEvent))
1602 assertThatThrownBy(() -> layout.toSerializable(logEvent))
18511603 .isInstanceOf(StackOverflowError.class);
18521604
18531605 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j.layout.template.json.resolver;
17
18 import org.apache.logging.log4j.core.LogEvent;
19 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
20 import org.apache.logging.log4j.layout.template.json.JsonTemplateLayout;
21 import org.apache.logging.log4j.layout.template.json.JsonTemplateLayoutDefaults;
22 import org.assertj.core.api.AbstractStringAssert;
23 import org.junit.jupiter.api.Nested;
24 import org.junit.jupiter.api.Test;
25
26 import java.io.ByteArrayOutputStream;
27 import java.io.PrintStream;
28 import java.math.BigDecimal;
29 import java.net.ServerSocket;
30 import java.util.Arrays;
31 import java.util.Collections;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.function.Consumer;
35 import java.util.regex.Pattern;
36 import java.util.stream.Collectors;
37 import java.util.stream.Stream;
38
39 import static org.apache.logging.log4j.layout.template.json.TestHelpers.*;
40 import static org.assertj.core.api.Assertions.assertThat;
41
42 class StackTraceStringResolverTest {
43
44 ////////////////////////////////////////////////////////////////////////////
45 // exceptions //////////////////////////////////////////////////////////////
46 ////////////////////////////////////////////////////////////////////////////
47
48 // Below we create arbitrary exceptions containing stack entries from non-Log4j packages.
49 // Non-Log4j package origin is needed to avoid the truncation (e.g., `... 58 more`) done by `Throwable#printStackTrace()`.
50
51 private static final String EXCEPTION_REGEX_FLAGS = "(?s)"; // DOTALL
52
53 private static final String TRUNCATION_SUFFIX = "<truncated>";
54
55 @SuppressWarnings({"BigDecimalMethodWithoutRoundingCalled", "ResultOfMethodCallIgnored"})
56 private static Throwable exception1() {
57 return catchException(() -> BigDecimal.ONE.divide(BigDecimal.ZERO));
58 }
59
60 private static String exception1Regex(final boolean truncated) {
61 final String truncationCorrectionRegex = truncationSuffixRegexOr(truncated, ".divide\\(");
62 return "java.lang.ArithmeticException: Division by zero\r?\n" +
63 "\t+at java.math.BigDecimal" + truncationCorrectionRegex + ".*";
64 }
65
66 @SuppressWarnings("ConstantConditions")
67 private static Throwable exception2() {
68 return catchException(() -> Collections.emptyList().add(0));
69 }
70
71 private static String exception2Regex(final boolean truncated) {
72 final String truncationCorrectionRegex = truncationSuffixRegexOr(truncated, ".add\\(");
73 return "java.lang.UnsupportedOperationException\r?\n" +
74 "\t+at java.util.AbstractList" + truncationCorrectionRegex + ".*";
75 }
76
77 private static Throwable exception3() {
78 return catchException(() -> new ServerSocket(-1));
79 }
80
81 private static String exception3Regex(final boolean truncated) {
82 final String truncationCorrectionRegex = truncationSuffixRegexOr(truncated, ".<init>");
83 return "java.lang.IllegalArgumentException: Port value out of range: -1\r?\n" +
84 "\t+at java.net.ServerSocket" + truncationCorrectionRegex + ".*";
85 }
86
87 private static String truncationSuffixRegexOr(final boolean truncated, final String fallback) {
88 return truncated
89 ? ("\r?\n" + TRUNCATION_SUFFIX)
90 : fallback;
91 }
92
93 private static Throwable catchException(ThrowingRunnable runnable) {
94 try {
95 runnable.run();
96 throw new AssertionError("should not have reached here");
97 } catch (Throwable error) {
98 return error;
99 }
100 }
101
102 @FunctionalInterface
103 private interface ThrowingRunnable {
104
105 void run() throws Throwable;
106
107 }
108
109 @Test
110 void exception1_regex_should_match() {
111 final Throwable error = exception1();
112 final String stackTrace = stackTrace(error);
113 final String regex = exception1Regex(false);
114 assertThat(stackTrace).matches(EXCEPTION_REGEX_FLAGS + regex);
115 }
116
117 @Test
118 void exception2_regex_should_match() {
119 final Throwable error = exception2();
120 final String stackTrace = stackTrace(error);
121 final String regex = exception2Regex(false);
122 assertThat(stackTrace).matches(EXCEPTION_REGEX_FLAGS + regex);
123 }
124
125 @Test
126 void exception3_regex_should_match() {
127 final Throwable error = exception3();
128 final String stackTrace = stackTrace(error);
129 final String regex = exception3Regex(false);
130 assertThat(stackTrace).matches(EXCEPTION_REGEX_FLAGS + regex);
131 }
132
133 private static String stackTrace(final Throwable throwable) {
134 final String encoding = "UTF-8";
135 try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
136 PrintStream printStream = new PrintStream(outputStream, false, encoding)) {
137 throwable.printStackTrace(printStream);
138 printStream.flush();
139 return outputStream.toString(encoding);
140 } catch (Exception error) {
141 throw new RuntimeException(error);
142 }
143 }
144
145 ////////////////////////////////////////////////////////////////////////////
146 // abstract tests //////////////////////////////////////////////////////////
147 ////////////////////////////////////////////////////////////////////////////
148
149 private static abstract class AbstractTestCases {
150
151 private final boolean truncated;
152
153 AbstractTestCases(boolean truncated) {
154 this.truncated = truncated;
155 }
156
157 private String exception1Regex() {
158 return StackTraceStringResolverTest.exception1Regex(truncated);
159 }
160
161 private String exception2Regex() {
162 return StackTraceStringResolverTest.exception2Regex(truncated);
163 }
164
165 private String exception3Regex() {
166 return StackTraceStringResolverTest.exception3Regex(truncated);
167 }
168
169 @Test
170 void exception_should_be_resolved() {
171 final Throwable exception = exception1();
172 final String serializedExceptionRegex = EXCEPTION_REGEX_FLAGS + exception1Regex();
173 assertSerializedException(exception, serializedExceptionRegex);
174 }
175
176 @Test
177 void exception_with_cause_should_be_resolved() {
178
179 // Create the exception.
180 final Throwable exception = exception1();
181 final Throwable cause = exception2();
182 exception.initCause(cause);
183
184 // Check the serialized exception.
185 final String serializedExceptionRegex = EXCEPTION_REGEX_FLAGS +
186 exception1Regex() +
187 "\nCaused by: " + exception2Regex();
188 assertSerializedException(exception, serializedExceptionRegex);
189
190 }
191
192 @Test
193 void exception_with_causes_should_be_resolved() {
194
195 // Create the exception.
196 final Throwable exception = exception1();
197 final Throwable cause1 = exception2();
198 final Throwable cause2 = exception3();
199 exception.initCause(cause1);
200 cause1.initCause(cause2);
201
202 // Check the serialized exception.
203 final String serializedExceptionRegex = EXCEPTION_REGEX_FLAGS +
204 exception1Regex() +
205 "\nCaused by: " + exception2Regex() +
206 "\nCaused by: " + exception3Regex();
207 assertSerializedException(exception, serializedExceptionRegex);
208
209 }
210
211 @Test
212 void exception_with_suppressed_should_be_resolved() {
213
214 // Create the exception.
215 final Throwable exception = exception1();
216 final Throwable suppressed = exception2();
217 exception.addSuppressed(suppressed);
218
219 // Check the serialized exception.
220 final String serializedExceptionRegex = EXCEPTION_REGEX_FLAGS +
221 exception1Regex() +
222 "\n\tSuppressed: " + exception2Regex();
223 assertSerializedException(exception, serializedExceptionRegex);
224
225 }
226
227 @Test
228 void exception_with_suppresseds_should_be_resolved() {
229
230 // Create the exception.
231 final Throwable exception = exception1();
232 final Throwable suppressed1 = exception2();
233 final Throwable suppressed2 = exception3();
234 exception.addSuppressed(suppressed1);
235 exception.addSuppressed(suppressed2);
236
237 // Check the serialized exception.
238 final String serializedExceptionRegex = EXCEPTION_REGEX_FLAGS +
239 exception1Regex() +
240 "\n\tSuppressed: " + exception2Regex() +
241 "\n\tSuppressed: " + exception3Regex();
242 assertSerializedException(exception, serializedExceptionRegex);
243
244 }
245
246 @Test
247 void exception_with_cause_and_suppressed_should_be_resolved() {
248
249 // Create the exception.
250 final Throwable exception = exception1();
251 final Throwable suppressed = exception2();
252 final Throwable cause = exception3();
253 exception.addSuppressed(suppressed);
254 exception.initCause(cause);
255
256 // Check the serialized exception.
257 final String serializedExceptionRegex = EXCEPTION_REGEX_FLAGS +
258 exception1Regex() +
259 "\n\tSuppressed: " + exception2Regex() +
260 "\nCaused by: " + exception3Regex();
261 assertSerializedException(exception, serializedExceptionRegex);
262
263 }
264
265 @Test
266 void exception_with_cause_with_suppressed_should_be_resolved() {
267
268 // Create the exception.
269 final Throwable exception = exception1();
270 final Throwable cause = exception2();
271 final Throwable suppressed = exception3();
272 exception.initCause(cause);
273 cause.addSuppressed(suppressed);
274
275 // Check the serialized exception.
276 final String serializedExceptionRegex = EXCEPTION_REGEX_FLAGS +
277 exception1Regex() +
278 "\nCaused by: " + exception2Regex() +
279 "\n\tSuppressed: " + exception3Regex();
280 assertSerializedException(exception, serializedExceptionRegex);
281
282 }
283
284 @Test
285 void exception_with_suppressed_with_cause_should_be_resolved() {
286
287 // Create the exception.
288 final Throwable exception = exception1();
289 final Throwable suppressed = exception2();
290 final Throwable cause = exception3();
291 exception.addSuppressed(suppressed);
292 suppressed.initCause(cause);
293
294 // Check the serialized exception.
295 final String serializedExceptionRegex = EXCEPTION_REGEX_FLAGS +
296 exception1Regex() +
297 "\n\tSuppressed: " + exception2Regex() +
298 "\n\tCaused by: " + exception3Regex();
299 assertSerializedException(exception, serializedExceptionRegex);
300
301 }
302
303 abstract void assertSerializedException(
304 final Throwable exception,
305 final String regex);
306
307 private static void assertSerializedException(
308 final Map<String, ?> exceptionResolverTemplate,
309 final Throwable exception,
310 final Consumer<AbstractStringAssert<?>> serializedExceptionAsserter) {
311
312 // Create the event template.
313 final String eventTemplate = writeJson(asMap("output", exceptionResolverTemplate));
314
315 // Create the layout.
316 final JsonTemplateLayout layout = JsonTemplateLayout
317 .newBuilder()
318 .setConfiguration(CONFIGURATION)
319 .setEventTemplate(eventTemplate)
320 .build();
321
322 // Create the log event.
323 final LogEvent logEvent = Log4jLogEvent
324 .newBuilder()
325 .setThrown(exception)
326 .build();
327
328 // Check the serialized event.
329 usingSerializedLogEventAccessor(layout, logEvent, accessor -> {
330 AbstractStringAssert<?> serializedExceptionAssert = assertThat(accessor.getString("output"));
331 serializedExceptionAsserter.accept(serializedExceptionAssert);
332 });
333
334 }
335
336 }
337
338 ////////////////////////////////////////////////////////////////////////////
339 // tests without truncation ////////////////////////////////////////////////
340 ////////////////////////////////////////////////////////////////////////////
341
342 @Nested
343 class WithoutTruncation extends AbstractTestCases {
344
345 WithoutTruncation() {
346 super(false);
347 }
348
349 @Override
350 void assertSerializedException(final Throwable exception, final String regex) {
351 assertSerializedExceptionWithoutTruncation(exception, regex);
352 }
353
354 private void assertSerializedExceptionWithoutTruncation(
355 final Throwable exception,
356 final String regex) {
357
358 // Create the event template.
359 final Map<String, ?> exceptionResolverTemplate = asMap(
360 "$resolver", "exception",
361 "field", "stackTrace",
362 "stackTrace", asMap("stringified", true));
363
364 // Check the serialized event.
365 AbstractTestCases.assertSerializedException(
366 exceptionResolverTemplate,
367 exception,
368 serializedExceptionAssert -> serializedExceptionAssert.matches(regex));
369
370 }
371
372 @Test
373 void JsonWriter_maxStringLength_should_work() {
374
375 // Create the event template.
376 final String eventTemplate = writeJson(asMap(
377 "ex", asMap(
378 "$resolver", "exception",
379 "field", "stackTrace",
380 "stringified", true)));
381
382 // Create the layout.
383 final int maxStringLength = eventTemplate.length();
384 final JsonTemplateLayout layout = JsonTemplateLayout
385 .newBuilder()
386 .setConfiguration(CONFIGURATION)
387 .setEventTemplate(eventTemplate)
388 .setMaxStringLength(maxStringLength)
389 .setStackTraceEnabled(true)
390 .build();
391
392 // Create the log event.
393 Throwable exception = exception1();
394 final LogEvent logEvent = Log4jLogEvent
395 .newBuilder()
396 .setThrown(exception)
397 .build();
398
399 // Check the serialized event.
400 usingSerializedLogEventAccessor(layout, logEvent, accessor -> {
401 final int expectedLength = maxStringLength +
402 JsonTemplateLayoutDefaults.getTruncatedStringSuffix().length();
403 assertThat(accessor.getString("ex").length()).isEqualTo(expectedLength);
404 });
405
406 }
407
408 }
409
410 ////////////////////////////////////////////////////////////////////////////
411 // tests with `truncationPointMatcherStrings` //////////////////////////////
412 ////////////////////////////////////////////////////////////////////////////
413
414 @Nested
415 class WithTruncation extends AbstractTestCases {
416
417 WithTruncation() {
418 super(true);
419 }
420
421 @Override
422 void assertSerializedException(final Throwable exception, final String regex) {
423 assertSerializedExceptionWithStringTruncation(exception, regex);
424 }
425
426 private void assertSerializedExceptionWithStringTruncation(
427 final Throwable exception,
428 final String regex) {
429
430 // Create the event template.
431 final List<String> pointMatcherStrings = pointMatcherStrings();
432 final Map<String, ?> exceptionResolverTemplate = asMap(
433 "$resolver", "exception",
434 "field", "stackTrace",
435 "stackTrace", asMap("stringified", asMap(
436 "truncation", asMap(
437 "suffix", TRUNCATION_SUFFIX,
438 "pointMatcherStrings", pointMatcherStrings))));
439
440 // Check the serialized event.
441 AbstractTestCases.assertSerializedException(
442 exceptionResolverTemplate,
443 exception,
444 serializedExceptionAssert -> serializedExceptionAssert.matches(regex));
445
446 }
447
448 private List<String> pointMatcherStrings() {
449 final Throwable exception1 = exception1();
450 final Throwable exception2 = exception2();
451 final Throwable exception3 = exception3();
452 return Stream
453 .of(exception1, exception2, exception3)
454 .map(this::pointMatcherString)
455 .collect(Collectors.toList());
456 }
457
458 @Test
459 void point_matchers_should_work() {
460
461 // Create the exception to be logged.
462 final Throwable parentError = exception1();
463 final Throwable childError = exception3();
464 parentError.initCause(childError);
465
466 // Create the event template.
467 final String eventTemplate = writeJson(asMap(
468
469 // Raw exception
470 "ex", asMap(
471 "$resolver", "exception",
472 "field", "stackTrace",
473 "stackTrace", asMap(
474 "stringified", true)),
475
476 // Exception matcher using strings
477 "stringMatchedEx", asMap(
478 "$resolver", "exception",
479 "field", "stackTrace",
480 "stackTrace", asMap(
481 "stringified", asMap(
482 "truncation", asMap(
483 "suffix", TRUNCATION_SUFFIX,
484 "pointMatcherStrings", Arrays.asList(
485 "this string shouldn't match with anything",
486 pointMatcherString(parentError)))))),
487
488 // Exception matcher using regexes
489 "regexMatchedEx", asMap(
490 "$resolver", "exception",
491 "field", "stackTrace",
492 "stackTrace", asMap(
493 "stringified", asMap(
494 "truncation", asMap(
495 "suffix", TRUNCATION_SUFFIX,
496 "pointMatcherRegexes", Arrays.asList(
497 "this string shouldn't match with anything",
498 pointMatcherRegex(parentError)))))),
499
500 // Raw exception root cause
501 "rootEx", asMap(
502 "$resolver", "exceptionRootCause",
503 "field", "stackTrace",
504 "stackTrace", asMap(
505 "stringified", true)),
506
507 // Exception root cause matcher using strings
508 "stringMatchedRootEx", asMap(
509 "$resolver", "exceptionRootCause",
510 "field", "stackTrace",
511 "stackTrace", asMap(
512 "stringified", asMap(
513 "truncation", asMap(
514 "suffix", TRUNCATION_SUFFIX,
515 "pointMatcherStrings", Arrays.asList(
516 "this string shouldn't match with anything",
517 pointMatcherString(childError)))))),
518
519 // Exception root cause matcher using regexes
520 "regexMatchedRootEx", asMap(
521 "$resolver", "exceptionRootCause",
522 "field", "stackTrace",
523 "stackTrace", asMap(
524 "stringified", asMap(
525 "truncation", asMap(
526 "suffix", TRUNCATION_SUFFIX,
527 "pointMatcherRegexes", Arrays.asList(
528 "this string shouldn't match with anything",
529 pointMatcherRegex(childError))))))));
530
531 // Create the layout.
532 final JsonTemplateLayout layout = JsonTemplateLayout
533 .newBuilder()
534 .setConfiguration(CONFIGURATION)
535 .setEventTemplate(eventTemplate)
536 .build();
537
538 // Create the log event.
539 final LogEvent logEvent = Log4jLogEvent
540 .newBuilder()
541 .setThrown(parentError)
542 .build();
543
544 // Check the serialized event.
545 usingSerializedLogEventAccessor(layout, logEvent, accessor -> {
546
547 // Check the raw parent exception.
548 final String exPattern = EXCEPTION_REGEX_FLAGS +
549 exception1Regex(false) +
550 "\nCaused by: " + exception3Regex(false);
551 assertThat(accessor.getString("ex")).matches(exPattern);
552
553 // Check the matcher usage on parent exception.
554 final String matchedExPattern = EXCEPTION_REGEX_FLAGS +
555 exception1Regex(true) +
556 "\nCaused by: " + exception3Regex(false);
557 assertThat(accessor.getString("stringMatchedEx")).matches(matchedExPattern);
558 assertThat(accessor.getString("regexMatchedEx")).matches(matchedExPattern);
559
560 // Check the raw child exception.
561 final String rootExPattern = EXCEPTION_REGEX_FLAGS +
562 exception3Regex(false);
563 assertThat(accessor.getString("rootEx")).matches(rootExPattern);
564
565 // Check the matcher usage on child exception.
566 final String matchedRootExPattern = EXCEPTION_REGEX_FLAGS +
567 exception3Regex(true);
568 assertThat(accessor.getString("stringMatchedRootEx")).matches(matchedRootExPattern);
569 assertThat(accessor.getString("regexMatchedRootEx")).matches(matchedRootExPattern);
570
571 });
572
573 }
574
575 private String pointMatcherString(Throwable exception) {
576 final StackTraceElement stackTraceElement = exception.getStackTrace()[0];
577 final String className = stackTraceElement.getClassName();
578 return "at " + className;
579 }
580
581 private String pointMatcherRegex(Throwable exception) {
582 String string = pointMatcherString(exception);
583 return matchingRegex(string);
584 }
585
586 /**
587 * @return a regex matching the given input
588 */
589 private String matchingRegex(String string) {
590 return "[" + string.charAt(0) + "]" + Pattern.quote(string.substring(1));
591 }
592
593 }
594
595 @Test
596 void nonAscii_utf8_method_name_should_get_serialized() {
597
598 // Create the log event.
599 final LogEvent logEvent = Log4jLogEvent
600 .newBuilder()
601 .setThrown(NonAsciiUtf8MethodNameContainingException.INSTANCE)
602 .build();
603
604 // Create the event template.
605 final String eventTemplate = writeJson(asMap(
606 "ex_stacktrace", asMap(
607 "$resolver", "exception",
608 "field", "stackTrace",
609 "stringified", true)));
610
611 // Create the layout.
612 final JsonTemplateLayout layout = JsonTemplateLayout
613 .newBuilder()
614 .setConfiguration(CONFIGURATION)
615 .setStackTraceEnabled(true)
616 .setEventTemplate(eventTemplate)
617 .build();
618
619 // Check the serialized event.
620 usingSerializedLogEventAccessor(layout, logEvent, accessor ->
621 assertThat(accessor.getString("ex_stacktrace"))
622 .contains(NonAsciiUtf8MethodNameContainingException.NON_ASCII_UTF8_TEXT));
623
624 }
625
626 private static final class NonAsciiUtf8MethodNameContainingException extends RuntimeException {
627
628 public static final long serialVersionUID = 0;
629
630 private static final String NON_ASCII_UTF8_TEXT = "அஆஇฬ๘";
631
632 private static final NonAsciiUtf8MethodNameContainingException INSTANCE =
633 createInstance();
634
635 private static NonAsciiUtf8MethodNameContainingException createInstance() {
636 try {
637 throwException_அஆஇฬ๘();
638 throw new IllegalStateException("should not have reached here");
639 } catch (final NonAsciiUtf8MethodNameContainingException exception) {
640 return exception;
641 }
642 }
643
644 @SuppressWarnings("NonAsciiCharacters")
645 private static void throwException_அஆஇฬ๘() {
646 throw new NonAsciiUtf8MethodNameContainingException(
647 "exception with non-ASCII UTF-8 method name");
648 }
649
650 private NonAsciiUtf8MethodNameContainingException(final String message) {
651 super(message);
652 }
653
654 }
655
656 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j.layout.template.json.util;
17
18 import org.assertj.core.api.Assertions;
19 import org.junit.jupiter.api.Test;
20 import org.junit.jupiter.params.ParameterizedTest;
21 import org.junit.jupiter.params.provider.CsvSource;
22
23 class CharSequencePointerTest {
24
25 private final CharSequencePointer pointer = new CharSequencePointer();
26
27 @Test
28 void length_should_fail_without_reset() {
29 // noinspection ResultOfMethodCallIgnored
30 assertMissingReset(pointer::length);
31 }
32
33 @Test
34 void charAt_should_fail_without_reset() {
35 assertMissingReset(() -> pointer.charAt(0));
36 }
37
38 @Test
39 void toString_should_fail_without_reset() {
40 // noinspection ResultOfMethodCallIgnored
41 assertMissingReset(pointer::toString);
42 }
43
44 private static void assertMissingReset(final Runnable runnable) {
45 Assertions
46 .assertThatThrownBy(runnable::run)
47 .isInstanceOf(IllegalStateException.class)
48 .hasMessage("pointer must be reset first");
49 }
50
51 @ParameterizedTest
52 @CsvSource({
53 "'',0,0,''",
54 "foo,0,1,f",
55 "foo,1,1,''",
56 "foo,1,2,o",
57 "foo,3,3,''"
58 })
59 void toString_should_subSequence(
60 final CharSequence delegate,
61 final int startIndex,
62 final int endIndex,
63 final String expectedOutput) {
64 pointer.reset(delegate, startIndex, endIndex);
65 Assertions.assertThat(pointer).hasToString(expectedOutput);
66 }
67
68 @Test
69 void subSequence_should_not_be_supported() {
70 pointer.reset("", 0, 0);
71 assertUnsupportedOperation(() -> pointer.subSequence(0, 0));
72 }
73
74 @Test
75 void chars_should_not_be_supported() {
76 pointer.reset("", 0, 0);
77 assertUnsupportedOperation(() -> pointer.subSequence(0, 0));
78 }
79
80 @Test
81 void codePoints_should_not_be_supported() {
82 pointer.reset("", 0, 0);
83 assertUnsupportedOperation(() -> pointer.subSequence(0, 0));
84 }
85
86 private static void assertUnsupportedOperation(final Runnable runnable) {
87 Assertions
88 .assertThatThrownBy(runnable::run)
89 .isInstanceOf(UnsupportedOperationException.class)
90 .hasMessage("operation requires allocation, contradicting with the purpose of the class");
91 }
92
93 @Test
94 void reset_should_fail_on_null_delegate() {
95 Assertions
96 .assertThatThrownBy(() -> pointer.reset(null, 0, 0))
97 .isInstanceOf(NullPointerException.class)
98 .hasMessage("delegate");
99 }
100
101 @ParameterizedTest
102 @CsvSource({
103 "foo,-1,3,invalid start: -1",
104 "foo,4,3,invalid length: -1",
105 "foo,0,-1,invalid length: -1",
106 "foo,1,0,invalid length: -1",
107 "foo,0,4,invalid end: 4"
108 })
109 void reset_should_fail_on_invalid_indices(
110 final CharSequence delegate,
111 final int startIndex,
112 final int endIndex,
113 final String expectedErrorMessage) {
114 Assertions
115 .assertThatThrownBy(() -> pointer.reset(delegate, startIndex, endIndex))
116 .isInstanceOf(IndexOutOfBoundsException.class)
117 .hasMessage(expectedErrorMessage);
118 }
119
120 }
1717
1818 import org.assertj.core.api.Assertions;
1919 import org.junit.jupiter.api.Test;
20
21 import java.util.function.Consumer;
2022
2123 class TruncatingBufferedWriterTest {
2224
224226 verifyTruncation(writer, 'n');
225227 }
226228
227 private void verifyTruncation(
229 private static void verifyTruncation(
228230 final TruncatingBufferedWriter writer,
229231 final char c) {
230232 Assertions.assertThat(writer.buffer()).isEqualTo(new char[]{c});
234236 verifyClose(writer);
235237 }
236238
237 private void verifyClose(final TruncatingBufferedWriter writer) {
239 private static void verifyClose(final TruncatingBufferedWriter writer) {
238240 writer.close();
239241 Assertions.assertThat(writer.position()).isEqualTo(0);
240242 Assertions.assertThat(writer.truncated()).isFalse();
241243 }
242244
245 @Test
246 void test_length_and_position() {
247
248 // Create the writer and the verifier.
249 final TruncatingBufferedWriter writer = new TruncatingBufferedWriter(2);
250 final Consumer<Integer> positionAndLengthVerifier =
251 (final Integer expected) -> Assertions
252 .assertThat(writer.position())
253 .isEqualTo(writer.length())
254 .isEqualTo(expected);
255
256 // Check the initial condition.
257 positionAndLengthVerifier.accept(0);
258
259 // Append the 1st character and verify.
260 writer.write("a");
261 positionAndLengthVerifier.accept(1);
262
263 // Append the 2nd character and verify.
264 writer.write("b");
265 positionAndLengthVerifier.accept(2);
266
267 // Append the 3rd to-be-truncated character and verify.
268 writer.write("c");
269 positionAndLengthVerifier.accept(2);
270
271 // Reposition the writer and verify.
272 writer.position(1);
273 positionAndLengthVerifier.accept(1);
274
275 }
276
277 @Test
278 void subSequence_should_not_be_supported() {
279 final TruncatingBufferedWriter writer = new TruncatingBufferedWriter(2);
280 assertUnsupportedOperation(() -> writer.subSequence(0, 0));
281 }
282
283 @Test
284 void chars_should_not_be_supported() {
285 final TruncatingBufferedWriter writer = new TruncatingBufferedWriter(2);
286 assertUnsupportedOperation(() -> writer.subSequence(0, 0));
287 }
288
289 @Test
290 void codePoints_should_not_be_supported() {
291 final TruncatingBufferedWriter writer = new TruncatingBufferedWriter(2);
292 assertUnsupportedOperation(() -> writer.subSequence(0, 0));
293 }
294
295 private static void assertUnsupportedOperation(final Runnable runnable) {
296 Assertions
297 .assertThatThrownBy(runnable::run)
298 .isInstanceOf(UnsupportedOperationException.class)
299 .hasMessage("operation requires allocation, contradicting with the purpose of the class");
300 }
301
243302 }
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-liquibase</artifactId>
2525 <packaging>jar</packaging>
6565 <dependency>
6666 <groupId>org.junit.vintage</groupId>
6767 <artifactId>junit-vintage-engine</artifactId>
68 <scope>test</scope>
6869 </dependency>
6970 <dependency>
7071 <groupId>org.junit.jupiter</groupId>
7172 <artifactId>junit-jupiter-engine</artifactId>
73 <scope>test</scope>
7274 </dependency>
7375 </dependencies>
7476 <build>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <modelVersion>4.0.0</modelVersion>
2525
5555 <dependency>
5656 <groupId>org.junit.vintage</groupId>
5757 <artifactId>junit-vintage-engine</artifactId>
58 <scope>test</scope>
5859 </dependency>
5960 <dependency>
6061 <groupId>org.junit.jupiter</groupId>
6162 <artifactId>junit-jupiter-engine</artifactId>
63 <scope>test</scope>
6264 </dependency>
6365 <dependency>
6466 <groupId>org.mockito</groupId>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <modelVersion>4.0.0</modelVersion>
2525
5555 <dependency>
5656 <groupId>org.junit.vintage</groupId>
5757 <artifactId>junit-vintage-engine</artifactId>
58 <scope>test</scope>
5859 </dependency>
5960 <dependency>
6061 <groupId>org.junit.jupiter</groupId>
6162 <artifactId>junit-jupiter-engine</artifactId>
63 <scope>test</scope>
6264 </dependency>
6365 <dependency>
6466 <groupId>org.mockito</groupId>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-osgi</artifactId>
2525 <packaging>jar</packaging>
3131 <projectDir>/osgi</projectDir>
3232 <module.name>org.apache.logging.log4j.osgi</module.name>
3333 <maven.doap.skip>true</maven.doap.skip>
34 <pax.exam.version>4.13.5</pax.exam.version>
3435 </properties>
3536 <dependencies>
37 <dependency>
38 <groupId>org.apache.logging.log4j</groupId>
39 <artifactId>log4j-api</artifactId>
40 <scope>test</scope>
41 </dependency>
42 <dependency>
43 <groupId>org.apache.logging.log4j</groupId>
44 <artifactId>log4j-api</artifactId>
45 <version>${project.version}</version>
46 <classifier>tests</classifier>
47 <scope>test</scope>
48 </dependency>
49 <dependency>
50 <groupId>org.apache.logging.log4j</groupId>
51 <artifactId>log4j-1.2-api</artifactId>
52 <scope>test</scope>
53 </dependency>
54 <dependency>
55 <groupId>org.apache.logging.log4j</groupId>
56 <artifactId>log4j-core</artifactId>
57 <scope>test</scope>
58 </dependency>
59 <dependency>
60 <groupId>org.apache.logging.log4j</groupId>
61 <artifactId>log4j-to-jul</artifactId>
62 <scope>test</scope>
63 </dependency>
64 <dependency>
65 <groupId>org.apache.logging.log4j</groupId>
66 <artifactId>log4j-to-slf4j</artifactId>
67 <scope>test</scope>
68 </dependency>
69 <dependency>
70 <groupId>org.apache.logging.log4j.samples</groupId>
71 <artifactId>log4j-samples-configuration</artifactId>
72 <version>${project.version}</version>
73 <scope>test</scope>
74 </dependency>
75 <dependency>
76 <groupId>ch.qos.logback</groupId>
77 <artifactId>logback-classic</artifactId>
78 <scope>test</scope>
79 </dependency>
80 <dependency>
81 <groupId>ch.qos.logback</groupId>
82 <artifactId>logback-core</artifactId>
83 <scope>test</scope>
84 </dependency>
3685 <!-- Place Felix before Equinox because Felix is signed. / also place it before org.osgi.core so that its versions of the OSGi classes are used -->
3786 <dependency>
3887 <groupId>org.apache.felix</groupId>
4291 <dependency>
4392 <groupId>org.osgi</groupId>
4493 <artifactId>org.osgi.core</artifactId>
45 <scope>test</scope>
4694 </dependency>
4795 <dependency>
4896 <groupId>org.junit.vintage</groupId>
4997 <artifactId>junit-vintage-engine</artifactId>
98 <scope>test</scope>
5099 </dependency>
51100 <dependency>
52101 <groupId>org.junit.jupiter</groupId>
53102 <artifactId>junit-jupiter-engine</artifactId>
103 <scope>test</scope>
54104 </dependency>
55105 <dependency>
56106 <groupId>org.eclipse.tycho</groupId>
58108 <scope>test</scope>
59109 </dependency>
60110 <dependency>
61 <groupId>org.apache.maven</groupId>
62 <artifactId>maven-core</artifactId>
63 <scope>test</scope>
64 </dependency>
65 <dependency>
66 <groupId>org.apache.commons</groupId>
67 <artifactId>commons-lang3</artifactId>
68 <scope>test</scope>
111 <groupId>javax.inject</groupId>
112 <artifactId>javax.inject</artifactId>
113 </dependency>
114 <dependency>
115 <groupId>org.ops4j.pax.exam</groupId>
116 <artifactId>pax-exam</artifactId>
117 <version>${pax.exam.version}</version>
118 <scope>test</scope>
119 </dependency>
120 <dependency>
121 <groupId>org.ops4j.pax.exam</groupId>
122 <artifactId>pax-exam-spi</artifactId>
123 <version>${pax.exam.version}</version>
124 <scope>test</scope>
125 </dependency>
126 <dependency>
127 <groupId>org.ops4j.pax.exam</groupId>
128 <artifactId>pax-exam-container-native</artifactId>
129 <version>${pax.exam.version}</version>
130 <scope>test</scope>
131 </dependency>
132 <dependency>
133 <groupId>org.ops4j.pax.exam</groupId>
134 <artifactId>pax-exam-junit4</artifactId>
135 <version>${pax.exam.version}</version>
136 <scope>test</scope>
137 </dependency>
138 <dependency>
139 <groupId>org.ops4j.pax.exam</groupId>
140 <artifactId>pax-exam-link-assembly</artifactId>
141 <version>${pax.exam.version}</version>
142 <scope>test</scope>
69143 </dependency>
70144 </dependencies>
71145 <build>
107181 </Import-Package>
108182 </instructions>
109183 </configuration>
184 </plugin>
185 <plugin>
186 <groupId>org.apache.maven.plugins</groupId>
187 <artifactId>maven-surefire-plugin</artifactId>
188 <configuration>
189 <systemPropertyVariables>
190 <!-- PAX logging has a copy of Log4j2 API-->
191 <pax.exam.logging>false</pax.exam.logging>
192 <java.protocol.handler.pkgs>org.ops4j.pax.url</java.protocol.handler.pkgs>
193 </systemPropertyVariables>
194 </configuration>
195 </plugin>
196 <plugin>
197 <groupId>org.ops4j.pax.exam</groupId>
198 <artifactId>exam-maven-plugin</artifactId>
199 <version>${pax.exam.version}</version>
200 <executions>
201 <execution>
202 <phase>generate-test-resources</phase>
203 <goals>
204 <goal>generate-link-files</goal>
205 </goals>
206 </execution>
207 </executions>
110208 </plugin>
111209 </plugins>
112210 </build>
2222 import java.io.PrintStream;
2323 import java.lang.reflect.Field;
2424 import java.lang.reflect.Method;
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
2725 import java.util.List;
2826 import java.util.stream.Collectors;
2927 import java.util.stream.Stream;
3028
31 import org.apache.logging.log4j.osgi.tests.junit.BundleTestInfo;
3229 import org.apache.logging.log4j.osgi.tests.junit.OsgiRule;
30 import org.apache.logging.log4j.util.ServiceLoaderUtil;
3331 import org.junit.Assert;
3432 import org.junit.Before;
3533 import org.junit.Rule;
4644
4745 private BundleContext bundleContext;
4846
49 private final BundleTestInfo bundleTestInfo;
50
51 private Path here;
52
5347 @Rule
5448 public OsgiRule osgi = new OsgiRule(getFactory());
55 /**
56 * Constructs a test for a given bundle.
57 */
58 public AbstractLoadBundleTest() {
59 this.bundleTestInfo = new BundleTestInfo();
60 }
6149
6250 /**
6351 * Called before each @Test.
6553 @Before
6654 public void before() throws BundleException {
6755 bundleContext = osgi.getFramework().getBundleContext();
68
69 here = Paths.get(".").toAbsolutePath().normalize();
56 }
57
58 private Bundle installBundle(String symbolicName) throws BundleException {
59 // The links are generated by 'exam-maven-plugin'
60 final String url = String.format("link:classpath:%s.link", symbolicName);
61 return bundleContext.installBundle(url);
7062 }
7163
7264 private Bundle getApiBundle() throws BundleException {
73 final Path apiPath = here.resolveSibling("log4j-api").resolve("target").resolve("log4j-api-" + bundleTestInfo.getVersion() + ".jar");
74 return bundleContext.installBundle(apiPath.toUri().toString());
65 return installBundle("org.apache.logging.log4j.api");
7566 }
7667
7768
7869 private Bundle getCoreBundle() throws BundleException {
79 final Path corePath = here.resolveSibling("log4j-core").resolve("target").resolve("log4j-core-" + bundleTestInfo.getVersion() + ".jar");
80 return bundleContext.installBundle(corePath.toUri().toString());
70 return installBundle("org.apache.logging.log4j.core");
8171 }
8272
8373 private Bundle getDummyBundle() throws BundleException {
84 final Path dumyPath = here.resolveSibling("log4j-samples").resolve("log4j-samples-configuration").resolve("target").resolve("log4j-samples-configuration-" + bundleTestInfo.getVersion() + ".jar");
85 return bundleContext.installBundle(dumyPath.toUri().toString());
74 return installBundle("org.apache.logging.log4j.samples.log4j-samples-configuration");
8675 }
8776
8877 private Bundle get12ApiBundle() throws BundleException {
89 final Path apiPath = here.resolveSibling("log4j-1.2-api").resolve("target").resolve("log4j-1.2-api-" + bundleTestInfo.getVersion() + ".jar");
90 return bundleContext.installBundle(apiPath.toUri().toString());
78 return installBundle("org.apache.logging.log4j.1.2-api");
9179 }
9280
9381 private Bundle getApiTestsBundle() throws BundleException {
94 final Path apiTestsPath = here.resolveSibling("log4j-api")
95 .resolve("target")
96 .resolve("log4j-api-" + bundleTestInfo.getVersion() + "-tests.jar");
97 return bundleContext.installBundle(apiTestsPath.toUri().toString());
82 return installBundle("org.apache.logging.log4j.api.tests");
9883 }
9984
10085 protected abstract FrameworkFactory getFactory();
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16
17 package org.apache.logging.log4j.osgi.tests;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertTrue;
21 import static org.ops4j.pax.exam.CoreOptions.junitBundles;
22 import static org.ops4j.pax.exam.CoreOptions.linkBundle;
23 import static org.ops4j.pax.exam.CoreOptions.options;
24
25 import java.util.Optional;
26 import java.util.stream.Stream;
27
28 import javax.inject.Inject;
29
30 import org.apache.logging.log4j.LogManager;
31 import org.apache.logging.log4j.spi.LoggerContextFactory;
32 import org.apache.logging.log4j.tojul.JULLoggerContextFactory;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 import org.ops4j.pax.exam.Configuration;
36 import org.ops4j.pax.exam.Option;
37 import org.ops4j.pax.exam.junit.PaxExam;
38 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
39 import org.ops4j.pax.exam.spi.reactors.PerClass;
40 import org.osgi.framework.Bundle;
41 import org.osgi.framework.BundleContext;
42
43 @RunWith(PaxExam.class)
44 @ExamReactorStrategy(PerClass.class)
45 public class JULProviderTest {
46
47 @Inject
48 private BundleContext context;
49
50 @Configuration
51 public Option[] config() {
52 return options(
53 linkBundle("org.apache.logging.log4j.api"),
54 linkBundle("org.apache.logging.log4j.to-jul"),
55 // required by Pax Exam's logging
56 linkBundle("slf4j.api"),
57 linkBundle("ch.qos.logback.classic"),
58 linkBundle("ch.qos.logback.core"),
59 junitBundles());
60 }
61
62 @Test
63 public void testJulFactoryResolves() {
64 final Optional<Bundle> julBundle = Stream.of(context.getBundles())
65 .filter(b -> "org.apache.logging.log4j.to-jul".equals(b.getSymbolicName()))
66 .findAny();
67 assertTrue(julBundle.isPresent());
68 final LoggerContextFactory factory = LogManager.getFactory();
69 assertEquals(JULLoggerContextFactory.class, factory.getClass());
70 }
71 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16
17 package org.apache.logging.log4j.osgi.tests;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertTrue;
21 import static org.ops4j.pax.exam.CoreOptions.junitBundles;
22 import static org.ops4j.pax.exam.CoreOptions.linkBundle;
23 import static org.ops4j.pax.exam.CoreOptions.options;
24
25 import java.util.Optional;
26 import java.util.stream.Stream;
27
28 import javax.inject.Inject;
29
30 import org.apache.logging.log4j.LogManager;
31 import org.apache.logging.log4j.spi.LoggerContextFactory;
32 import org.apache.logging.slf4j.SLF4JLoggerContextFactory;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 import org.ops4j.pax.exam.Configuration;
36 import org.ops4j.pax.exam.Option;
37 import org.ops4j.pax.exam.junit.PaxExam;
38 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
39 import org.ops4j.pax.exam.spi.reactors.PerClass;
40 import org.osgi.framework.Bundle;
41 import org.osgi.framework.BundleContext;
42
43 @RunWith(PaxExam.class)
44 @ExamReactorStrategy(PerClass.class)
45 public class SLF4JProviderTest {
46
47 @Inject
48 private BundleContext context;
49
50 @Configuration
51 public Option[] config() {
52 return options(
53 linkBundle("org.apache.logging.log4j.api"),
54 linkBundle("org.apache.logging.log4j.to-slf4j"),
55 linkBundle("slf4j.api"),
56 linkBundle("ch.qos.logback.classic"),
57 linkBundle("ch.qos.logback.core"),
58 junitBundles());
59 }
60
61 @Test
62 public void testSlf4jFactoryResolves() {
63 final Optional<Bundle> slf4jBundle = Stream.of(context.getBundles())
64 .filter(b -> "org.apache.logging.log4j.to-slf4j".equals(b.getSymbolicName()))
65 .findAny();
66 assertTrue(slf4jBundle.isPresent());
67 final LoggerContextFactory factory = LogManager.getFactory();
68 assertEquals(SLF4JLoggerContextFactory.class, factory.getClass());
69 }
70 }
+0
-71
log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/junit/BundleTestInfo.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16
17 package org.apache.logging.log4j.osgi.tests.junit;
18
19 import java.io.FileReader;
20 import java.io.IOException;
21
22 import org.apache.maven.model.Model;
23 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
24 import org.apache.maven.project.MavenProject;
25 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
26
27 /**
28 * Provides tests with bundle information. Reads the {@code pom.xml} in the current directory to get project settings.
29 */
30 public class BundleTestInfo {
31
32 private final MavenProject project;
33
34 /**
35 * Constructs a new helper objects and initializes itself.
36 */
37 public BundleTestInfo() {
38 try (final FileReader reader = new FileReader("pom.xml")) {
39 // get a raw POM view, not a fully realized POM object.
40 final Model model = new MavenXpp3Reader().read(reader);
41 this.project = new MavenProject(model);
42 } catch (final IOException | XmlPullParserException e) {
43 throw new IllegalStateException("Could not read pom.xml", e);
44 }
45 }
46
47 /**
48 * Gets the Maven artifact ID.
49 *
50 * @return the Maven artifact ID.
51 */
52 public String getArtifactId() {
53 return project.getArtifactId();
54 }
55
56 /**
57 * Gets the Maven version String.
58 *
59 * @return the Maven version String.
60 */
61 public String getVersion() {
62 return project.getVersion();
63 }
64
65 @Override
66 public String toString() {
67 return "BundleTestInfo [project=" + project + "]";
68 }
69
70 }
1919 <parent>
2020 <artifactId>log4j</artifactId>
2121 <groupId>org.apache.logging.log4j</groupId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424
2525 <artifactId>log4j-perf</artifactId>
1919 <parent>
2020 <artifactId>log4j-samples</artifactId>
2121 <groupId>org.apache.logging.log4j.samples</groupId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-samples-configuration</artifactId>
2525 <packaging>jar</packaging>
1919 <parent>
2020 <artifactId>log4j-samples</artifactId>
2121 <groupId>org.apache.logging.log4j.samples</groupId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-samples-flume-common</artifactId>
2525 <packaging>jar</packaging>
1919 <parent>
2020 <artifactId>log4j-samples</artifactId>
2121 <groupId>org.apache.logging.log4j.samples</groupId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-samples-flume-embedded</artifactId>
2525 <packaging>war</packaging>
1919 <parent>
2020 <artifactId>log4j-samples</artifactId>
2121 <groupId>org.apache.logging.log4j.samples</groupId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-samples-flume-remote</artifactId>
2525 <packaging>war</packaging>
1919 <parent>
2020 <artifactId>log4j-samples</artifactId>
2121 <groupId>org.apache.logging.log4j.samples</groupId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-samples-loggerProperties</artifactId>
2525 <packaging>jar</packaging>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <groupId>org.apache.logging.log4j.samples</groupId>
2525 <artifactId>log4j-samples</artifactId>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-slf4j-impl</artifactId>
2525 <packaging>jar</packaging>
8787 <dependency>
8888 <groupId>org.junit.vintage</groupId>
8989 <artifactId>junit-vintage-engine</artifactId>
90 <scope>test</scope>
9091 </dependency>
9192 <dependency>
9293 <groupId>org.junit.jupiter</groupId>
9394 <artifactId>junit-jupiter-engine</artifactId>
95 <scope>test</scope>
9496 </dependency>
9597 </dependencies>
9698 <build>
2929 import org.apache.logging.log4j.util.LoaderUtil;
3030 import org.slf4j.Marker;
3131 import org.slf4j.MarkerFactory;
32 import org.slf4j.impl.StaticMarkerBinder;
3332 import org.slf4j.spi.LocationAwareLogger;
3433
3534 /**
4645 private final boolean eventLogger;
4746 private transient ExtendedLogger logger;
4847 private final String name;
49
50 public Log4jLogger(final ExtendedLogger logger, final String name) {
48 private transient Log4jMarkerFactory markerFactory;
49
50 public Log4jLogger(final Log4jMarkerFactory markerFactory, final ExtendedLogger logger, final String name) {
51 this.markerFactory = markerFactory;
5152 this.logger = logger;
5253 this.eventLogger = "EventLogger".equals(name);
5354 this.name = name;
8586
8687 @Override
8788 public boolean isTraceEnabled(final Marker marker) {
88 return logger.isEnabled(Level.TRACE, getMarker(marker), null);
89 return logger.isEnabled(Level.TRACE, markerFactory.getLog4jMarker(marker), null);
8990 }
9091
9192 @Override
9293 public void trace(final Marker marker, final String s) {
93 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s);
94 logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s);
9495 }
9596
9697 @Override
9798 public void trace(final Marker marker, final String s, final Object o) {
98 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o);
99 logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s, o);
99100 }
100101
101102 @Override
102103 public void trace(final Marker marker, final String s, final Object o, final Object o1) {
103 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o, o1);
104 logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s, o, o1);
104105 }
105106
106107 @Override
107108 public void trace(final Marker marker, final String s, final Object... objects) {
108 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, objects);
109 logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s, objects);
109110 }
110111
111112 @Override
112113 public void trace(final Marker marker, final String s, final Throwable throwable) {
113 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, throwable);
114 logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s, throwable);
114115 }
115116
116117 @Override
145146
146147 @Override
147148 public boolean isDebugEnabled(final Marker marker) {
148 return logger.isEnabled(Level.DEBUG, getMarker(marker), null);
149 return logger.isEnabled(Level.DEBUG, markerFactory.getLog4jMarker(marker), null);
149150 }
150151
151152 @Override
152153 public void debug(final Marker marker, final String s) {
153 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s);
154 logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s);
154155 }
155156
156157 @Override
157158 public void debug(final Marker marker, final String s, final Object o) {
158 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o);
159 logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s, o);
159160 }
160161
161162 @Override
162163 public void debug(final Marker marker, final String s, final Object o, final Object o1) {
163 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o, o1);
164 logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s, o, o1);
164165 }
165166
166167 @Override
167168 public void debug(final Marker marker, final String s, final Object... objects) {
168 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, objects);
169 logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s, objects);
169170 }
170171
171172 @Override
172173 public void debug(final Marker marker, final String s, final Throwable throwable) {
173 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, throwable);
174 logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s, throwable);
174175 }
175176
176177 @Override
205206
206207 @Override
207208 public boolean isInfoEnabled(final Marker marker) {
208 return logger.isEnabled(Level.INFO, getMarker(marker), null);
209 return logger.isEnabled(Level.INFO, markerFactory.getLog4jMarker(marker), null);
209210 }
210211
211212 @Override
212213 public void info(final Marker marker, final String s) {
213 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s);
214 logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s);
214215 }
215216
216217 @Override
217218 public void info(final Marker marker, final String s, final Object o) {
218 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o);
219 logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s, o);
219220 }
220221
221222 @Override
222223 public void info(final Marker marker, final String s, final Object o, final Object o1) {
223 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o, o1);
224 logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s, o, o1);
224225 }
225226
226227 @Override
227228 public void info(final Marker marker, final String s, final Object... objects) {
228 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, objects);
229 logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s, objects);
229230 }
230231
231232 @Override
232233 public void info(final Marker marker, final String s, final Throwable throwable) {
233 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, throwable);
234 logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s, throwable);
234235 }
235236
236237 @Override
265266
266267 @Override
267268 public boolean isWarnEnabled(final Marker marker) {
268 return logger.isEnabled(Level.WARN, getMarker(marker), null);
269 return logger.isEnabled(Level.WARN, markerFactory.getLog4jMarker(marker), null);
269270 }
270271
271272 @Override
272273 public void warn(final Marker marker, final String s) {
273 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s);
274 logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s);
274275 }
275276
276277 @Override
277278 public void warn(final Marker marker, final String s, final Object o) {
278 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o);
279 logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s, o);
279280 }
280281
281282 @Override
282283 public void warn(final Marker marker, final String s, final Object o, final Object o1) {
283 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o, o1);
284 logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s, o, o1);
284285 }
285286
286287 @Override
287288 public void warn(final Marker marker, final String s, final Object... objects) {
288 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, objects);
289 logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s, objects);
289290 }
290291
291292 @Override
292293 public void warn(final Marker marker, final String s, final Throwable throwable) {
293 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, throwable);
294 logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s, throwable);
294295 }
295296
296297 @Override
325326
326327 @Override
327328 public boolean isErrorEnabled(final Marker marker) {
328 return logger.isEnabled(Level.ERROR, getMarker(marker), null);
329 return logger.isEnabled(Level.ERROR, markerFactory.getLog4jMarker(marker), null);
329330 }
330331
331332 @Override
332333 public void error(final Marker marker, final String s) {
333 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s);
334 logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s);
334335 }
335336
336337 @Override
337338 public void error(final Marker marker, final String s, final Object o) {
338 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o);
339 logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s, o);
339340 }
340341
341342 @Override
342343 public void error(final Marker marker, final String s, final Object o, final Object o1) {
343 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o, o1);
344 logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s, o, o1);
344345 }
345346
346347 @Override
347348 public void error(final Marker marker, final String s, final Object... objects) {
348 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, objects);
349 logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s, objects);
349350 }
350351
351352 @Override
352353 public void error(final Marker marker, final String s, final Throwable throwable) {
353 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, throwable);
354 }
355
356 @Override
357 public void log(final Marker marker, final String fqcn, final int level, final String message, final Object[] params, Throwable throwable) {
354 logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s, throwable);
355 }
356
357 @Override
358 public void log(final Marker marker, final String fqcn, final int level, final String message, final Object[] params, final Throwable throwable) {
358359 final Level log4jLevel = getLevel(level);
359 final org.apache.logging.log4j.Marker log4jMarker = getMarker(marker);
360 final org.apache.logging.log4j.Marker log4jMarker = markerFactory.getLog4jMarker(marker);
360361
361362 if (!logger.isEnabled(log4jLevel, log4jMarker, message, params)) {
362363 return;
363364 }
364365 final Message msg;
366 final Throwable actualThrowable;
365367 if (CONVERTER != null && eventLogger && marker != null && marker.contains(EVENT_MARKER)) {
366368 msg = CONVERTER.convertEvent(message, params, throwable);
369 actualThrowable = throwable != null ? throwable : msg.getThrowable();
367370 } else if (params == null) {
368371 msg = new SimpleMessage(message);
372 actualThrowable = throwable;
369373 } else {
370374 msg = new ParameterizedMessage(message, params, throwable);
371 if (throwable != null) {
372 throwable = msg.getThrowable();
373 }
375 actualThrowable = throwable != null ? throwable : msg.getThrowable();
374376 }
375 logger.logMessage(fqcn, log4jLevel, log4jMarker, msg, throwable);
376 }
377
378 private static org.apache.logging.log4j.Marker getMarker(final Marker marker) {
379 if (marker == null) {
380 return null;
381 } else if (marker instanceof Log4jMarker) {
382 return ((Log4jMarker) marker).getLog4jMarker();
383 } else {
384 final Log4jMarkerFactory factory = (Log4jMarkerFactory) StaticMarkerBinder.SINGLETON.getMarkerFactory();
385 return ((Log4jMarker) factory.getMarker(marker)).getLog4jMarker();
386 }
377 logger.logMessage(fqcn, log4jLevel, log4jMarker, msg, actualThrowable);
387378 }
388379
389380 @Override
399390 // always perform the default de-serialization first
400391 aInputStream.defaultReadObject();
401392 logger = LogManager.getContext().getLogger(name);
393 markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory();
402394 }
403395
404396 /**
3333
3434 private static final StatusLogger LOGGER = StatusLogger.getLogger();
3535 private static final String SLF4J_PACKAGE = "org.slf4j";
36 private static final String TO_SLF4J_CONTEXT = "org.apache.logging.slf4j.SLF4JLoggerContext";
3736 private static final Predicate<Class<?>> CALLER_PREDICATE = clazz ->
3837 !AbstractLoggerAdapter.class.equals(clazz) && !clazz.getName().startsWith(SLF4J_PACKAGE);
38 private static final String TO_SLF4J_CONTEXT = "org.apache.logging.slf4j.SLF4JLoggerContext";
39
40 private final Log4jMarkerFactory markerFactory;
41
42 public Log4jLoggerFactory(final Log4jMarkerFactory markerFactory) {
43 this.markerFactory = markerFactory;
44 }
3945
4046 @Override
4147 protected Logger newLogger(final String name, final LoggerContext context) {
4248 final String key = Logger.ROOT_LOGGER_NAME.equals(name) ? LogManager.ROOT_LOGGER_NAME : name;
43 return new Log4jLogger(validateContext(context).getLogger(key), name);
49 return new Log4jLogger(markerFactory, validateContext(context).getLogger(key), name);
4450 }
4551
4652 @Override
5460 : getContext(anchor);
5561 }
5662
63 Log4jMarkerFactory getMarkerFactory() {
64 return markerFactory;
65 }
66
5767 private LoggerContext validateContext(final LoggerContext context) {
5868 if (TO_SLF4J_CONTEXT.equals(context.getClass().getName())) {
5969 throw new LoggingException("log4j-slf4j-impl cannot be present with log4j-to-slf4j");
5151 }
5252
5353 @Override
54 @SuppressWarnings("unchecked") // nothing we can do about this, restricted by SLF4J API
55 public void setContextMap(@SuppressWarnings("rawtypes") final Map map) {
54 public void setContextMap(final Map<String, String> map) {
5655 ThreadContext.clearMap();
5756 ThreadContext.putAll(map);
5857 }
2323 import org.apache.logging.log4j.MarkerManager;
2424 import org.slf4j.IMarkerFactory;
2525 import org.slf4j.Marker;
26 import org.slf4j.impl.StaticMarkerBinder;
2726
2827 /**
29 * Log4j/SLF4J {@link org.slf4j.Marker} type bridge.
28 * Log4j/SLF4J {@link Marker} type bridge.
3029 */
31 public class Log4jMarker implements Marker {
30 class Log4jMarker implements Marker {
3231
3332 public static final long serialVersionUID = 1590472L;
3433
35 private final IMarkerFactory factory = StaticMarkerBinder.SINGLETON.getMarkerFactory();
34 private final IMarkerFactory factory;
3635
3736 private final org.apache.logging.log4j.Marker marker;
3837
4039 * Constructs a Log4jMarker using an existing Log4j {@link org.apache.logging.log4j.Marker}.
4140 * @param marker The Log4j Marker upon which to base this Marker.
4241 */
43 public Log4jMarker(final org.apache.logging.log4j.Marker marker) {
42 public Log4jMarker(final IMarkerFactory markerFactory, final org.apache.logging.log4j.Marker marker) {
43 this.factory = markerFactory;
4444 this.marker = marker;
4545 }
4646
5454 }
5555
5656 @Override
57 public boolean contains(final org.slf4j.Marker marker) {
57 public boolean contains(final Marker marker) {
5858 if (marker == null) {
5959 throw new IllegalArgumentException();
6060 }
5555 }
5656
5757 private Marker addMarkerIfAbsent(final String name, final org.apache.logging.log4j.Marker log4jMarker) {
58 final Marker marker = new Log4jMarker(log4jMarker);
58 final Marker marker = new Log4jMarker(this, log4jMarker);
5959 final Marker existing = markerMap.putIfAbsent(name, marker);
6060 return existing == null ? marker : existing;
6161 }
7777 return addMarkerIfAbsent(marker.getName(), convertMarker(marker));
7878 }
7979
80 private static org.apache.logging.log4j.Marker convertMarker(final Marker original) {
80 /**
81 * Gets the Log4j2 marker associated to this SLF4J marker or creates a new one.
82 *
83 * @param marker a SLF4J marker
84 * @return a Log4j2 marker
85 */
86 org.apache.logging.log4j.Marker getLog4jMarker(final Marker marker) {
87 if (marker == null) {
88 return null;
89 } else if (marker instanceof Log4jMarker) {
90 return ((Log4jMarker) marker).getLog4jMarker();
91 } else {
92 return ((Log4jMarker) getMarker(marker)).getLog4jMarker();
93 }
94 }
95
96 static org.apache.logging.log4j.Marker convertMarker(final Marker original) {
8197 if (original == null) {
8298 throw new IllegalArgumentException("Marker must not be null");
8399 }
1616 package org.slf4j.impl;
1717
1818 import org.apache.logging.slf4j.Log4jLoggerFactory;
19 import org.apache.logging.slf4j.Log4jMarkerFactory;
1920 import org.slf4j.ILoggerFactory;
2021 import org.slf4j.spi.LoggerFactoryBinder;
2122
4950 * Private constructor to prevent instantiation
5051 */
5152 private StaticLoggerBinder() {
52 loggerFactory = new Log4jLoggerFactory();
53 loggerFactory = new Log4jLoggerFactory((Log4jMarkerFactory) StaticMarkerBinder.getSingleton().getMarkerFactory());
5354 }
5455
5556 /**
2828 */
2929 public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
3030
31 private final MDCAdapter mdcAdapter = new Log4jMDCAdapter();
32
3133 private StaticMDCBinder() {
3234 }
3335
4547 * @return an MDC adapter
4648 */
4749 public MDCAdapter getMDCA() {
48 return new Log4jMDCAdapter();
50 return mdcAdapter;
4951 }
5052
5153 /**
2020 The Log4j 2 SLF4J Binding allows applications coded to the SLF4J API to use
2121 Log4j 2 as the implementation.
2222
23 Due to a break in compatibility in the SLF4J binding, as of release 2.11.1 two SLF4J to Log4j Adapters are provided.
23 Due to a break in compatibility in the SLF4J binding, as of release 2.19.0 two SLF4J to Log4j Adapters are provided.
2424
25 1. log4j-slf4j-impl should be used with SLF4J 1.7.x releases or older.
26 1. log4j-slf4j18-impl should be used with SLF4J 1.8.x releases or newer.
25 1. `log4j-slf4j-impl` should be used with SLF4J 1.7.x releases or older.
26 1. `log4j-slf4j2-impl` should be used with SLF4J 2.0.x releases or newer.
2727
28 Applications that take advantage of the Java Module System should use SLF4J 1.8.x and log4j-slf4j18-impl.
28 Applications that take advantage of the Java Module System should use SLF4J 2.0.x and log4j-slf4j2-impl.
29
30 As of release 2.19.0 the `log4j-slf4j18-impl` module targetting the unreleased SLF4J 1.8.x series has been removed.
2931
3032 ## Requirements
3133
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import static org.junit.Assert.assertEquals;
19
20 import java.util.List;
21
22 import org.apache.logging.log4j.junit.LoggerContextRule;
23 import org.apache.logging.log4j.test.appender.ListAppender;
24 import org.junit.ClassRule;
25 import org.junit.Test;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 public class CallerInformationTest {
30
31 // config from log4j-core test-jar
32 private static final String CONFIG = "log4j2-calling-class.xml";
33
34 @ClassRule
35 public static final LoggerContextRule ctx = new LoggerContextRule(CONFIG);
36
37 @Test
38 public void testClassLogger() throws Exception {
39 final ListAppender app = ctx.getListAppender("Class").clear();
40 final Logger logger = LoggerFactory.getLogger("ClassLogger");
41 logger.info("Ignored message contents.");
42 logger.warn("Verifying the caller class is still correct.");
43 logger.error("Hopefully nobody breaks me!");
44 final List<String> messages = app.getMessages();
45 assertEquals("Incorrect number of messages.", 3, messages.size());
46 for (final String message : messages) {
47 assertEquals("Incorrect caller class name.", this.getClass().getName(), message);
48 }
49 }
50
51 @Test
52 public void testMethodLogger() throws Exception {
53 final ListAppender app = ctx.getListAppender("Method").clear();
54 final Logger logger = LoggerFactory.getLogger("MethodLogger");
55 logger.info("More messages.");
56 logger.warn("CATASTROPHE INCOMING!");
57 logger.error("ZOMBIES!!!");
58 logger.warn("brains~~~");
59 logger.info("Itchy. Tasty.");
60 final List<String> messages = app.getMessages();
61 assertEquals("Incorrect number of messages.", 5, messages.size());
62 for (final String message : messages) {
63 assertEquals("Incorrect caller method name.", "testMethodLogger", message);
64 }
65 }
66 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import static org.junit.Assert.assertEquals;
19
20 import java.util.List;
21
22 import org.apache.logging.log4j.junit.LoggerContextRule;
23 import org.apache.logging.log4j.test.appender.ListAppender;
24 import org.junit.ClassRule;
25 import org.junit.Test;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 public class CallerInformationTest {
30
31 // config from log4j-core test-jar
32 private static final String CONFIG = "log4j2-calling-class.xml";
33
34 @ClassRule
35 public static final LoggerContextRule ctx = new LoggerContextRule(CONFIG);
36
37 @Test
38 public void testClassLogger() throws Exception {
39 final ListAppender app = ctx.getListAppender("Class").clear();
40 final Logger logger = LoggerFactory.getLogger("ClassLogger");
41 logger.info("Ignored message contents.");
42 logger.warn("Verifying the caller class is still correct.");
43 logger.error("Hopefully nobody breaks me!");
44 final List<String> messages = app.getMessages();
45 assertEquals("Incorrect number of messages.", 3, messages.size());
46 for (final String message : messages) {
47 assertEquals("Incorrect caller class name.", this.getClass().getName(), message);
48 }
49 }
50
51 @Test
52 public void testMethodLogger() throws Exception {
53 final ListAppender app = ctx.getListAppender("Method").clear();
54 final Logger logger = LoggerFactory.getLogger("MethodLogger");
55 logger.info("More messages.");
56 logger.warn("CATASTROPHE INCOMING!");
57 logger.error("ZOMBIES!!!");
58 logger.warn("brains~~~");
59 logger.info("Itchy. Tasty.");
60 final List<String> messages = app.getMessages();
61 assertEquals("Incorrect number of messages.", 5, messages.size());
62 for (final String message : messages) {
63 assertEquals("Incorrect caller method name.", "testMethodLogger", message);
64 }
65 }
66 }
1818 import org.apache.logging.log4j.Marker;
1919 import org.apache.logging.log4j.MarkerManager;
2020 import org.junit.Assert;
21 import org.junit.BeforeClass;
2122 import org.junit.Test;
2223
2324 public class Log4jMarkerTest {
25
26 private static Log4jMarkerFactory markerFactory;
27
28 @BeforeClass
29 public static void startup() {
30 markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory();
31
32 }
2433
2534 @Test
2635 public void testEquals() {
2736 final Marker markerA = MarkerManager.getMarker(Log4jMarkerTest.class.getName() + "-A");
2837 final Marker markerB = MarkerManager.getMarker(Log4jMarkerTest.class.getName() + "-B");
29 final Log4jMarker marker1 = new Log4jMarker(markerA);
30 final Log4jMarker marker2 = new Log4jMarker(markerA);
31 final Log4jMarker marker3 = new Log4jMarker(markerB);
38 final Log4jMarker marker1 = new Log4jMarker(markerFactory, markerA);
39 final Log4jMarker marker2 = new Log4jMarker(markerFactory, markerA);
40 final Log4jMarker marker3 = new Log4jMarker(markerFactory, markerB);
3241 Assert.assertEquals(marker1, marker2);
3342 Assert.assertNotEquals(marker1, null);
3443 Assert.assertNotEquals(null, marker1);
1818 import org.apache.logging.log4j.core.LifeCycle;
1919 import org.apache.logging.log4j.spi.LoggerContext;
2020 import org.junit.Test;
21 import org.slf4j.impl.StaticLoggerBinder;
21 import org.slf4j.LoggerFactory;
2222
2323 import java.util.Set;
2424
25 import static org.junit.Assert.*;
25 import static org.junit.Assert.assertTrue;
2626
2727 /**
2828 * Tests cleanup of the LoggerContexts.
3131
3232 @Test
3333 public void testCleanup() throws Exception {
34 Log4jLoggerFactory factory = (Log4jLoggerFactory) StaticLoggerBinder.getSingleton().getLoggerFactory();
34 Log4jLoggerFactory factory = (Log4jLoggerFactory) LoggerFactory.getILoggerFactory();
3535 factory.getLogger("test");
3636 Set<LoggerContext> set = factory.getLoggerContexts();
3737 LoggerContext ctx1 = set.toArray(LoggerContext.EMPTY_ARRAY)[0];
2222 import java.util.List;
2323 import java.util.Locale;
2424
25 import org.apache.logging.log4j.core.LogEvent;
2526 import org.apache.logging.log4j.junit.LoggerContextRule;
2627 import org.apache.logging.log4j.test.appender.ListAppender;
2728 import org.apache.logging.log4j.util.Strings;
161162 verify("EventLogger", "o.a.l.s.LoggerTest Transfer [Audit@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"] Transfer Complete" + Strings.LINE_SEPARATOR);
162163 }
163164
164 private void verify(final String name, final String expected) {
165 @Test
166 public void testThrowable() {
167 final Throwable expected = new RuntimeException();
168 logger.debug("Hello {}", expected);
169 verifyThrowable(expected);
170 logger.debug("Hello {}", (Object) expected);
171 verifyThrowable(null);
172 logger.debug("Hello", expected);
173 verifyThrowable(expected);
174 logger.debug("Hello {}! {}", "World!", expected);
175 verifyThrowable(null);
176 logger.debug("Hello {}!", "World!", expected);
177 verifyThrowable(expected);
178 final LocationAwareLogger lal = (LocationAwareLogger) logger;
179 lal.log(null, LoggerTest.class.getName(), LocationAwareLogger.DEBUG_INT, "Hello {}", null, expected);
180 verifyThrowable(expected);
181 lal.log(null, LoggerTest.class.getName(), LocationAwareLogger.DEBUG_INT, "Hello {}", new Object[] { expected },
182 null);
183 verifyThrowable(null);
184 lal.log(null, LoggerTest.class.getName(), LocationAwareLogger.DEBUG_INT, "Hello {}",
185 new Object[] { "World!", expected }, null);
186 verifyThrowable(expected);
187 }
188
189 private ListAppender getAppenderByName(final String name) {
165190 final ListAppender listApp = ctx.getListAppender(name);
166191 assertNotNull("Missing Appender", listApp);
192 return listApp;
193 }
194
195 private void verify(final String name, final String expected) {
196 final ListAppender listApp = getAppenderByName(name);
167197 final List<String> events = listApp.getMessages();
168198 assertTrue("Incorrect number of messages. Expected 1 Actual " + events.size(), events.size()== 1);
169199 final String actual = events.get(0);
171201 listApp.clear();
172202 }
173203
204 private void verifyThrowable(final Throwable expected) {
205 final ListAppender listApp = getAppenderByName("UnformattedList");
206 final List<LogEvent> events = listApp.getEvents();
207 assertEquals("Incorrect number of messages", 1, events.size());
208 final LogEvent actual = events.get(0);
209 assertEquals("Incorrect throwable.", expected, actual.getThrown());
210 listApp.clear();
211 }
212
174213 @Before
175214 @After
176215 public void cleanup() {
177216 MDC.clear();
178217 ctx.getListAppender("List").clear();
218 ctx.getListAppender("UnformattedList").clear();
179219 ctx.getListAppender("EventLogger").clear();
180220 }
181221 }
2020 import org.junit.After;
2121 import org.junit.Assert;
2222 import org.junit.Before;
23 import org.junit.BeforeClass;
2324 import org.junit.Test;
2425
2526 import static org.junit.Assert.*;
3132
3233 private static final String CHILD_MAKER_NAME = MarkerTest.class.getSimpleName() + "-TEST";
3334 private static final String PARENT_MARKER_NAME = MarkerTest.class.getSimpleName() + "-PARENT";
35 private static Log4jMarkerFactory markerFactory;
3436
35 @Before
37 @BeforeClass
38 public static void startup() {
39 markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory();
40
41 }
42
43 @Before
3644 @After
3745 public void clearMarkers() {
3846 MarkerManager.clear();
6472 slf4jMarker.add(slf4jParent);
6573 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
6674 final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
67 final Log4jMarker log4jSlf4jParent = new Log4jMarker(log4jParent);
68 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(log4jMarker);
75 final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
76 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
6977 final org.slf4j.Marker nullMarker = null;
7078 try {
7179 log4jSlf4jParent.add(nullMarker);
125133 slf4jMarker.add(slf4jParent);
126134 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
127135 final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
128 final Log4jMarker log4jSlf4jParent = new Log4jMarker(log4jParent);
129 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(log4jMarker);
136 final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
137 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
130138 final org.slf4j.Marker nullMarker = null;
131139 try {
132140 Assert.assertFalse(log4jSlf4jParent.contains(nullMarker));
151159 slf4jMarker.add(slf4jParent);
152160 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
153161 final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
154 final Log4jMarker log4jSlf4jParent = new Log4jMarker(log4jParent);
155 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(log4jMarker);
162 final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
163 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
156164 final String nullStr = null;
157165 Assert.assertFalse(log4jSlf4jParent.contains(nullStr));
158166 Assert.assertFalse(log4jSlf4jMarker.contains(nullStr));
167175 slf4jMarker.add(slf4jParent);
168176 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
169177 final Marker log4jMarker = MarkerManager.getMarker(childMakerName);
170 final Log4jMarker log4jSlf4jParent = new Log4jMarker(log4jParent);
171 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(log4jMarker);
178 final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
179 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
172180 final org.slf4j.Marker nullMarker = null;
173181 Assert.assertFalse(log4jSlf4jParent.remove(nullMarker));
174182 Assert.assertFalse(log4jSlf4jMarker.remove(nullMarker));
1515 */
1616 package org.apache.logging.slf4j;
1717
18 import static org.junit.Assert.fail;
19
1820 import org.apache.logging.log4j.LoggingException;
1921 import org.junit.Test;
20 import org.slf4j.Logger;
2122 import org.slf4j.LoggerFactory;
22
23 import static org.junit.Assert.fail;
2423
2524 /**
2625 * Tests StackOverflow when slf4j-impl and to-slf4j are both present.
3029 @Test
3130 public void log() {
3231 try {
33 final Logger logger = LoggerFactory.getLogger(OverflowTest.class);
32 LoggerFactory.getLogger(OverflowTest.class);
3433 fail("Failed to detect inclusion of log4j-to-slf4j");
3534 } catch (LoggingException ex) {
3635 // Expected exception.
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import java.io.Serializable;
19
20 import org.apache.logging.log4j.junit.LoggerContextRule;
21 import org.junit.ClassRule;
22 import org.junit.Test;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 import static org.apache.logging.log4j.SerializableMatchers.serializesRoundTrip;
27 import static org.junit.Assert.*;
28
29 /**
30 *
31 */
32 public class SerializeTest {
33
34 private static final String CONFIG = "log4j-test1.xml";
35
36 @ClassRule
37 public static final LoggerContextRule CTX = new LoggerContextRule(CONFIG);
38
39 Logger logger = LoggerFactory.getLogger("LoggerTest");
40
41 @Test
42 public void testLogger() throws Exception {
43 assertThat((Serializable) logger, serializesRoundTrip());
44 }
45 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import static org.apache.logging.log4j.SerializableMatchers.serializesRoundTrip;
19 import static org.hamcrest.MatcherAssert.assertThat;
20
21 import java.io.Serializable;
22
23 import org.apache.logging.log4j.junit.LoggerContextRule;
24 import org.junit.ClassRule;
25 import org.junit.Test;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30 *
31 */
32 public class SerializeTest {
33
34 private static final String CONFIG = "log4j-test1.xml";
35
36 @ClassRule
37 public static final LoggerContextRule CTX = new LoggerContextRule(CONFIG);
38
39 Logger logger = LoggerFactory.getLogger("LoggerTest");
40
41 @Test
42 public void testLogger() throws Exception {
43 assertThat((Serializable) logger, serializesRoundTrip());
44 }
45 }
1919 <List name="List">
2020 <PatternLayout pattern="%C{1.} %m MDC%X%n%ex{0}"/>
2121 </List>
22 <List name="UnformattedList" />
2223 <SLF4J name="SLF4J"/>
2324 </Appenders>
2425
3334
3435 <Root level="trace">
3536 <AppenderRef ref="List"/>
37 <AppenderRef ref="UnformattedList"/>
3638 </Root>
3739 </Loggers>
3840
+0
-255
log4j-slf4j18-impl/pom.xml less more
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!--
2 Licensed to the Apache Software Foundation (ASF) under one or more
3 contributor license agreements. See the NOTICE file distributed with
4 this work for additional information regarding copyright ownership.
5 The ASF licenses this file to You under the Apache License, Version 2.0
6 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 -->
17 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
18 <modelVersion>4.0.0</modelVersion>
19 <parent>
20 <groupId>org.apache.logging.log4j</groupId>
21 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
23 </parent>
24 <artifactId>log4j-slf4j18-impl</artifactId>
25 <packaging>jar</packaging>
26 <name>Apache Log4j SLF4J 1.8+ Binding</name>
27 <description>The Apache Log4j SLF4J 1.8 API binding to Log4j 2 Core</description>
28 <properties>
29 <log4jParentDir>${basedir}/..</log4jParentDir>
30 <docLabel>SLF4J Documentation</docLabel>
31 <projectDir>/slf4j18</projectDir>
32 <slf4j.version>1.8.0-beta4</slf4j.version>
33 <module.name>org.apache.logging.log4j.slf4j</module.name>
34 <maven.doap.skip>true</maven.doap.skip>
35 </properties>
36 <dependencies>
37 <dependency>
38 <groupId>org.slf4j</groupId>
39 <artifactId>slf4j-api</artifactId>
40 <version>${slf4j.version}</version>
41 </dependency>
42 <dependency>
43 <groupId>org.slf4j</groupId>
44 <artifactId>slf4j-ext</artifactId>
45 <version>${slf4j.version}</version>
46 <optional>true</optional>
47 </dependency>
48 <dependency>
49 <groupId>org.apache.logging.log4j</groupId>
50 <artifactId>log4j-api</artifactId>
51 </dependency>
52 <dependency>
53 <groupId>org.apache.logging.log4j</groupId>
54 <artifactId>log4j-core</artifactId>
55 <scope>runtime</scope>
56 </dependency>
57 <dependency>
58 <groupId>org.apache.logging.log4j</groupId>
59 <artifactId>log4j-api</artifactId>
60 <type>test-jar</type>
61 <scope>test</scope>
62 </dependency>
63 <dependency>
64 <groupId>org.apache.commons</groupId>
65 <artifactId>commons-lang3</artifactId>
66 <scope>test</scope>
67 </dependency>
68 <dependency>
69 <groupId>org.apache.commons</groupId>
70 <artifactId>commons-csv</artifactId>
71 <scope>test</scope>
72 </dependency>
73 <dependency>
74 <groupId>org.apache.logging.log4j</groupId>
75 <artifactId>log4j-core</artifactId>
76 <type>test-jar</type>
77 <scope>test</scope>
78 </dependency>
79 <dependency>
80 <groupId>org.apache.logging.log4j</groupId>
81 <artifactId>log4j-to-slf4j</artifactId>
82 <scope>test</scope>
83 <version>${project.version}</version>
84 </dependency>
85 <dependency>
86 <groupId>org.junit.vintage</groupId>
87 <artifactId>junit-vintage-engine</artifactId>
88 </dependency>
89 <dependency>
90 <groupId>org.junit.jupiter</groupId>
91 <artifactId>junit-jupiter-engine</artifactId>
92 </dependency>
93 </dependencies>
94 <build>
95 <plugins>
96 <!-- Include the standard NOTICE and LICENSE -->
97 <plugin>
98 <groupId>org.apache.maven.plugins</groupId>
99 <artifactId>maven-remote-resources-plugin</artifactId>
100 <executions>
101 <execution>
102 <goals>
103 <goal>process</goal>
104 </goals>
105 <configuration>
106 <skip>false</skip>
107 </configuration>
108 </execution>
109 </executions>
110 </plugin>
111 <plugin>
112 <groupId>org.apache.maven.plugins</groupId>
113 <artifactId>maven-surefire-plugin</artifactId>
114 <executions>
115 <execution>
116 <id>loop-test</id>
117 <phase>test</phase>
118 <goals>
119 <goal>test</goal>
120 </goals>
121 <configuration>
122 <includes>
123 <include>**/OverflowTest.java</include>
124 </includes>
125 </configuration>
126 </execution>
127 <execution>
128 <id>default-test</id>
129 <phase>test</phase>
130 <goals>
131 <goal>test</goal>
132 </goals>
133 <configuration>
134 <includes>
135 <include>**/*Test.java</include>
136 </includes>
137 <excludes>
138 <exclude>**/OverflowTest.java</exclude>
139 </excludes>
140 <classpathDependencyExcludes>
141 <classpathDependencyExcludes>org.apache.logging.log4j:log4j-to-slf4j</classpathDependencyExcludes>
142 </classpathDependencyExcludes>
143 </configuration>
144 </execution>
145 </executions>
146 </plugin>
147 <plugin>
148 <groupId>org.apache.felix</groupId>
149 <artifactId>maven-bundle-plugin</artifactId>
150 <configuration>
151 <instructions>
152 <Export-Package>
153 org.apache.logging.slf4j,
154 org.slf4j.impl
155 </Export-Package>
156 <Require-Capability>
157 osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)"
158 </Require-Capability>
159 <Provide-Capability>
160 osgi.serviceloader;osgi.serviceloader=org.slf4j.spi.SLF4JServiceProvider
161 </Provide-Capability>
162 </instructions>
163 </configuration>
164 </plugin>
165 </plugins>
166 </build>
167 <reporting>
168 <plugins>
169 <plugin>
170 <groupId>org.apache.maven.plugins</groupId>
171 <artifactId>maven-changes-plugin</artifactId>
172 <version>${changes.plugin.version}</version>
173 <reportSets>
174 <reportSet>
175 <reports>
176 <report>changes-report</report>
177 </reports>
178 </reportSet>
179 </reportSets>
180 <configuration>
181 <issueLinkTemplate>%URL%/show_bug.cgi?id=%ISSUE%</issueLinkTemplate>
182 <useJql>true</useJql>
183 </configuration>
184 </plugin>
185 <plugin>
186 <groupId>org.apache.maven.plugins</groupId>
187 <artifactId>maven-checkstyle-plugin</artifactId>
188 <version>${checkstyle.plugin.version}</version>
189 <configuration>
190 <!--<propertiesLocation>${vfs.parent.dir}/checkstyle.properties</propertiesLocation> -->
191 <configLocation>${log4jParentDir}/checkstyle.xml</configLocation>
192 <suppressionsLocation>${log4jParentDir}/checkstyle-suppressions.xml</suppressionsLocation>
193 <enableRulesSummary>false</enableRulesSummary>
194 <propertyExpansion>basedir=${basedir}</propertyExpansion>
195 <propertyExpansion>licensedir=${log4jParentDir}/checkstyle-header.txt</propertyExpansion>
196 </configuration>
197 </plugin>
198 <plugin>
199 <groupId>org.apache.maven.plugins</groupId>
200 <artifactId>maven-javadoc-plugin</artifactId>
201 <version>${javadoc.plugin.version}</version>
202 <configuration>
203 <bottom><![CDATA[<p align="center">Copyright &#169; {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br />
204 Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo,
205 and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom>
206 <!-- module link generation is completely broken in the javadoc plugin for a multi-module non-aggregating
207 project -->
208 <detectOfflineLinks>false</detectOfflineLinks>
209 <linksource>true</linksource>
210 </configuration>
211 <reportSets>
212 <reportSet>
213 <id>non-aggregate</id>
214 <reports>
215 <report>javadoc</report>
216 </reports>
217 </reportSet>
218 </reportSets>
219 </plugin>
220 <plugin>
221 <groupId>com.github.spotbugs</groupId>
222 <artifactId>spotbugs-maven-plugin</artifactId>
223 </plugin>
224 <plugin>
225 <groupId>org.apache.maven.plugins</groupId>
226 <artifactId>maven-jxr-plugin</artifactId>
227 <version>${jxr.plugin.version}</version>
228 <reportSets>
229 <reportSet>
230 <id>non-aggregate</id>
231 <reports>
232 <report>jxr</report>
233 </reports>
234 </reportSet>
235 <reportSet>
236 <id>aggregate</id>
237 <reports>
238 <report>aggregate</report>
239 </reports>
240 </reportSet>
241 </reportSets>
242 </plugin>
243 <plugin>
244 <groupId>org.apache.maven.plugins</groupId>
245 <artifactId>maven-pmd-plugin</artifactId>
246 <version>${pmd.plugin.version}</version>
247 <configuration>
248 <targetJdk>${maven.compiler.target}</targetJdk>
249 </configuration>
250 </plugin>
251 </plugins>
252 </reporting>
253 </project>
254
+0
-420
log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jLogger.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import java.io.IOException;
19 import java.io.ObjectInputStream;
20 import java.io.ObjectOutputStream;
21 import java.io.Serializable;
22
23 import org.apache.logging.log4j.Level;
24 import org.apache.logging.log4j.LogManager;
25 import org.apache.logging.log4j.message.Message;
26 import org.apache.logging.log4j.message.ParameterizedMessage;
27 import org.apache.logging.log4j.message.SimpleMessage;
28 import org.apache.logging.log4j.spi.ExtendedLogger;
29 import org.slf4j.Marker;
30 import org.slf4j.spi.LocationAwareLogger;
31
32 /**
33 * SLF4J logger implementation that uses Log4j.
34 */
35 public class Log4jLogger implements LocationAwareLogger, Serializable {
36
37 public static final String FQCN = Log4jLogger.class.getName();
38
39 private static final long serialVersionUID = 7869000638091304316L;
40 private transient ExtendedLogger logger;
41 private final String name;
42 private transient Log4jMarkerFactory markerFactory;
43
44 public Log4jLogger(final Log4jMarkerFactory markerFactory, final ExtendedLogger logger, final String name) {
45 this.markerFactory = markerFactory;
46 this.logger = logger;
47 this.name = name;
48 }
49
50 @Override
51 public void trace(final String format) {
52 logger.logIfEnabled(FQCN, Level.TRACE, null, format);
53 }
54
55 @Override
56 public void trace(final String format, final Object o) {
57 logger.logIfEnabled(FQCN, Level.TRACE, null, format, o);
58 }
59
60 @Override
61 public void trace(final String format, final Object arg1, final Object arg2) {
62 logger.logIfEnabled(FQCN, Level.TRACE, null, format, arg1, arg2);
63 }
64
65 @Override
66 public void trace(final String format, final Object... args) {
67 logger.logIfEnabled(FQCN, Level.TRACE, null, format, args);
68 }
69
70 @Override
71 public void trace(final String format, final Throwable t) {
72 logger.logIfEnabled(FQCN, Level.TRACE, null, format, t);
73 }
74
75 @Override
76 public boolean isTraceEnabled() {
77 return logger.isEnabled(Level.TRACE, null, null);
78 }
79
80 @Override
81 public boolean isTraceEnabled(final Marker marker) {
82 return logger.isEnabled(Level.TRACE, getMarker(marker), null);
83 }
84
85 @Override
86 public void trace(final Marker marker, final String s) {
87 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s);
88 }
89
90 @Override
91 public void trace(final Marker marker, final String s, final Object o) {
92 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o);
93 }
94
95 @Override
96 public void trace(final Marker marker, final String s, final Object o, final Object o1) {
97 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o, o1);
98 }
99
100 @Override
101 public void trace(final Marker marker, final String s, final Object... objects) {
102 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, objects);
103 }
104
105 @Override
106 public void trace(final Marker marker, final String s, final Throwable throwable) {
107 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, throwable);
108 }
109
110 @Override
111 public void debug(final String format) {
112 logger.logIfEnabled(FQCN, Level.DEBUG, null, format);
113 }
114
115 @Override
116 public void debug(final String format, final Object o) {
117 logger.logIfEnabled(FQCN, Level.DEBUG, null, format, o);
118 }
119
120 @Override
121 public void debug(final String format, final Object arg1, final Object arg2) {
122 logger.logIfEnabled(FQCN, Level.DEBUG, null, format, arg1, arg2);
123 }
124
125 @Override
126 public void debug(final String format, final Object... args) {
127 logger.logIfEnabled(FQCN, Level.DEBUG, null, format, args);
128 }
129
130 @Override
131 public void debug(final String format, final Throwable t) {
132 logger.logIfEnabled(FQCN, Level.DEBUG, null, format, t);
133 }
134
135 @Override
136 public boolean isDebugEnabled() {
137 return logger.isEnabled(Level.DEBUG, null, null);
138 }
139
140 @Override
141 public boolean isDebugEnabled(final Marker marker) {
142 return logger.isEnabled(Level.DEBUG, getMarker(marker), null);
143 }
144
145 @Override
146 public void debug(final Marker marker, final String s) {
147 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s);
148 }
149
150 @Override
151 public void debug(final Marker marker, final String s, final Object o) {
152 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o);
153 }
154
155 @Override
156 public void debug(final Marker marker, final String s, final Object o, final Object o1) {
157 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o, o1);
158 }
159
160 @Override
161 public void debug(final Marker marker, final String s, final Object... objects) {
162 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, objects);
163 }
164
165 @Override
166 public void debug(final Marker marker, final String s, final Throwable throwable) {
167 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, throwable);
168 }
169
170 @Override
171 public void info(final String format) {
172 logger.logIfEnabled(FQCN, Level.INFO, null, format);
173 }
174
175 @Override
176 public void info(final String format, final Object o) {
177 logger.logIfEnabled(FQCN, Level.INFO, null, format, o);
178 }
179
180 @Override
181 public void info(final String format, final Object arg1, final Object arg2) {
182 logger.logIfEnabled(FQCN, Level.INFO, null, format, arg1, arg2);
183 }
184
185 @Override
186 public void info(final String format, final Object... args) {
187 logger.logIfEnabled(FQCN, Level.INFO, null, format, args);
188 }
189
190 @Override
191 public void info(final String format, final Throwable t) {
192 logger.logIfEnabled(FQCN, Level.INFO, null, format, t);
193 }
194
195 @Override
196 public boolean isInfoEnabled() {
197 return logger.isEnabled(Level.INFO, null, null);
198 }
199
200 @Override
201 public boolean isInfoEnabled(final Marker marker) {
202 return logger.isEnabled(Level.INFO, getMarker(marker), null);
203 }
204
205 @Override
206 public void info(final Marker marker, final String s) {
207 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s);
208 }
209
210 @Override
211 public void info(final Marker marker, final String s, final Object o) {
212 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o);
213 }
214
215 @Override
216 public void info(final Marker marker, final String s, final Object o, final Object o1) {
217 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o, o1);
218 }
219
220 @Override
221 public void info(final Marker marker, final String s, final Object... objects) {
222 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, objects);
223 }
224
225 @Override
226 public void info(final Marker marker, final String s, final Throwable throwable) {
227 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, throwable);
228 }
229
230 @Override
231 public void warn(final String format) {
232 logger.logIfEnabled(FQCN, Level.WARN, null, format);
233 }
234
235 @Override
236 public void warn(final String format, final Object o) {
237 logger.logIfEnabled(FQCN, Level.WARN, null, format, o);
238 }
239
240 @Override
241 public void warn(final String format, final Object arg1, final Object arg2) {
242 logger.logIfEnabled(FQCN, Level.WARN, null, format, arg1, arg2);
243 }
244
245 @Override
246 public void warn(final String format, final Object... args) {
247 logger.logIfEnabled(FQCN, Level.WARN, null, format, args);
248 }
249
250 @Override
251 public void warn(final String format, final Throwable t) {
252 logger.logIfEnabled(FQCN, Level.WARN, null, format, t);
253 }
254
255 @Override
256 public boolean isWarnEnabled() {
257 return logger.isEnabled(Level.WARN, null, null);
258 }
259
260 @Override
261 public boolean isWarnEnabled(final Marker marker) {
262 return logger.isEnabled(Level.WARN, getMarker(marker), null);
263 }
264
265 @Override
266 public void warn(final Marker marker, final String s) {
267 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s);
268 }
269
270 @Override
271 public void warn(final Marker marker, final String s, final Object o) {
272 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o);
273 }
274
275 @Override
276 public void warn(final Marker marker, final String s, final Object o, final Object o1) {
277 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o, o1);
278 }
279
280 @Override
281 public void warn(final Marker marker, final String s, final Object... objects) {
282 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, objects);
283 }
284
285 @Override
286 public void warn(final Marker marker, final String s, final Throwable throwable) {
287 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, throwable);
288 }
289
290 @Override
291 public void error(final String format) {
292 logger.logIfEnabled(FQCN, Level.ERROR, null, format);
293 }
294
295 @Override
296 public void error(final String format, final Object o) {
297 logger.logIfEnabled(FQCN, Level.ERROR, null, format, o);
298 }
299
300 @Override
301 public void error(final String format, final Object arg1, final Object arg2) {
302 logger.logIfEnabled(FQCN, Level.ERROR, null, format, arg1, arg2);
303 }
304
305 @Override
306 public void error(final String format, final Object... args) {
307 logger.logIfEnabled(FQCN, Level.ERROR, null, format, args);
308 }
309
310 @Override
311 public void error(final String format, final Throwable t) {
312 logger.logIfEnabled(FQCN, Level.ERROR, null, format, t);
313 }
314
315 @Override
316 public boolean isErrorEnabled() {
317 return logger.isEnabled(Level.ERROR, null, null);
318 }
319
320 @Override
321 public boolean isErrorEnabled(final Marker marker) {
322 return logger.isEnabled(Level.ERROR, getMarker(marker), null);
323 }
324
325 @Override
326 public void error(final Marker marker, final String s) {
327 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s);
328 }
329
330 @Override
331 public void error(final Marker marker, final String s, final Object o) {
332 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o);
333 }
334
335 @Override
336 public void error(final Marker marker, final String s, final Object o, final Object o1) {
337 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o, o1);
338 }
339
340 @Override
341 public void error(final Marker marker, final String s, final Object... objects) {
342 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, objects);
343 }
344
345 @Override
346 public void error(final Marker marker, final String s, final Throwable throwable) {
347 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, throwable);
348 }
349
350 @Override
351 public void log(final Marker marker, final String fqcn, final int level, final String message, final Object[] params, Throwable throwable) {
352 final Level log4jLevel = getLevel(level);
353 final org.apache.logging.log4j.Marker log4jMarker = getMarker(marker);
354
355 if (!logger.isEnabled(log4jLevel, log4jMarker, message, params)) {
356 return;
357 }
358 final Message msg;
359 if (params == null) {
360 msg = new SimpleMessage(message);
361 } else {
362 msg = new ParameterizedMessage(message, params, throwable);
363 if (throwable != null) {
364 throwable = msg.getThrowable();
365 }
366 }
367 logger.logMessage(fqcn, log4jLevel, log4jMarker, msg, throwable);
368 }
369
370 private org.apache.logging.log4j.Marker getMarker(final Marker marker) {
371 if (marker == null) {
372 return null;
373 } else if (marker instanceof Log4jMarker) {
374 return ((Log4jMarker) marker).getLog4jMarker();
375 } else {
376 return ((Log4jMarker) markerFactory.getMarker(marker)).getLog4jMarker();
377 }
378 }
379
380 @Override
381 public String getName() {
382 return name;
383 }
384
385 /**
386 * Always treat de-serialization as a full-blown constructor, by validating the final state of
387 * the de-serialized object.
388 */
389 private void readObject(final ObjectInputStream aInputStream) throws ClassNotFoundException, IOException {
390 // always perform the default de-serialization first
391 aInputStream.defaultReadObject();
392 logger = LogManager.getContext().getLogger(name);
393 markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory();
394 }
395
396 /**
397 * This is the default implementation of writeObject. Customise if necessary.
398 */
399 private void writeObject(final ObjectOutputStream aOutputStream) throws IOException {
400 // perform the default serialization for all non-transient, non-static fields
401 aOutputStream.defaultWriteObject();
402 }
403
404 private static Level getLevel(final int i) {
405 switch (i) {
406 case TRACE_INT:
407 return Level.TRACE;
408 case DEBUG_INT:
409 return Level.DEBUG;
410 case INFO_INT:
411 return Level.INFO;
412 case WARN_INT:
413 return Level.WARN;
414 case ERROR_INT:
415 return Level.ERROR;
416 }
417 return Level.ERROR;
418 }
419 }
+0
-75
log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jLoggerFactory.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import org.apache.logging.log4j.LogManager;
19 import org.apache.logging.log4j.LoggingException;
20 import org.apache.logging.log4j.spi.AbstractLoggerAdapter;
21 import org.apache.logging.log4j.spi.LoggerContext;
22 import org.apache.logging.log4j.status.StatusLogger;
23 import org.apache.logging.log4j.util.StackLocatorUtil;
24 import org.slf4j.ILoggerFactory;
25 import org.slf4j.Logger;
26
27 import java.util.function.Predicate;
28
29 /**
30 * Log4j implementation of SLF4J ILoggerFactory interface.
31 */
32 public class Log4jLoggerFactory extends AbstractLoggerAdapter<Logger> implements ILoggerFactory {
33
34 private static final StatusLogger LOGGER = StatusLogger.getLogger();
35 private static final String SLF4J_PACKAGE = "org.slf4j";
36 private static final Predicate<Class<?>> CALLER_PREDICATE = clazz ->
37 !AbstractLoggerAdapter.class.equals(clazz) && !clazz.getName().startsWith(SLF4J_PACKAGE);
38 private static final String TO_SLF4J_CONTEXT = "org.apache.logging.slf4j.SLF4JLoggerContext";
39
40 private final Log4jMarkerFactory markerFactory;
41
42 public Log4jLoggerFactory(final Log4jMarkerFactory markerFactory) {
43 this.markerFactory = markerFactory;
44 }
45
46
47 @Override
48 protected Logger newLogger(final String name, final LoggerContext context) {
49 final String key = Logger.ROOT_LOGGER_NAME.equals(name) ? LogManager.ROOT_LOGGER_NAME : name;
50 return new Log4jLogger(markerFactory, validateContext(context).getLogger(key), name);
51 }
52
53 @Override
54 protected LoggerContext getContext() {
55 final Class<?> anchor = LogManager.getFactory().isClassLoaderDependent()
56 ? StackLocatorUtil.getCallerClass(Log4jLoggerFactory.class, CALLER_PREDICATE)
57 : null;
58 LOGGER.trace("Log4jLoggerFactory.getContext() found anchor {}", anchor);
59 return anchor == null
60 ? LogManager.getContext(false)
61 : getContext(anchor);
62 }
63
64 Log4jMarkerFactory getMarkerFactory() {
65 return markerFactory;
66 }
67
68 private LoggerContext validateContext(final LoggerContext context) {
69 if (TO_SLF4J_CONTEXT.equals(context.getClass().getName())) {
70 throw new LoggingException("log4j-slf4j-impl cannot be present with log4j-to-slf4j");
71 }
72 return context;
73 }
74 }
+0
-60
log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMDCAdapter.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import java.util.Map;
19
20 import org.apache.logging.log4j.ThreadContext;
21 import org.slf4j.spi.MDCAdapter;
22
23 /**
24 *
25 */
26 public class Log4jMDCAdapter implements MDCAdapter {
27
28 @Override
29 public void put(final String key, final String val) {
30 ThreadContext.put(key, val);
31 }
32
33 @Override
34 public String get(final String key) {
35 return ThreadContext.get(key);
36 }
37
38 @Override
39 public void remove(final String key) {
40 ThreadContext.remove(key);
41 }
42
43 @Override
44 public void clear() {
45 ThreadContext.clearMap();
46 }
47
48 @Override
49 public Map<String, String> getCopyOfContextMap() {
50 return ThreadContext.getContext();
51 }
52
53 @Override
54 @SuppressWarnings("unchecked") // nothing we can do about this, restricted by SLF4J API
55 public void setContextMap(@SuppressWarnings("rawtypes") final Map map) {
56 ThreadContext.clearMap();
57 ThreadContext.putAll(map);
58 }
59 }
+0
-126
log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMarker.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import java.util.ArrayList;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.Objects;
22
23 import org.apache.logging.log4j.MarkerManager;
24 import org.slf4j.IMarkerFactory;
25 import org.slf4j.Marker;
26
27 /**
28 * Log4j/SLF4J {@link Marker} type bridge.
29 */
30 class Log4jMarker implements Marker {
31
32 public static final long serialVersionUID = 1590472L;
33
34 private final IMarkerFactory factory;
35
36 private final org.apache.logging.log4j.Marker marker;
37
38 /**
39 * Constructs a Log4jMarker using an existing Log4j {@link org.apache.logging.log4j.Marker}.
40 * @param marker The Log4j Marker upon which to base this Marker.
41 */
42 public Log4jMarker(final IMarkerFactory markerFactory, final org.apache.logging.log4j.Marker marker) {
43 this.factory = markerFactory;
44 this.marker = marker;
45 }
46
47 @Override
48 public void add(final Marker marker) {
49 if (marker == null) {
50 throw new IllegalArgumentException();
51 }
52 final Marker m = factory.getMarker(marker.getName());
53 this.marker.addParents(((Log4jMarker)m).getLog4jMarker());
54 }
55
56 @Override
57 public boolean contains(final Marker marker) {
58 if (marker == null) {
59 throw new IllegalArgumentException();
60 }
61 return this.marker.isInstanceOf(marker.getName());
62 }
63
64 @Override
65 public boolean contains(final String s) {
66 return s != null ? this.marker.isInstanceOf(s) : false;
67 }
68
69 @Override
70 public boolean equals(final Object obj) {
71 if (this == obj) {
72 return true;
73 }
74 if (obj == null) {
75 return false;
76 }
77 if (!(obj instanceof Log4jMarker)) {
78 return false;
79 }
80 final Log4jMarker other = (Log4jMarker) obj;
81 if (!Objects.equals(marker, other.marker)) {
82 return false;
83 }
84 return true;
85 }
86
87 public org.apache.logging.log4j.Marker getLog4jMarker() {
88 return marker;
89 }
90
91 @Override
92 public String getName() {
93 return marker.getName();
94 }
95
96 @Override
97 public boolean hasChildren() {
98 return marker.hasParents();
99 }
100
101 @Override
102 public int hashCode() {
103 return 31 + Objects.hashCode(marker);
104 }
105
106 @Override
107 public boolean hasReferences() {
108 return marker.hasParents();
109 }
110
111 @Override
112 public Iterator<Marker> iterator() {
113 final org.apache.logging.log4j.Marker[] log4jParents = this.marker.getParents();
114 final List<Marker> parents = new ArrayList<>(log4jParents.length);
115 for (final org.apache.logging.log4j.Marker m : log4jParents) {
116 parents.add(factory.getMarker(m.getName()));
117 }
118 return parents.iterator();
119 }
120
121 @Override
122 public boolean remove(final Marker marker) {
123 return marker != null ? this.marker.remove(MarkerManager.getMarker(marker.getName())) : false;
124 }
125 }
+0
-138
log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMarkerFactory.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Iterator;
21 import java.util.concurrent.ConcurrentHashMap;
22 import java.util.concurrent.ConcurrentMap;
23
24 import org.apache.logging.log4j.Logger;
25 import org.apache.logging.log4j.MarkerManager;
26 import org.apache.logging.log4j.status.StatusLogger;
27 import org.slf4j.IMarkerFactory;
28 import org.slf4j.Marker;
29
30 /**
31 * Log4j/SLF4J bridge to create SLF4J Markers based on name or based on existing SLF4J Markers.
32 */
33 public class Log4jMarkerFactory implements IMarkerFactory {
34
35 private static final Logger LOGGER = StatusLogger.getLogger();
36
37 private final ConcurrentMap<String, Marker> markerMap = new ConcurrentHashMap<>();
38
39 /**
40 * Returns a Log4j Marker that is compatible with SLF4J.
41 * @param name The name of the Marker.
42 * @return A Marker.
43 */
44 @Override
45 public Marker getMarker(final String name) {
46 if (name == null) {
47 throw new IllegalArgumentException("Marker name must not be null");
48 }
49 final Marker marker = markerMap.get(name);
50 if (marker != null) {
51 return marker;
52 }
53 final org.apache.logging.log4j.Marker log4jMarker = MarkerManager.getMarker(name);
54 return addMarkerIfAbsent(name, log4jMarker);
55 }
56
57 private Marker addMarkerIfAbsent(final String name, final org.apache.logging.log4j.Marker log4jMarker) {
58 final Marker marker = new Log4jMarker(this, log4jMarker);
59 final Marker existing = markerMap.putIfAbsent(name, marker);
60 return existing == null ? marker : existing;
61 }
62
63 /**
64 * Returns a Log4j Marker converted from an existing custom SLF4J Marker.
65 * @param marker The SLF4J Marker to convert.
66 * @return A converted Log4j/SLF4J Marker.
67 * @since 2.1
68 */
69 public Marker getMarker(final Marker marker) {
70 if (marker == null) {
71 throw new IllegalArgumentException("Marker must not be null");
72 }
73 final Marker m = markerMap.get(marker.getName());
74 if (m != null) {
75 return m;
76 }
77 return addMarkerIfAbsent(marker.getName(), convertMarker(marker));
78 }
79
80 private static org.apache.logging.log4j.Marker convertMarker(final Marker original) {
81 if (original == null) {
82 throw new IllegalArgumentException("Marker must not be null");
83 }
84 return convertMarker(original, new ArrayList<Marker>());
85 }
86
87 private static org.apache.logging.log4j.Marker convertMarker(final Marker original,
88 final Collection<Marker> visited) {
89 final org.apache.logging.log4j.Marker marker = MarkerManager.getMarker(original.getName());
90 if (original.hasReferences()) {
91 final Iterator<Marker> it = original.iterator();
92 while (it.hasNext()) {
93 final Marker next = it.next();
94 if (visited.contains(next)) {
95 LOGGER.warn("Found a cycle in Marker [{}]. Cycle will be broken.", next.getName());
96 } else {
97 visited.add(next);
98 marker.addParents(convertMarker(next, visited));
99 }
100 }
101 }
102 return marker;
103 }
104
105 /**
106 * Returns true if the Marker exists.
107 * @param name The Marker name.
108 * @return {@code true} if the Marker exists, {@code false} otherwise.
109 */
110 @Override
111 public boolean exists(final String name) {
112 return markerMap.containsKey(name);
113 }
114
115 /**
116 * Log4j does not support detached Markers. This method always returns false.
117 * @param name The Marker name.
118 * @return {@code false}
119 */
120 @Override
121 public boolean detachMarker(final String name) {
122 return false;
123 }
124
125 /**
126 * Log4j does not support detached Markers for performance reasons. The returned Marker is attached.
127 * @param name The Marker name.
128 * @return The named Marker (unmodified).
129 */
130 @Override
131 public Marker getDetachedMarker(final String name) {
132 LOGGER.warn("Log4j does not support detached Markers. Returned Marker [{}] will be unchanged.", name);
133 return getMarker(name);
134 }
135
136
137 }
+0
-41
log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/SLF4JLoggingException.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 /**
19 * Exception thrown when the SLF4J adapter encounters a problem.
20 *
21 */
22 public class SLF4JLoggingException extends RuntimeException {
23
24 /**
25 * Generated serial version ID.
26 */
27 private static final long serialVersionUID = -1618650972455089998L;
28
29 public SLF4JLoggingException(final String msg) {
30 super(msg);
31 }
32
33 public SLF4JLoggingException(final String msg, final Exception ex) {
34 super(msg, ex);
35 }
36
37 public SLF4JLoggingException(final Exception ex) {
38 super(ex);
39 }
40 }
+0
-59
log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/SLF4JServiceProvider.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import org.slf4j.ILoggerFactory;
19 import org.slf4j.IMarkerFactory;
20 import org.slf4j.spi.MDCAdapter;
21
22 public class SLF4JServiceProvider implements org.slf4j.spi.SLF4JServiceProvider {
23
24 public static final String REQUESTED_API_VERSION = "1.8.99";
25
26 private ILoggerFactory loggerFactory;
27 private Log4jMarkerFactory markerFactory;
28 private MDCAdapter mdcAdapter;
29
30 @Override
31 public ILoggerFactory getLoggerFactory() {
32 return loggerFactory;
33 }
34
35 @Override
36 public IMarkerFactory getMarkerFactory() {
37 return markerFactory;
38 }
39
40 @Override
41 public MDCAdapter getMDCAdapter() {
42 return mdcAdapter;
43 }
44
45 @Override
46 public String getRequesteApiVersion() {
47 return REQUESTED_API_VERSION;
48 }
49
50 @Override
51 public void initialize() {
52 markerFactory = new Log4jMarkerFactory();
53 loggerFactory = new Log4jLoggerFactory(markerFactory);
54 mdcAdapter = new Log4jMDCAdapter();
55 }
56
57
58 }
+0
-22
log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/package-info.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 /**
17 * SLF4J support. Note that this does indeed share the same package namespace as the one found in log4j-to-slf4j;
18 * this is intentional. The two JARs should <em>not</em> be used at the same time! Thus, in an OSGi environment
19 * where split packages are not allowed, this error is prevented due to both JARs sharing an exported package name.
20 */
21 package org.apache.logging.slf4j;
+0
-1
log4j-slf4j18-impl/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider less more
0 org.apache.logging.slf4j.SLF4JServiceProvider
+0
-40
log4j-slf4j18-impl/src/site/markdown/index.md less more
0 <!-- vim: set syn=markdown : -->
1 <!--
2 Licensed to the Apache Software Foundation (ASF) under one or more
3 contributor license agreements. See the NOTICE file distributed with
4 this work for additional information regarding copyright ownership.
5 The ASF licenses this file to You under the Apache License, Version 2.0
6 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 -->
17
18 # Log4j 2 SLF4J Binding
19
20 The Log4j 2 SLF4J Binding allows applications coded to the SLF4J API to use
21 Log4j 2 as the implementation.
22
23 ## Requirements
24
25 The Log4j 2 SLF4J Binding has a dependency on the Log4j 2 API as well as the SLF4J API.
26 For more information, see [Runtime Dependencies](../runtime-dependencies.html).
27
28 ## Usage
29
30 The SLF4J binding provided in this component cause all the SLF4J APIs to be routed to Log4j 2. Simply
31 include the Log4j 2 SLF4J Binding jar along with the Log4j 2 jars and SLF4J API jar to cause all SLF4J
32 logging to be handled by Log4j 2.
33
34 <div class="alert alert-danger">
35 Use of the Log4j 2 SLF4J Binding (log4j-slf4j-impl-2.0.jar) together with
36 the SLF4J adapter (log4j-to-slf4j-2.0.jar) should
37 never be attempted, as it will cause events to endlessly be routed between
38 SLF4J and Log4j 2.
39 </div>
+0
-52
log4j-slf4j18-impl/src/site/site.xml less more
0 <!--
1 Licensed to the Apache Software Foundation (ASF) under one or more
2 contributor license agreements. See the NOTICE file distributed with
3 this work for additional information regarding copyright ownership.
4 The ASF licenses this file to You under the Apache License, Version 2.0
5 (the "License"); you may not use this file except in compliance with
6 the License. You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15
16 -->
17 <project name="SLF4J Binding Using Log4j"
18 xmlns="http://maven.apache.org/DECORATION/1.4.0"
19 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
20 xsi:schemaLocation="http://maven.apache.org/DECORATION/1.4.0 http://maven.apache.org/xsd/decoration-1.4.0.xsd">
21 <body>
22 <links>
23 <item name="Apache" href="http://www.apache.org/" />
24 <item name="Logging Services" href="http://logging.apache.org/"/>
25 <item name="Log4j" href="../index.html"/>
26 </links>
27
28 <!-- Component-specific reports -->
29 <menu ref="reports"/>
30
31 <!-- Overall Project Info -->
32 <menu name="Log4j Project Information" img="icon-info-sign">
33 <item name="Dependencies" href="../dependencies.html" />
34 <item name="Dependency Convergence" href="../dependency-convergence.html" />
35 <item name="Dependency Management" href="../dependency-management.html" />
36 <item name="Project Team" href="../team-list.html" />
37 <item name="Mailing Lists" href="../mail-lists.html" />
38 <item name="Issue Tracking" href="../issue-tracking.html" />
39 <item name="Project License" href="../license.html" />
40 <item name="Source Repository" href="../source-repository.html" />
41 <item name="Project Summary" href="../project-summary.html" />
42 </menu>
43
44 <menu name="Log4j Project Reports" img="icon-cog">
45 <item name="Changes Report" href="../changes-report.html" />
46 <item name="JIRA Report" href="../jira-report.html" />
47 <item name="Surefire Report" href="../surefire-report.html" />
48 <item name="RAT Report" href="../rat-report.html" />
49 </menu>
50 </body>
51 </project>
+0
-91
log4j-slf4j18-impl/src/test/java/org/apache/logging/other/pkg/LoggerContextAnchorTest.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.other.pkg;
17
18 import org.apache.logging.log4j.Level;
19 import org.apache.logging.log4j.status.StatusData;
20 import org.apache.logging.log4j.status.StatusListener;
21 import org.apache.logging.log4j.status.StatusLogger;
22 import org.junit.Test;
23 import org.slf4j.LoggerFactory;
24
25 import java.util.List;
26 import java.util.concurrent.CopyOnWriteArrayList;
27
28 import static org.junit.Assert.assertEquals;
29
30 /**
31 * Test LoggerContext lookups by verifying the anchor class representing calling code.
32 */
33 public class LoggerContextAnchorTest {
34 private static final String PREFIX = "Log4jLoggerFactory.getContext() found anchor class ";
35
36 @Test
37 public void testLoggerFactoryLookupClass() {
38 String fqcn = getAnchorFqcn(() -> LoggerFactory.getLogger(LoggerContextAnchorTest.class));
39 assertEquals(getClass().getName(), fqcn);
40 }
41
42 @Test
43 public void testLoggerFactoryLookupString() {
44 String fqcn = getAnchorFqcn(() -> LoggerFactory.getLogger("custom.logger"));
45 assertEquals(getClass().getName(), fqcn);
46 }
47
48 @Test
49 public void testLoggerFactoryGetILoggerFactoryLookup() {
50 String fqcn = getAnchorFqcn(() -> LoggerFactory.getILoggerFactory().getLogger("custom.logger"));
51 assertEquals(getClass().getName(), fqcn);
52 }
53
54 private static String getAnchorFqcn(Runnable runnable) {
55 List<String> results = new CopyOnWriteArrayList<>();
56 StatusListener listener = new StatusListener() {
57 @Override
58 public void log(StatusData data) {
59 String formattedMessage = data.getMessage().getFormattedMessage();
60 if (formattedMessage.startsWith(PREFIX)) {
61 results.add(formattedMessage.substring(PREFIX.length()));
62 }
63 }
64
65 @Override
66 public Level getStatusLevel() {
67 return Level.TRACE;
68 }
69
70 @Override
71 public void close() {
72 // nop
73 }
74 };
75 StatusLogger statusLogger = StatusLogger.getLogger();
76 statusLogger.registerListener(listener);
77 try {
78 runnable.run();
79 if (results.isEmpty()) {
80 throw new AssertionError("Failed to locate an anchor lookup status message");
81 }
82 if (results.size() > 1) {
83 throw new AssertionError("Found multiple anchor lines: " + results);
84 }
85 return results.get(0);
86 } finally {
87 statusLogger.removeListener(listener);
88 }
89 }
90 }
+0
-67
log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import static org.junit.Assert.assertEquals;
19
20 import java.util.List;
21
22 import org.apache.logging.log4j.junit.LoggerContextRule;
23 import org.apache.logging.log4j.test.appender.ListAppender;
24 import org.junit.ClassRule;
25 import org.junit.Test;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 public class CallerInformationTest {
30
31 // config from log4j-core test-jar
32 private static final String CONFIG = "log4j2-calling-class.xml";
33
34 @ClassRule
35 public static final LoggerContextRule ctx = new LoggerContextRule(CONFIG);
36
37 @Test
38 public void testClassLogger() throws Exception {
39 final ListAppender app = ctx.getListAppender("Class").clear();
40 final Logger logger = LoggerFactory.getLogger("ClassLogger");
41 logger.info("Ignored message contents.");
42 logger.warn("Verifying the caller class is still correct.");
43 logger.error("Hopefully nobody breaks me!");
44 final List<String> messages = app.getMessages();
45 assertEquals("Incorrect number of messages.", 3, messages.size());
46 for (final String message : messages) {
47 assertEquals("Incorrect caller class name.", this.getClass().getName(), message);
48 }
49 }
50
51 @Test
52 public void testMethodLogger() throws Exception {
53 final ListAppender app = ctx.getListAppender("Method").clear();
54 final Logger logger = LoggerFactory.getLogger("MethodLogger");
55 logger.info("More messages.");
56 logger.warn("CATASTROPHE INCOMING!");
57 logger.error("ZOMBIES!!!");
58 logger.warn("brains~~~");
59 logger.info("Itchy. Tasty.");
60 final List<String> messages = app.getMessages();
61 assertEquals("Incorrect number of messages.", 5, messages.size());
62 for (final String message : messages) {
63 assertEquals("Incorrect caller method name.", "testMethodLogger", message);
64 }
65 }
66 }
+0
-76
log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CustomFlatMarker.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16
17 package org.apache.logging.slf4j;
18
19 import java.util.Iterator;
20
21 import org.slf4j.Marker;
22
23 /**
24 * Test Marker that may contain no reference/parent Markers.
25 * @see <a href="https://issues.apache.org/jira/browse/LOG4J2-793">LOG4J2-793</a>
26 */
27 public class CustomFlatMarker implements Marker {
28 private static final long serialVersionUID = -4115520883240247266L;
29
30 private final String name;
31
32 public CustomFlatMarker(final String name) {
33 this.name = name;
34 }
35
36 @Override
37 public String getName() {
38 return name;
39 }
40
41 @Override
42 public void add(final Marker reference) {
43 throw new UnsupportedOperationException();
44 }
45
46 @Override
47 public boolean remove(final Marker reference) {
48 throw new UnsupportedOperationException();
49 }
50
51 @Override
52 public boolean hasChildren() {
53 return hasReferences();
54 }
55
56 @Override
57 public boolean hasReferences() {
58 return false;
59 }
60
61 @Override
62 public Iterator<Marker> iterator() {
63 throw new UnsupportedOperationException();
64 }
65
66 @Override
67 public boolean contains(final Marker other) {
68 return false;
69 }
70
71 @Override
72 public boolean contains(final String name) {
73 return false;
74 }
75 }
+0
-57
log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4j1222Test.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import org.junit.Test;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 import static org.junit.Assert.*;
23
24 /**
25 * Tests logging during shutdown.
26 */
27 public class Log4j1222Test
28 {
29
30 @Test
31 public void homepageRendersSuccessfully()
32 {
33 System.setProperty("log4j.configurationFile", "log4j2-console.xml");
34 Runtime.getRuntime().addShutdownHook(new ShutdownHook());
35 }
36
37 private static class ShutdownHook extends Thread {
38
39 private static class Holder {
40 private static final Logger LOGGER = LoggerFactory.getLogger(Log4j1222Test.class);
41 }
42
43 @Override
44 public void run()
45 {
46 super.run();
47 trigger();
48 }
49
50 private void trigger() {
51 Holder.LOGGER.info("Attempt to trigger");
52 assertTrue("Logger is of type " + Holder.LOGGER.getClass().getName(), Holder.LOGGER instanceof Log4jLogger);
53
54 }
55 }
56 }
+0
-41
log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4j2_1482_Slf4jTest.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16
17 package org.apache.logging.slf4j;
18
19 import org.apache.logging.log4j.core.layout.Log4j2_1482_Test;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 /**
24 * Tests https://issues.apache.org/jira/browse/LOG4J2-1482
25 */
26 public class Log4j2_1482_Slf4jTest extends Log4j2_1482_Test {
27
28 @Override
29 protected void log(final int runNumber) {
30 if (runNumber == 2) {
31 // System.out.println("Set a breakpoint here.");
32 }
33 final Logger logger = LoggerFactory.getLogger("auditcsvfile");
34 final int val1 = 9, val2 = 11, val3 = 12;
35 logger.info("Info Message!", val1, val2, val3);
36 logger.info("Info Message!", val1, val2, val3);
37 logger.info("Info Message!", val1, val2, val3);
38 }
39
40 }
+0
-47
log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4jMarkerTest.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import org.apache.logging.log4j.Marker;
19 import org.apache.logging.log4j.MarkerManager;
20 import org.junit.Assert;
21 import org.junit.BeforeClass;
22 import org.junit.Test;
23
24 public class Log4jMarkerTest {
25
26 private static Log4jMarkerFactory markerFactory;
27
28 @BeforeClass
29 public static void startup() {
30 markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory();
31
32 }
33
34 @Test
35 public void testEquals() {
36 final Marker markerA = MarkerManager.getMarker(Log4jMarkerTest.class.getName() + "-A");
37 final Marker markerB = MarkerManager.getMarker(Log4jMarkerTest.class.getName() + "-B");
38 final Log4jMarker marker1 = new Log4jMarker(markerFactory, markerA);
39 final Log4jMarker marker2 = new Log4jMarker(markerFactory, markerA);
40 final Log4jMarker marker3 = new Log4jMarker(markerFactory, markerB);
41 Assert.assertEquals(marker1, marker2);
42 Assert.assertNotEquals(marker1, null);
43 Assert.assertNotEquals(null, marker1);
44 Assert.assertNotEquals(marker1, marker3);
45 }
46 }
+0
-44
log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/LoggerContextTest.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import org.apache.logging.log4j.core.LifeCycle;
19 import org.apache.logging.log4j.spi.LoggerContext;
20 import org.junit.Test;
21 import org.slf4j.LoggerFactory;
22
23 import java.util.Set;
24
25 import static org.junit.Assert.assertTrue;
26
27 /**
28 * Tests cleanup of the LoggerContexts.
29 */
30 public class LoggerContextTest {
31
32 @Test
33 public void testCleanup() throws Exception {
34 Log4jLoggerFactory factory = (Log4jLoggerFactory) LoggerFactory.getILoggerFactory();
35 factory.getLogger("test");
36 Set<LoggerContext> set = factory.getLoggerContexts();
37 LoggerContext ctx1 = set.toArray(LoggerContext.EMPTY_ARRAY)[0];
38 assertTrue("LoggerContext is not enabled for shutdown", ctx1 instanceof LifeCycle);
39 ((LifeCycle) ctx1).stop();
40 set = factory.getLoggerContexts();
41 assertTrue("Expected no LoggerContexts", set.isEmpty());
42 }
43 }
+0
-161
log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertNotNull;
20 import static org.junit.Assert.assertTrue;
21
22 import java.util.List;
23
24 import org.apache.logging.log4j.junit.LoggerContextRule;
25 import org.apache.logging.log4j.test.appender.ListAppender;
26 import org.apache.logging.log4j.util.Strings;
27 import org.junit.After;
28 import org.junit.Before;
29 import org.junit.ClassRule;
30 import org.junit.Test;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33 import org.slf4j.MDC;
34 import org.slf4j.Marker;
35 import org.slf4j.ext.XLogger;
36 import org.slf4j.ext.XLoggerFactory;
37 import org.slf4j.spi.LocationAwareLogger;
38
39 /**
40 *
41 */
42 public class LoggerTest {
43
44 private static final String CONFIG = "log4j-test1.xml";
45
46 @ClassRule
47 public static LoggerContextRule ctx = new LoggerContextRule(CONFIG);
48
49 Logger logger = LoggerFactory.getLogger("LoggerTest");
50 XLogger xlogger = XLoggerFactory.getXLogger("LoggerTest");
51
52 @Test
53 public void basicFlow() {
54 xlogger.entry();
55 verify("List", "o.a.l.s.LoggerTest entry MDC{}" + Strings.LINE_SEPARATOR);
56 xlogger.exit();
57 verify("List", "o.a.l.s.LoggerTest exit MDC{}" + Strings.LINE_SEPARATOR);
58 }
59
60 @Test
61 public void simpleFlow() {
62 xlogger.entry(CONFIG);
63 verify("List", "o.a.l.s.LoggerTest entry with (log4j-test1.xml) MDC{}" + Strings.LINE_SEPARATOR);
64 xlogger.exit(0);
65 verify("List", "o.a.l.s.LoggerTest exit with (0) MDC{}" + Strings.LINE_SEPARATOR);
66 }
67
68 @Test
69 public void throwing() {
70 xlogger.throwing(new IllegalArgumentException("Test Exception"));
71 verify("List", "o.a.l.s.LoggerTest throwing MDC{}" + Strings.LINE_SEPARATOR);
72 }
73
74 @Test
75 public void catching() {
76 try {
77 throw new NullPointerException();
78 } catch (final Exception e) {
79 xlogger.catching(e);
80 verify("List", "o.a.l.s.LoggerTest catching MDC{}" + Strings.LINE_SEPARATOR);
81 }
82 }
83
84 @Test
85 public void debug() {
86 logger.debug("Debug message");
87 verify("List", "o.a.l.s.LoggerTest Debug message MDC{}" + Strings.LINE_SEPARATOR);
88 }
89
90 @Test
91 public void debugNoParms() {
92 logger.debug("Debug message {}");
93 verify("List", "o.a.l.s.LoggerTest Debug message {} MDC{}" + Strings.LINE_SEPARATOR);
94 logger.debug("Debug message {}", (Object[]) null);
95 verify("List", "o.a.l.s.LoggerTest Debug message {} MDC{}" + Strings.LINE_SEPARATOR);
96 ((LocationAwareLogger)logger).log(null, Log4jLogger.class.getName(), LocationAwareLogger.DEBUG_INT,
97 "Debug message {}", null, null);
98 verify("List", "o.a.l.s.LoggerTest Debug message {} MDC{}" + Strings.LINE_SEPARATOR);
99 }
100
101
102 @Test
103 public void debugWithParms() {
104 logger.debug("Hello, {}", "World");
105 verify("List", "o.a.l.s.LoggerTest Hello, World MDC{}" + Strings.LINE_SEPARATOR);
106 }
107
108 @Test
109 public void mdc() {
110
111 MDC.put("TestYear", "2010");
112 logger.debug("Debug message");
113 verify("List", "o.a.l.s.LoggerTest Debug message MDC{TestYear=2010}" + Strings.LINE_SEPARATOR);
114 MDC.clear();
115 logger.debug("Debug message");
116 verify("List", "o.a.l.s.LoggerTest Debug message MDC{}" + Strings.LINE_SEPARATOR);
117 }
118
119 /**
120 * @see <a href="https://issues.apache.org/jira/browse/LOG4J2-793">LOG4J2-793</a>
121 */
122 @Test
123 public void supportsCustomSLF4JMarkers() {
124 final Marker marker = new CustomFlatMarker("TEST");
125 logger.debug(marker, "Test");
126 verify("List", "o.a.l.s.LoggerTest Test MDC{}" + Strings.LINE_SEPARATOR);
127 }
128
129 @Test
130 public void testRootLogger() {
131 final Logger l = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
132 assertNotNull("No Root Logger", l);
133 assertEquals(Logger.ROOT_LOGGER_NAME, l.getName());
134 }
135
136 @Test
137 public void doubleSubst() {
138 logger.debug("Hello, {}", "Log4j {}");
139 verify("List", "o.a.l.s.LoggerTest Hello, Log4j {} MDC{}" + Strings.LINE_SEPARATOR);
140 xlogger.debug("Hello, {}", "Log4j {}");
141 verify("List", "o.a.l.s.LoggerTest Hello, Log4j Log4j {} MDC{}" + Strings.LINE_SEPARATOR);
142 }
143
144 private void verify(final String name, final String expected) {
145 final ListAppender listApp = ctx.getListAppender(name);
146 assertNotNull("Missing Appender", listApp);
147 final List<String> events = listApp.getMessages();
148 assertTrue("Incorrect number of messages. Expected 1 Actual " + events.size(), events.size()== 1);
149 final String actual = events.get(0);
150 assertEquals("Incorrect message. Expected " + expected + ". Actual " + actual, expected, actual);
151 listApp.clear();
152 }
153
154 @Before
155 @After
156 public void cleanup() {
157 MDC.clear();
158 ctx.getListAppender("List").clear();
159 }
160 }
+0
-186
log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/MarkerTest.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import org.apache.logging.log4j.Marker;
19 import org.apache.logging.log4j.MarkerManager;
20 import org.junit.After;
21 import org.junit.Assert;
22 import org.junit.Before;
23 import org.junit.BeforeClass;
24 import org.junit.Test;
25
26 import static org.junit.Assert.*;
27
28 /**
29 *
30 */
31 public class MarkerTest {
32
33 private static final String CHILD_MAKER_NAME = MarkerTest.class.getSimpleName() + "-TEST";
34 private static final String PARENT_MARKER_NAME = MarkerTest.class.getSimpleName() + "-PARENT";
35 private static Log4jMarkerFactory markerFactory;
36
37 @BeforeClass
38 public static void startup() {
39 markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory();
40
41 }
42
43 @Before
44 @After
45 public void clearMarkers() {
46 MarkerManager.clear();
47 }
48
49 @Test
50 public void testAddMarker() {
51 final String childMakerName = CHILD_MAKER_NAME + "-AM";
52 final String parentMarkerName = PARENT_MARKER_NAME + "-AM";
53 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMakerName);
54 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMarkerName);
55 slf4jMarker.add(slf4jParent);
56 final Marker log4jParent = MarkerManager.getMarker(parentMarkerName);
57 final Marker log4jMarker = MarkerManager.getMarker(childMakerName);
58
59 assertTrue("Incorrect Marker class", slf4jMarker instanceof Log4jMarker);
60 assertTrue(String.format("%s (log4jMarker=%s) is not an instance of %s (log4jParent=%s) in Log4j",
61 childMakerName, parentMarkerName, log4jMarker, log4jParent), log4jMarker.isInstanceOf(log4jParent));
62 assertTrue(String.format("%s (slf4jMarker=%s) is not an instance of %s (log4jParent=%s) in SLF4J",
63 childMakerName, parentMarkerName, slf4jMarker, slf4jParent), slf4jMarker.contains(slf4jParent));
64 }
65
66 @Test
67 public void testAddNullMarker() {
68 final String childMarkerName = CHILD_MAKER_NAME + "-ANM";
69 final String parentMakerName = PARENT_MARKER_NAME + "-ANM";
70 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
71 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
72 slf4jMarker.add(slf4jParent);
73 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
74 final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
75 final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
76 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
77 final org.slf4j.Marker nullMarker = null;
78 try {
79 log4jSlf4jParent.add(nullMarker);
80 fail("Expected " + IllegalArgumentException.class.getName());
81 } catch (final IllegalArgumentException e) {
82 // expected
83 }
84 try {
85 log4jSlf4jMarker.add(nullMarker);
86 fail("Expected " + IllegalArgumentException.class.getName());
87 } catch (final IllegalArgumentException e) {
88 // expected
89 }
90 }
91
92 @Test
93 public void testAddSameMarker() {
94 final String childMarkerName = CHILD_MAKER_NAME + "-ASM";
95 final String parentMakerName = PARENT_MARKER_NAME + "-ASM";
96 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
97 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
98 slf4jMarker.add(slf4jParent);
99 slf4jMarker.add(slf4jParent);
100 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
101 final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
102 assertTrue(String.format("%s (log4jMarker=%s) is not an instance of %s (log4jParent=%s) in Log4j",
103 childMarkerName, parentMakerName, log4jMarker, log4jParent), log4jMarker.isInstanceOf(log4jParent));
104 assertTrue(String.format("%s (slf4jMarker=%s) is not an instance of %s (log4jParent=%s) in SLF4J",
105 childMarkerName, parentMakerName, slf4jMarker, slf4jParent), slf4jMarker.contains(slf4jParent));
106 }
107
108 @Test
109 public void testEquals() {
110 final String childMarkerName = CHILD_MAKER_NAME + "-ASM";
111 final String parentMakerName = PARENT_MARKER_NAME + "-ASM";
112 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
113 final org.slf4j.Marker slf4jMarker2 = org.slf4j.MarkerFactory.getMarker(childMarkerName);
114 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
115 slf4jMarker.add(slf4jParent);
116 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
117 final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
118 final Marker log4jMarker2 = MarkerManager.getMarker(childMarkerName);
119 assertEquals(log4jParent, log4jParent);
120 assertEquals(log4jMarker, log4jMarker);
121 assertEquals(log4jMarker, log4jMarker2);
122 assertEquals(slf4jMarker, slf4jMarker2);
123 assertNotEquals(log4jParent, log4jMarker);
124 assertNotEquals(log4jMarker, log4jParent);
125 }
126
127 @Test
128 public void testContainsNullMarker() {
129 final String childMarkerName = CHILD_MAKER_NAME + "-CM";
130 final String parentMakerName = PARENT_MARKER_NAME + "-CM";
131 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
132 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
133 slf4jMarker.add(slf4jParent);
134 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
135 final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
136 final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
137 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
138 final org.slf4j.Marker nullMarker = null;
139 try {
140 Assert.assertFalse(log4jSlf4jParent.contains(nullMarker));
141 fail("Expected " + IllegalArgumentException.class.getName());
142 } catch (final IllegalArgumentException e) {
143 // expected
144 }
145 try {
146 Assert.assertFalse(log4jSlf4jMarker.contains(nullMarker));
147 fail("Expected " + IllegalArgumentException.class.getName());
148 } catch (final IllegalArgumentException e) {
149 // expected
150 }
151 }
152
153 @Test
154 public void testContainsNullString() {
155 final String childMarkerName = CHILD_MAKER_NAME + "-CS";
156 final String parentMakerName = PARENT_MARKER_NAME + "-CS";
157 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
158 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
159 slf4jMarker.add(slf4jParent);
160 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
161 final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
162 final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
163 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
164 final String nullStr = null;
165 Assert.assertFalse(log4jSlf4jParent.contains(nullStr));
166 Assert.assertFalse(log4jSlf4jMarker.contains(nullStr));
167 }
168
169 @Test
170 public void testRemoveNullMarker() {
171 final String childMakerName = CHILD_MAKER_NAME + "-CM";
172 final String parentMakerName = PARENT_MARKER_NAME + "-CM";
173 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMakerName);
174 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
175 slf4jMarker.add(slf4jParent);
176 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
177 final Marker log4jMarker = MarkerManager.getMarker(childMakerName);
178 final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
179 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
180 final org.slf4j.Marker nullMarker = null;
181 Assert.assertFalse(log4jSlf4jParent.remove(nullMarker));
182 Assert.assertFalse(log4jSlf4jMarker.remove(nullMarker));
183 }
184
185 }
+0
-43
log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/OverflowTest.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import org.apache.logging.log4j.LoggingException;
19 import org.junit.Test;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 import static org.junit.Assert.fail;
24
25 /**
26 * Tests StackOverflow when slf4j-impl and to-slf4j are both present.
27 */
28 public class OverflowTest {
29
30 @Test
31 public void log() {
32 try {
33 final Logger logger = LoggerFactory.getLogger(OverflowTest.class);
34 fail("Failed to detect inclusion of log4j-to-slf4j");
35 } catch (LoggingException ex) {
36 // Expected exception.
37 } catch (StackOverflowError error) {
38 fail("Failed to detect inclusion of log4j-to-slf4j, caught StackOverflowError");
39 }
40 }
41
42 }
+0
-46
log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/SerializeTest.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import java.io.Serializable;
19
20 import org.apache.logging.log4j.junit.LoggerContextRule;
21 import org.junit.ClassRule;
22 import org.junit.Test;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 import static org.apache.logging.log4j.SerializableMatchers.serializesRoundTrip;
27 import static org.junit.Assert.*;
28
29 /**
30 *
31 */
32 public class SerializeTest {
33
34 private static final String CONFIG = "log4j-test1.xml";
35
36 @ClassRule
37 public static final LoggerContextRule CTX = new LoggerContextRule(CONFIG);
38
39 Logger logger = LoggerFactory.getLogger("LoggerTest");
40
41 @Test
42 public void testLogger() throws Exception {
43 assertThat((Serializable) logger, serializesRoundTrip());
44 }
45 }
+0
-33
log4j-slf4j18-impl/src/test/resources/log4j-test1.xml less more
0 <?xml version="1.0" encoding="UTF-8"?>
1 <configuration status="error" name="LoggerTest">
2 <properties>
3 <property name="filename">target/test.log</property>
4 </properties>
5 <ThresholdFilter level="trace"/>
6
7 <Appenders>
8 <Console name="STDOUT">
9 <PatternLayout pattern="%C{1.} %m MDC%X%n"/>
10 </Console>
11 <File name="File" fileName="${filename}">
12 <PatternLayout>
13 <pattern>%d %p %C{1.} [%t] %m%n</pattern>
14 </PatternLayout>
15 </File>
16 <List name="List">
17 <PatternLayout pattern="%C{1.} %m MDC%X%n%ex{0}"/>
18 </List>
19 <SLF4J name="SLF4J"/>
20 </Appenders>
21
22 <Loggers>
23 <Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
24 <AppenderRef ref="File"/>
25 </Logger>
26
27 <Root level="trace">
28 <AppenderRef ref="List"/>
29 </Root>
30 </Loggers>
31
32 </configuration>
+0
-27
log4j-slf4j18-impl/src/test/resources/log4j2-1482.xml less more
0 <?xml version="1.0" encoding="UTF-8"?>
1 <Configuration status="warn" name="MyApp" packages="">
2 <Properties>
3 <Property name="audit-path">target/log4j2-1482</Property>
4 <Property name="file-name">audit</Property>
5 <Property name="file-header">param1,param2,param3${sys:line.separator}
6 </Property>
7 </Properties>
8
9 <Appenders>
10 <RollingFile name="auditfile" fileName="${audit-path}/${file-name}.tmp"
11 filePattern="${audit-path}/${file-name}-%d{yyyy-MM-dd}-%i.csv">
12 <CsvParameterLayout delimiter="," header="${file-header}">
13 </CsvParameterLayout>
14 <Policies>
15 <SizeBasedTriggeringPolicy size="80 B" />
16 </Policies>
17 <DefaultRolloverStrategy max="2" />
18 </RollingFile>
19 </Appenders>
20
21 <Loggers>
22 <Root level="info">
23 <AppenderRef ref="auditfile" />
24 </Root>
25 </Loggers>
26 </Configuration>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!--
2 Licensed to the Apache Software Foundation (ASF) under one or more
3 contributor license agreements. See the NOTICE file distributed with
4 this work for additional information regarding copyright ownership.
5 The ASF licenses this file to You under the Apache License, Version 2.0
6 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 -->
17 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
18 <modelVersion>4.0.0</modelVersion>
19 <parent>
20 <groupId>org.apache.logging.log4j</groupId>
21 <artifactId>log4j</artifactId>
22 <version>2.19.0</version>
23 </parent>
24 <artifactId>log4j-slf4j2-impl</artifactId>
25 <packaging>jar</packaging>
26 <name>Apache Log4j SLF4J 2.0 Binding</name>
27 <description>The Apache Log4j SLF4J 2.0 API binding to Log4j 2 Core</description>
28 <properties>
29 <log4jParentDir>${basedir}/..</log4jParentDir>
30 <docLabel>SLF4J Documentation</docLabel>
31 <projectDir>/slf4j2-impl</projectDir>
32 <slf4j.version>2.0.0</slf4j.version>
33 <module.name>org.apache.logging.log4j.slf4j</module.name>
34 <maven.doap.skip>true</maven.doap.skip>
35 </properties>
36 <dependencies>
37 <dependency>
38 <groupId>org.slf4j</groupId>
39 <artifactId>slf4j-api</artifactId>
40 <version>${slf4j.version}</version>
41 </dependency>
42 <dependency>
43 <groupId>org.slf4j</groupId>
44 <artifactId>slf4j-ext</artifactId>
45 <version>${slf4j.version}</version>
46 <optional>true</optional>
47 </dependency>
48 <dependency>
49 <groupId>org.apache.logging.log4j</groupId>
50 <artifactId>log4j-api</artifactId>
51 </dependency>
52 <dependency>
53 <groupId>org.apache.logging.log4j</groupId>
54 <artifactId>log4j-core</artifactId>
55 <scope>test</scope>
56 </dependency>
57 <dependency>
58 <groupId>org.apache.logging.log4j</groupId>
59 <artifactId>log4j-api</artifactId>
60 <type>test-jar</type>
61 <scope>test</scope>
62 </dependency>
63 <dependency>
64 <groupId>org.apache.commons</groupId>
65 <artifactId>commons-lang3</artifactId>
66 <scope>test</scope>
67 </dependency>
68 <dependency>
69 <groupId>org.apache.commons</groupId>
70 <artifactId>commons-csv</artifactId>
71 <scope>test</scope>
72 </dependency>
73 <dependency>
74 <groupId>org.apache.logging.log4j</groupId>
75 <artifactId>log4j-core</artifactId>
76 <type>test-jar</type>
77 <scope>test</scope>
78 </dependency>
79 <dependency>
80 <groupId>org.apache.logging.log4j</groupId>
81 <artifactId>log4j-to-slf4j</artifactId>
82 <version>${project.version}</version>
83 <scope>test</scope>
84 </dependency>
85 <dependency>
86 <groupId>org.junit.vintage</groupId>
87 <artifactId>junit-vintage-engine</artifactId>
88 <scope>test</scope>
89 </dependency>
90 <dependency>
91 <groupId>org.junit.jupiter</groupId>
92 <artifactId>junit-jupiter-engine</artifactId>
93 <scope>test</scope>
94 </dependency>
95 <dependency>
96 <groupId>org.junit.jupiter</groupId>
97 <artifactId>junit-jupiter-params</artifactId>
98 <scope>test</scope>
99 </dependency>
100 <dependency>
101 <groupId>org.assertj</groupId>
102 <artifactId>assertj-core</artifactId>
103 <scope>test</scope>
104 </dependency>
105 </dependencies>
106 <build>
107 <plugins>
108 <!-- Include the standard NOTICE and LICENSE -->
109 <plugin>
110 <groupId>org.apache.maven.plugins</groupId>
111 <artifactId>maven-remote-resources-plugin</artifactId>
112 <executions>
113 <execution>
114 <goals>
115 <goal>process</goal>
116 </goals>
117 <configuration>
118 <skip>false</skip>
119 </configuration>
120 </execution>
121 </executions>
122 </plugin>
123 <plugin>
124 <groupId>org.apache.maven.plugins</groupId>
125 <artifactId>maven-surefire-plugin</artifactId>
126 <executions>
127 <execution>
128 <id>loop-test</id>
129 <phase>test</phase>
130 <goals>
131 <goal>test</goal>
132 </goals>
133 <configuration>
134 <includes>
135 <include>**/OverflowTest.java</include>
136 </includes>
137 <includeJUnit5Engines>junit-vintage</includeJUnit5Engines>
138 </configuration>
139 </execution>
140 <execution>
141 <id>default-test</id>
142 <phase>test</phase>
143 <goals>
144 <goal>test</goal>
145 </goals>
146 <configuration>
147 <includes>
148 <include>**/*Test.java</include>
149 </includes>
150 <excludes>
151 <exclude>**/OverflowTest.java</exclude>
152 </excludes>
153 <classpathDependencyExcludes>
154 <classpathDependencyExcludes>org.apache.logging.log4j:log4j-to-slf4j</classpathDependencyExcludes>
155 </classpathDependencyExcludes>
156 </configuration>
157 </execution>
158 </executions>
159 </plugin>
160 <plugin>
161 <groupId>org.apache.felix</groupId>
162 <artifactId>maven-bundle-plugin</artifactId>
163 <configuration>
164 <instructions>
165 <Export-Package>
166 org.apache.logging.slf4j,
167 org.slf4j.impl
168 </Export-Package>
169 <Require-Capability>
170 osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)"
171 </Require-Capability>
172 <Provide-Capability>
173 osgi.serviceloader;osgi.serviceloader=org.slf4j.spi.SLF4JServiceProvider
174 </Provide-Capability>
175 </instructions>
176 </configuration>
177 </plugin>
178 </plugins>
179 </build>
180 <reporting>
181 <plugins>
182 <plugin>
183 <groupId>org.apache.maven.plugins</groupId>
184 <artifactId>maven-changes-plugin</artifactId>
185 <version>${changes.plugin.version}</version>
186 <reportSets>
187 <reportSet>
188 <reports>
189 <report>changes-report</report>
190 </reports>
191 </reportSet>
192 </reportSets>
193 <configuration>
194 <issueLinkTemplate>%URL%/show_bug.cgi?id=%ISSUE%</issueLinkTemplate>
195 <useJql>true</useJql>
196 </configuration>
197 </plugin>
198 <plugin>
199 <groupId>org.apache.maven.plugins</groupId>
200 <artifactId>maven-checkstyle-plugin</artifactId>
201 <version>${checkstyle.plugin.version}</version>
202 <configuration>
203 <!--<propertiesLocation>${vfs.parent.dir}/checkstyle.properties</propertiesLocation> -->
204 <configLocation>${log4jParentDir}/checkstyle.xml</configLocation>
205 <suppressionsLocation>${log4jParentDir}/checkstyle-suppressions.xml</suppressionsLocation>
206 <enableRulesSummary>false</enableRulesSummary>
207 <propertyExpansion>basedir=${basedir}</propertyExpansion>
208 <propertyExpansion>licensedir=${log4jParentDir}/checkstyle-header.txt</propertyExpansion>
209 </configuration>
210 </plugin>
211 <plugin>
212 <groupId>org.apache.maven.plugins</groupId>
213 <artifactId>maven-javadoc-plugin</artifactId>
214 <version>${javadoc.plugin.version}</version>
215 <configuration>
216 <bottom><![CDATA[<p align="center">Copyright &#169; {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br />
217 Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo,
218 and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom>
219 <!-- module link generation is completely broken in the javadoc plugin for a multi-module non-aggregating
220 project -->
221 <detectOfflineLinks>false</detectOfflineLinks>
222 <linksource>true</linksource>
223 </configuration>
224 <reportSets>
225 <reportSet>
226 <id>non-aggregate</id>
227 <reports>
228 <report>javadoc</report>
229 </reports>
230 </reportSet>
231 </reportSets>
232 </plugin>
233 <plugin>
234 <groupId>com.github.spotbugs</groupId>
235 <artifactId>spotbugs-maven-plugin</artifactId>
236 </plugin>
237 <plugin>
238 <groupId>org.apache.maven.plugins</groupId>
239 <artifactId>maven-jxr-plugin</artifactId>
240 <version>${jxr.plugin.version}</version>
241 <reportSets>
242 <reportSet>
243 <id>non-aggregate</id>
244 <reports>
245 <report>jxr</report>
246 </reports>
247 </reportSet>
248 <reportSet>
249 <id>aggregate</id>
250 <reports>
251 <report>aggregate</report>
252 </reports>
253 </reportSet>
254 </reportSets>
255 </plugin>
256 <plugin>
257 <groupId>org.apache.maven.plugins</groupId>
258 <artifactId>maven-pmd-plugin</artifactId>
259 <version>${pmd.plugin.version}</version>
260 <configuration>
261 <targetJdk>${maven.compiler.target}</targetJdk>
262 </configuration>
263 </plugin>
264 </plugins>
265 </reporting>
266 </project>
267
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.function.Supplier;
23
24 import org.apache.logging.log4j.BridgeAware;
25 import org.apache.logging.log4j.CloseableThreadContext;
26 import org.apache.logging.log4j.CloseableThreadContext.Instance;
27 import org.apache.logging.log4j.LogBuilder;
28 import org.slf4j.Marker;
29 import org.slf4j.spi.LoggingEventBuilder;
30
31 public class Log4jEventBuilder implements LoggingEventBuilder {
32
33 private static final String FQCN = Log4jEventBuilder.class.getName();
34
35 private final Log4jMarkerFactory markerFactory;
36 private final LogBuilder logBuilder;
37 private final List<Object> arguments = new ArrayList<>();
38 private String message = null;
39 private Map<String, String> keyValuePairs = null;
40
41 public Log4jEventBuilder(final Log4jMarkerFactory markerFactory, final LogBuilder logBuilder) {
42 this.markerFactory = markerFactory;
43 this.logBuilder = logBuilder;
44 if (logBuilder instanceof BridgeAware) {
45 ((BridgeAware) logBuilder).setEntryPoint(FQCN);
46 }
47 }
48
49 @Override
50 public LoggingEventBuilder setCause(Throwable cause) {
51 logBuilder.withThrowable(cause);
52 return this;
53 }
54
55 @Override
56 public LoggingEventBuilder addMarker(Marker marker) {
57 logBuilder.withMarker(markerFactory.getLog4jMarker(marker));
58 return this;
59 }
60
61 @Override
62 public LoggingEventBuilder addArgument(Object p) {
63 arguments.add(p);
64 return this;
65 }
66
67 @Override
68 public LoggingEventBuilder addArgument(Supplier<?> objectSupplier) {
69 arguments.add(objectSupplier.get());
70 return this;
71 }
72
73 @Override
74 public LoggingEventBuilder addKeyValue(String key, Object value) {
75 if (keyValuePairs == null) {
76 keyValuePairs = new HashMap<>();
77 }
78 keyValuePairs.put(key, String.valueOf(value));
79 return this;
80 }
81
82 @Override
83 public LoggingEventBuilder addKeyValue(String key, Supplier<Object> valueSupplier) {
84 if (keyValuePairs == null) {
85 keyValuePairs = new HashMap<>();
86 }
87 keyValuePairs.put(key, String.valueOf(valueSupplier.get()));
88 return this;
89 }
90
91 @Override
92 public LoggingEventBuilder setMessage(String message) {
93 this.message = message;
94 return this;
95 }
96
97 @Override
98 public LoggingEventBuilder setMessage(Supplier<String> messageSupplier) {
99 this.message = messageSupplier.get();
100 return this;
101 }
102
103 @Override
104 public void log() {
105 if (keyValuePairs == null || keyValuePairs.isEmpty()) {
106 logBuilder.log(message, arguments.toArray());
107 } else {
108 try (Instance c = CloseableThreadContext.putAll(keyValuePairs)) {
109 logBuilder.log(message, arguments.toArray());
110 }
111 }
112 }
113
114 @Override
115 public void log(String message) {
116 setMessage(message);
117 log();
118 }
119
120 @Override
121 public void log(String message, Object arg) {
122 setMessage(message);
123 addArgument(arg);
124 log();
125 }
126
127 @Override
128 public void log(String message, Object arg0, Object arg1) {
129 setMessage(message);
130 addArgument(arg0);
131 addArgument(arg1);
132 log();
133 }
134
135 @Override
136 public void log(String message, Object... args) {
137 setMessage(message);
138 for (final Object arg : args) {
139 addArgument(arg);
140 }
141 log();
142 }
143
144 @Override
145 public void log(Supplier<String> messageSupplier) {
146 setMessage(messageSupplier);
147 log();
148 }
149
150 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import java.io.IOException;
19 import java.io.ObjectInputStream;
20 import java.io.ObjectOutputStream;
21 import java.io.Serializable;
22
23 import org.apache.logging.log4j.Level;
24 import org.apache.logging.log4j.LogManager;
25 import org.apache.logging.log4j.message.Message;
26 import org.apache.logging.log4j.message.ParameterizedMessage;
27 import org.apache.logging.log4j.message.SimpleMessage;
28 import org.apache.logging.log4j.spi.ExtendedLogger;
29 import org.slf4j.Marker;
30 import org.slf4j.spi.LocationAwareLogger;
31 import org.slf4j.spi.LoggingEventBuilder;
32 import org.slf4j.spi.NOPLoggingEventBuilder;
33
34 /**
35 * SLF4J logger implementation that uses Log4j.
36 */
37 public class Log4jLogger implements LocationAwareLogger, Serializable {
38
39 public static final String FQCN = Log4jLogger.class.getName();
40
41 private static final long serialVersionUID = 7869000638091304316L;
42 private transient ExtendedLogger logger;
43 private final String name;
44 private transient Log4jMarkerFactory markerFactory;
45
46 public Log4jLogger(final Log4jMarkerFactory markerFactory, final ExtendedLogger logger, final String name) {
47 this.markerFactory = markerFactory;
48 this.logger = logger;
49 this.name = name;
50 }
51
52 @Override
53 public void trace(final String format) {
54 logger.logIfEnabled(FQCN, Level.TRACE, null, format);
55 }
56
57 @Override
58 public void trace(final String format, final Object o) {
59 logger.logIfEnabled(FQCN, Level.TRACE, null, format, o);
60 }
61
62 @Override
63 public void trace(final String format, final Object arg1, final Object arg2) {
64 logger.logIfEnabled(FQCN, Level.TRACE, null, format, arg1, arg2);
65 }
66
67 @Override
68 public void trace(final String format, final Object... args) {
69 logger.logIfEnabled(FQCN, Level.TRACE, null, format, args);
70 }
71
72 @Override
73 public void trace(final String format, final Throwable t) {
74 logger.logIfEnabled(FQCN, Level.TRACE, null, format, t);
75 }
76
77 @Override
78 public boolean isTraceEnabled() {
79 return logger.isEnabled(Level.TRACE, null, null);
80 }
81
82 @Override
83 public boolean isTraceEnabled(final Marker marker) {
84 return logger.isEnabled(Level.TRACE, markerFactory.getLog4jMarker(marker), null);
85 }
86
87 @Override
88 public void trace(final Marker marker, final String s) {
89 logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s);
90 }
91
92 @Override
93 public void trace(final Marker marker, final String s, final Object o) {
94 logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s, o);
95 }
96
97 @Override
98 public void trace(final Marker marker, final String s, final Object o, final Object o1) {
99 logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s, o, o1);
100 }
101
102 @Override
103 public void trace(final Marker marker, final String s, final Object... objects) {
104 logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s, objects);
105 }
106
107 @Override
108 public void trace(final Marker marker, final String s, final Throwable throwable) {
109 logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s, throwable);
110 }
111
112 @Override
113 public void debug(final String format) {
114 logger.logIfEnabled(FQCN, Level.DEBUG, null, format);
115 }
116
117 @Override
118 public void debug(final String format, final Object o) {
119 logger.logIfEnabled(FQCN, Level.DEBUG, null, format, o);
120 }
121
122 @Override
123 public void debug(final String format, final Object arg1, final Object arg2) {
124 logger.logIfEnabled(FQCN, Level.DEBUG, null, format, arg1, arg2);
125 }
126
127 @Override
128 public void debug(final String format, final Object... args) {
129 logger.logIfEnabled(FQCN, Level.DEBUG, null, format, args);
130 }
131
132 @Override
133 public void debug(final String format, final Throwable t) {
134 logger.logIfEnabled(FQCN, Level.DEBUG, null, format, t);
135 }
136
137 @Override
138 public boolean isDebugEnabled() {
139 return logger.isEnabled(Level.DEBUG, null, null);
140 }
141
142 @Override
143 public boolean isDebugEnabled(final Marker marker) {
144 return logger.isEnabled(Level.DEBUG, markerFactory.getLog4jMarker(marker), null);
145 }
146
147 @Override
148 public void debug(final Marker marker, final String s) {
149 logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s);
150 }
151
152 @Override
153 public void debug(final Marker marker, final String s, final Object o) {
154 logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s, o);
155 }
156
157 @Override
158 public void debug(final Marker marker, final String s, final Object o, final Object o1) {
159 logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s, o, o1);
160 }
161
162 @Override
163 public void debug(final Marker marker, final String s, final Object... objects) {
164 logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s, objects);
165 }
166
167 @Override
168 public void debug(final Marker marker, final String s, final Throwable throwable) {
169 logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s, throwable);
170 }
171
172 @Override
173 public void info(final String format) {
174 logger.logIfEnabled(FQCN, Level.INFO, null, format);
175 }
176
177 @Override
178 public void info(final String format, final Object o) {
179 logger.logIfEnabled(FQCN, Level.INFO, null, format, o);
180 }
181
182 @Override
183 public void info(final String format, final Object arg1, final Object arg2) {
184 logger.logIfEnabled(FQCN, Level.INFO, null, format, arg1, arg2);
185 }
186
187 @Override
188 public void info(final String format, final Object... args) {
189 logger.logIfEnabled(FQCN, Level.INFO, null, format, args);
190 }
191
192 @Override
193 public void info(final String format, final Throwable t) {
194 logger.logIfEnabled(FQCN, Level.INFO, null, format, t);
195 }
196
197 @Override
198 public boolean isInfoEnabled() {
199 return logger.isEnabled(Level.INFO, null, null);
200 }
201
202 @Override
203 public boolean isInfoEnabled(final Marker marker) {
204 return logger.isEnabled(Level.INFO, markerFactory.getLog4jMarker(marker), null);
205 }
206
207 @Override
208 public void info(final Marker marker, final String s) {
209 logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s);
210 }
211
212 @Override
213 public void info(final Marker marker, final String s, final Object o) {
214 logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s, o);
215 }
216
217 @Override
218 public void info(final Marker marker, final String s, final Object o, final Object o1) {
219 logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s, o, o1);
220 }
221
222 @Override
223 public void info(final Marker marker, final String s, final Object... objects) {
224 logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s, objects);
225 }
226
227 @Override
228 public void info(final Marker marker, final String s, final Throwable throwable) {
229 logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s, throwable);
230 }
231
232 @Override
233 public void warn(final String format) {
234 logger.logIfEnabled(FQCN, Level.WARN, null, format);
235 }
236
237 @Override
238 public void warn(final String format, final Object o) {
239 logger.logIfEnabled(FQCN, Level.WARN, null, format, o);
240 }
241
242 @Override
243 public void warn(final String format, final Object arg1, final Object arg2) {
244 logger.logIfEnabled(FQCN, Level.WARN, null, format, arg1, arg2);
245 }
246
247 @Override
248 public void warn(final String format, final Object... args) {
249 logger.logIfEnabled(FQCN, Level.WARN, null, format, args);
250 }
251
252 @Override
253 public void warn(final String format, final Throwable t) {
254 logger.logIfEnabled(FQCN, Level.WARN, null, format, t);
255 }
256
257 @Override
258 public boolean isWarnEnabled() {
259 return logger.isEnabled(Level.WARN, null, null);
260 }
261
262 @Override
263 public boolean isWarnEnabled(final Marker marker) {
264 return logger.isEnabled(Level.WARN, markerFactory.getLog4jMarker(marker), null);
265 }
266
267 @Override
268 public void warn(final Marker marker, final String s) {
269 logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s);
270 }
271
272 @Override
273 public void warn(final Marker marker, final String s, final Object o) {
274 logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s, o);
275 }
276
277 @Override
278 public void warn(final Marker marker, final String s, final Object o, final Object o1) {
279 logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s, o, o1);
280 }
281
282 @Override
283 public void warn(final Marker marker, final String s, final Object... objects) {
284 logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s, objects);
285 }
286
287 @Override
288 public void warn(final Marker marker, final String s, final Throwable throwable) {
289 logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s, throwable);
290 }
291
292 @Override
293 public void error(final String format) {
294 logger.logIfEnabled(FQCN, Level.ERROR, null, format);
295 }
296
297 @Override
298 public void error(final String format, final Object o) {
299 logger.logIfEnabled(FQCN, Level.ERROR, null, format, o);
300 }
301
302 @Override
303 public void error(final String format, final Object arg1, final Object arg2) {
304 logger.logIfEnabled(FQCN, Level.ERROR, null, format, arg1, arg2);
305 }
306
307 @Override
308 public void error(final String format, final Object... args) {
309 logger.logIfEnabled(FQCN, Level.ERROR, null, format, args);
310 }
311
312 @Override
313 public void error(final String format, final Throwable t) {
314 logger.logIfEnabled(FQCN, Level.ERROR, null, format, t);
315 }
316
317 @Override
318 public boolean isErrorEnabled() {
319 return logger.isEnabled(Level.ERROR, null, null);
320 }
321
322 @Override
323 public boolean isErrorEnabled(final Marker marker) {
324 return logger.isEnabled(Level.ERROR, markerFactory.getLog4jMarker(marker), null);
325 }
326
327 @Override
328 public void error(final Marker marker, final String s) {
329 logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s);
330 }
331
332 @Override
333 public void error(final Marker marker, final String s, final Object o) {
334 logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s, o);
335 }
336
337 @Override
338 public void error(final Marker marker, final String s, final Object o, final Object o1) {
339 logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s, o, o1);
340 }
341
342 @Override
343 public void error(final Marker marker, final String s, final Object... objects) {
344 logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s, objects);
345 }
346
347 @Override
348 public void error(final Marker marker, final String s, final Throwable throwable) {
349 logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s, throwable);
350 }
351
352 @Override
353 public void log(final Marker marker, final String fqcn, final int level, final String message, final Object[] params, final Throwable throwable) {
354 final Level log4jLevel = getLevel(level);
355 final org.apache.logging.log4j.Marker log4jMarker = markerFactory.getLog4jMarker(marker);
356
357 if (!logger.isEnabled(log4jLevel, log4jMarker, message, params)) {
358 return;
359 }
360 final Message msg;
361 final Throwable actualThrowable;
362 if (params == null) {
363 msg = new SimpleMessage(message);
364 actualThrowable = throwable;
365 } else {
366 msg = new ParameterizedMessage(message, params, throwable);
367 actualThrowable = throwable != null ? throwable : msg.getThrowable();
368 }
369 logger.logMessage(fqcn, log4jLevel, log4jMarker, msg, actualThrowable);
370 }
371
372 @Override
373 public String getName() {
374 return name;
375 }
376
377 /**
378 * Always treat de-serialization as a full-blown constructor, by validating the final state of
379 * the de-serialized object.
380 */
381 private void readObject(final ObjectInputStream aInputStream) throws ClassNotFoundException, IOException {
382 // always perform the default de-serialization first
383 aInputStream.defaultReadObject();
384 logger = LogManager.getContext().getLogger(name);
385 markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory();
386 }
387
388 /**
389 * This is the default implementation of writeObject. Customise if necessary.
390 */
391 private void writeObject(final ObjectOutputStream aOutputStream) throws IOException {
392 // perform the default serialization for all non-transient, non-static fields
393 aOutputStream.defaultWriteObject();
394 }
395
396 private static Level getLevel(final int i) {
397 switch (i) {
398 case TRACE_INT:
399 return Level.TRACE;
400 case DEBUG_INT:
401 return Level.DEBUG;
402 case INFO_INT:
403 return Level.INFO;
404 case WARN_INT:
405 return Level.WARN;
406 case ERROR_INT:
407 return Level.ERROR;
408 }
409 return Level.ERROR;
410 }
411
412 @Override
413 public LoggingEventBuilder makeLoggingEventBuilder(org.slf4j.event.Level level) {
414 final Level log4jLevel = getLevel(level.toInt());
415 if (logger.isEnabled(log4jLevel)) {
416 return new Log4jEventBuilder(markerFactory, logger.atLevel(log4jLevel));
417 }
418 return NOPLoggingEventBuilder.singleton();
419 }
420
421 @Override
422 public LoggingEventBuilder atTrace() {
423 if (logger.isTraceEnabled()) {
424 return new Log4jEventBuilder(markerFactory, logger.atTrace());
425 }
426 return NOPLoggingEventBuilder.singleton();
427 }
428
429 @Override
430 public LoggingEventBuilder atDebug() {
431 if (logger.isDebugEnabled()) {
432 return new Log4jEventBuilder(markerFactory, logger.atDebug());
433 }
434 return NOPLoggingEventBuilder.singleton();
435 }
436
437 @Override
438 public LoggingEventBuilder atInfo() {
439 if (logger.isInfoEnabled()) {
440 return new Log4jEventBuilder(markerFactory, logger.atInfo());
441 }
442 return NOPLoggingEventBuilder.singleton();
443 }
444
445 @Override
446 public LoggingEventBuilder atWarn() {
447 if (logger.isWarnEnabled()) {
448 return new Log4jEventBuilder(markerFactory, logger.atWarn());
449 }
450 return NOPLoggingEventBuilder.singleton();
451 }
452
453 @Override
454 public LoggingEventBuilder atError() {
455 if (logger.isErrorEnabled()) {
456 return new Log4jEventBuilder(markerFactory, logger.atError());
457 }
458 return NOPLoggingEventBuilder.singleton();
459 }
460
461 @Override
462 public boolean isEnabledForLevel(org.slf4j.event.Level level) {
463 return logger.isEnabled(getLevel(level.toInt()));
464 }
465
466
467 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import org.apache.logging.log4j.LogManager;
19 import org.apache.logging.log4j.LoggingException;
20 import org.apache.logging.log4j.spi.AbstractLoggerAdapter;
21 import org.apache.logging.log4j.spi.LoggerContext;
22 import org.apache.logging.log4j.status.StatusLogger;
23 import org.apache.logging.log4j.util.StackLocatorUtil;
24 import org.slf4j.ILoggerFactory;
25 import org.slf4j.Logger;
26
27 import java.util.function.Predicate;
28
29 /**
30 * Log4j implementation of SLF4J ILoggerFactory interface.
31 */
32 public class Log4jLoggerFactory extends AbstractLoggerAdapter<Logger> implements ILoggerFactory {
33
34 private static final StatusLogger LOGGER = StatusLogger.getLogger();
35 private static final String SLF4J_PACKAGE = "org.slf4j";
36 private static final Predicate<Class<?>> CALLER_PREDICATE = clazz ->
37 !AbstractLoggerAdapter.class.equals(clazz) && !clazz.getName().startsWith(SLF4J_PACKAGE);
38 private static final String TO_SLF4J_CONTEXT = "org.apache.logging.slf4j.SLF4JLoggerContext";
39
40 private final Log4jMarkerFactory markerFactory;
41
42 public Log4jLoggerFactory(final Log4jMarkerFactory markerFactory) {
43 this.markerFactory = markerFactory;
44 }
45
46 @Override
47 protected Logger newLogger(final String name, final LoggerContext context) {
48 final String key = Logger.ROOT_LOGGER_NAME.equals(name) ? LogManager.ROOT_LOGGER_NAME : name;
49 return new Log4jLogger(markerFactory, validateContext(context).getLogger(key), name);
50 }
51
52 @Override
53 protected LoggerContext getContext() {
54 final Class<?> anchor = LogManager.getFactory().isClassLoaderDependent()
55 ? StackLocatorUtil.getCallerClass(Log4jLoggerFactory.class, CALLER_PREDICATE)
56 : null;
57 LOGGER.trace("Log4jLoggerFactory.getContext() found anchor {}", anchor);
58 return anchor == null
59 ? LogManager.getContext(false)
60 : getContext(anchor);
61 }
62
63 Log4jMarkerFactory getMarkerFactory() {
64 return markerFactory;
65 }
66
67 private LoggerContext validateContext(final LoggerContext context) {
68 if (TO_SLF4J_CONTEXT.equals(context.getClass().getName())) {
69 throw new LoggingException("log4j-slf4j-impl cannot be present with log4j-to-slf4j");
70 }
71 return context;
72 }
73 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import java.util.ArrayDeque;
19 import java.util.Deque;
20 import java.util.HashMap;
21 import java.util.Map;
22 import java.util.Objects;
23
24 import org.apache.logging.log4j.Logger;
25 import org.apache.logging.log4j.ThreadContext;
26 import org.apache.logging.log4j.ThreadContext.ContextStack;
27 import org.apache.logging.log4j.status.StatusLogger;
28 import org.slf4j.spi.MDCAdapter;
29
30 /**
31 *
32 */
33 public class Log4jMDCAdapter implements MDCAdapter {
34
35 private static Logger LOGGER = StatusLogger.getLogger();
36
37 private final ThreadLocalMapOfStacks mapOfStacks = new ThreadLocalMapOfStacks();
38
39 @Override
40 public void put(final String key, final String val) {
41 ThreadContext.put(key, val);
42 }
43
44 @Override
45 public String get(final String key) {
46 return ThreadContext.get(key);
47 }
48
49 @Override
50 public void remove(final String key) {
51 ThreadContext.remove(key);
52 }
53
54 @Override
55 public void clear() {
56 ThreadContext.clearMap();
57 }
58
59 @Override
60 public Map<String, String> getCopyOfContextMap() {
61 return ThreadContext.getContext();
62 }
63
64 @Override
65 public void setContextMap(final Map<String, String> map) {
66 ThreadContext.clearMap();
67 ThreadContext.putAll(map);
68 }
69
70 @Override
71 public void pushByKey(String key, String value) {
72 if (key == null) {
73 ThreadContext.push(value);
74 } else {
75 final String oldValue = mapOfStacks.peekByKey(key);
76 if (!Objects.equals(ThreadContext.get(key), oldValue)) {
77 LOGGER.warn("The key {} was used in both the string and stack-valued MDC.", key);
78 }
79 mapOfStacks.pushByKey(key, value);
80 ThreadContext.put(key, value);
81 }
82 }
83
84 @Override
85 public String popByKey(String key) {
86 if (key == null) {
87 return ThreadContext.getDepth() > 0 ? ThreadContext.pop() : null;
88 }
89 final String value = mapOfStacks.popByKey(key);
90 if (!Objects.equals(ThreadContext.get(key), value)) {
91 LOGGER.warn("The key {} was used in both the string and stack-valued MDC.", key);
92 }
93 ThreadContext.put(key, mapOfStacks.peekByKey(key));
94 return value;
95 }
96
97 @Override
98 public Deque<String> getCopyOfDequeByKey(String key) {
99 if (key == null) {
100 final ContextStack stack = ThreadContext.getImmutableStack();
101 final Deque<String> copy = new ArrayDeque<>(stack.size());
102 stack.forEach(copy::push);
103 return copy;
104 }
105 return mapOfStacks.getCopyOfDequeByKey(key);
106 }
107
108 @Override
109 public void clearDequeByKey(String key) {
110 if (key == null) {
111 ThreadContext.clearStack();
112 } else {
113 mapOfStacks.clearByKey(key);
114 ThreadContext.put(key, null);
115 }
116 }
117
118 private static class ThreadLocalMapOfStacks {
119
120 private final ThreadLocal<Map<String, Deque<String>>> tlMapOfStacks = ThreadLocal.withInitial(HashMap::new);
121
122 public void pushByKey(String key, String value) {
123 tlMapOfStacks.get()
124 .computeIfAbsent(key, ignored -> new ArrayDeque<>())
125 .push(value);
126 }
127
128 public String popByKey(String key) {
129 final Deque<String> deque = tlMapOfStacks.get().get(key);
130 return deque != null ? deque.poll() : null;
131 }
132
133 public Deque<String> getCopyOfDequeByKey(String key) {
134 final Deque<String> deque = tlMapOfStacks.get().get(key);
135 return deque != null ? new ArrayDeque<>(deque) : null;
136 }
137
138 public void clearByKey(String key) {
139 final Deque<String> deque = tlMapOfStacks.get().get(key);
140 if (deque != null) {
141 deque.clear();
142 }
143 }
144
145 public String peekByKey(String key) {
146 final Deque<String> deque = tlMapOfStacks.get().get(key);
147 return deque != null ? deque.peek() : null;
148 }
149 }
150 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import java.util.ArrayList;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.Objects;
22
23 import org.apache.logging.log4j.MarkerManager;
24 import org.slf4j.IMarkerFactory;
25 import org.slf4j.Marker;
26
27 /**
28 * Log4j/SLF4J {@link Marker} type bridge.
29 */
30 class Log4jMarker implements Marker {
31
32 public static final long serialVersionUID = 1590472L;
33
34 private final IMarkerFactory factory;
35
36 private final org.apache.logging.log4j.Marker marker;
37
38 /**
39 * Constructs a Log4jMarker using an existing Log4j {@link org.apache.logging.log4j.Marker}.
40 * @param marker The Log4j Marker upon which to base this Marker.
41 */
42 public Log4jMarker(final IMarkerFactory markerFactory, final org.apache.logging.log4j.Marker marker) {
43 this.factory = markerFactory;
44 this.marker = marker;
45 }
46
47 @Override
48 public void add(final Marker marker) {
49 if (marker == null) {
50 throw new IllegalArgumentException();
51 }
52 final Marker m = factory.getMarker(marker.getName());
53 this.marker.addParents(((Log4jMarker)m).getLog4jMarker());
54 }
55
56 @Override
57 public boolean contains(final Marker marker) {
58 if (marker == null) {
59 throw new IllegalArgumentException();
60 }
61 return this.marker.isInstanceOf(marker.getName());
62 }
63
64 @Override
65 public boolean contains(final String s) {
66 return s != null ? this.marker.isInstanceOf(s) : false;
67 }
68
69 @Override
70 public boolean equals(final Object obj) {
71 if (this == obj) {
72 return true;
73 }
74 if (obj == null) {
75 return false;
76 }
77 if (!(obj instanceof Log4jMarker)) {
78 return false;
79 }
80 final Log4jMarker other = (Log4jMarker) obj;
81 if (!Objects.equals(marker, other.marker)) {
82 return false;
83 }
84 return true;
85 }
86
87 public org.apache.logging.log4j.Marker getLog4jMarker() {
88 return marker;
89 }
90
91 @Override
92 public String getName() {
93 return marker.getName();
94 }
95
96 @Override
97 public boolean hasChildren() {
98 return marker.hasParents();
99 }
100
101 @Override
102 public int hashCode() {
103 return 31 + Objects.hashCode(marker);
104 }
105
106 @Override
107 public boolean hasReferences() {
108 return marker.hasParents();
109 }
110
111 @Override
112 public Iterator<Marker> iterator() {
113 final org.apache.logging.log4j.Marker[] log4jParents = this.marker.getParents();
114 final List<Marker> parents = new ArrayList<>(log4jParents.length);
115 for (final org.apache.logging.log4j.Marker m : log4jParents) {
116 parents.add(factory.getMarker(m.getName()));
117 }
118 return parents.iterator();
119 }
120
121 @Override
122 public boolean remove(final Marker marker) {
123 return marker != null ? this.marker.remove(MarkerManager.getMarker(marker.getName())) : false;
124 }
125 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Iterator;
21 import java.util.concurrent.ConcurrentHashMap;
22 import java.util.concurrent.ConcurrentMap;
23
24 import org.apache.logging.log4j.Logger;
25 import org.apache.logging.log4j.MarkerManager;
26 import org.apache.logging.log4j.status.StatusLogger;
27 import org.slf4j.IMarkerFactory;
28 import org.slf4j.Marker;
29
30 /**
31 * Log4j/SLF4J bridge to create SLF4J Markers based on name or based on existing SLF4J Markers.
32 */
33 public class Log4jMarkerFactory implements IMarkerFactory {
34
35 private static final Logger LOGGER = StatusLogger.getLogger();
36
37 private final ConcurrentMap<String, Marker> markerMap = new ConcurrentHashMap<>();
38
39 /**
40 * Returns a Log4j Marker that is compatible with SLF4J.
41 * @param name The name of the Marker.
42 * @return A Marker.
43 */
44 @Override
45 public Marker getMarker(final String name) {
46 if (name == null) {
47 throw new IllegalArgumentException("Marker name must not be null");
48 }
49 final Marker marker = markerMap.get(name);
50 if (marker != null) {
51 return marker;
52 }
53 final org.apache.logging.log4j.Marker log4jMarker = MarkerManager.getMarker(name);
54 return addMarkerIfAbsent(name, log4jMarker);
55 }
56
57 private Marker addMarkerIfAbsent(final String name, final org.apache.logging.log4j.Marker log4jMarker) {
58 final Marker marker = new Log4jMarker(this, log4jMarker);
59 final Marker existing = markerMap.putIfAbsent(name, marker);
60 return existing == null ? marker : existing;
61 }
62
63 /**
64 * Returns a Log4j Marker converted from an existing custom SLF4J Marker.
65 * @param marker The SLF4J Marker to convert.
66 * @return A converted Log4j/SLF4J Marker.
67 * @since 2.1
68 */
69 public Marker getMarker(final Marker marker) {
70 if (marker == null) {
71 throw new IllegalArgumentException("Marker must not be null");
72 }
73 final Marker m = markerMap.get(marker.getName());
74 if (m != null) {
75 return m;
76 }
77 return addMarkerIfAbsent(marker.getName(), convertMarker(marker));
78 }
79
80 /**
81 * Gets the Log4j2 marker associated to this SLF4J marker or creates a new one.
82 *
83 * @param marker a SLF4J marker
84 * @return a Log4j2 marker
85 */
86 org.apache.logging.log4j.Marker getLog4jMarker(final Marker marker) {
87 if (marker == null) {
88 return null;
89 } else if (marker instanceof Log4jMarker) {
90 return ((Log4jMarker) marker).getLog4jMarker();
91 } else {
92 return ((Log4jMarker) getMarker(marker)).getLog4jMarker();
93 }
94 }
95
96 static org.apache.logging.log4j.Marker convertMarker(final Marker original) {
97 if (original == null) {
98 throw new IllegalArgumentException("Marker must not be null");
99 }
100 return convertMarker(original, new ArrayList<Marker>());
101 }
102
103 private static org.apache.logging.log4j.Marker convertMarker(final Marker original,
104 final Collection<Marker> visited) {
105 final org.apache.logging.log4j.Marker marker = MarkerManager.getMarker(original.getName());
106 if (original.hasReferences()) {
107 final Iterator<Marker> it = original.iterator();
108 while (it.hasNext()) {
109 final Marker next = it.next();
110 if (visited.contains(next)) {
111 LOGGER.warn("Found a cycle in Marker [{}]. Cycle will be broken.", next.getName());
112 } else {
113 visited.add(next);
114 marker.addParents(convertMarker(next, visited));
115 }
116 }
117 }
118 return marker;
119 }
120
121 /**
122 * Returns true if the Marker exists.
123 * @param name The Marker name.
124 * @return {@code true} if the Marker exists, {@code false} otherwise.
125 */
126 @Override
127 public boolean exists(final String name) {
128 return markerMap.containsKey(name);
129 }
130
131 /**
132 * Log4j does not support detached Markers. This method always returns false.
133 * @param name The Marker name.
134 * @return {@code false}
135 */
136 @Override
137 public boolean detachMarker(final String name) {
138 return false;
139 }
140
141 /**
142 * Log4j does not support detached Markers for performance reasons. The returned Marker is attached.
143 * @param name The Marker name.
144 * @return The named Marker (unmodified).
145 */
146 @Override
147 public Marker getDetachedMarker(final String name) {
148 LOGGER.warn("Log4j does not support detached Markers. Returned Marker [{}] will be unchanged.", name);
149 return getMarker(name);
150 }
151
152
153 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 /**
19 * Exception thrown when the SLF4J adapter encounters a problem.
20 *
21 */
22 public class SLF4JLoggingException extends RuntimeException {
23
24 /**
25 * Generated serial version ID.
26 */
27 private static final long serialVersionUID = -1618650972455089998L;
28
29 public SLF4JLoggingException(final String msg) {
30 super(msg);
31 }
32
33 public SLF4JLoggingException(final String msg, final Exception ex) {
34 super(msg, ex);
35 }
36
37 public SLF4JLoggingException(final Exception ex) {
38 super(ex);
39 }
40 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import org.slf4j.ILoggerFactory;
19 import org.slf4j.IMarkerFactory;
20 import org.slf4j.spi.MDCAdapter;
21
22 public class SLF4JServiceProvider implements org.slf4j.spi.SLF4JServiceProvider {
23
24 public static final String REQUESTED_API_VERSION = "2.0.99";
25
26 private ILoggerFactory loggerFactory;
27 private Log4jMarkerFactory markerFactory;
28 private MDCAdapter mdcAdapter;
29
30 @Override
31 public ILoggerFactory getLoggerFactory() {
32 return loggerFactory;
33 }
34
35 @Override
36 public IMarkerFactory getMarkerFactory() {
37 return markerFactory;
38 }
39
40 @Override
41 public MDCAdapter getMDCAdapter() {
42 return mdcAdapter;
43 }
44
45 @Override
46 public String getRequestedApiVersion() {
47 return REQUESTED_API_VERSION;
48 }
49
50 @Override
51 public void initialize() {
52 markerFactory = new Log4jMarkerFactory();
53 loggerFactory = new Log4jLoggerFactory(markerFactory);
54 mdcAdapter = new Log4jMDCAdapter();
55 }
56
57
58 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 /**
17 * SLF4J support. Note that this does indeed share the same package namespace as the one found in log4j-to-slf4j;
18 * this is intentional. The two JARs should <em>not</em> be used at the same time! Thus, in an OSGi environment
19 * where split packages are not allowed, this error is prevented due to both JARs sharing an exported package name.
20 */
21 package org.apache.logging.slf4j;
0 <!-- vim: set syn=markdown : -->
1 <!--
2 Licensed to the Apache Software Foundation (ASF) under one or more
3 contributor license agreements. See the NOTICE file distributed with
4 this work for additional information regarding copyright ownership.
5 The ASF licenses this file to You under the Apache License, Version 2.0
6 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 -->
17
18 # Log4j 2 SLF4J Binding
19
20 The Log4j 2 SLF4J Binding allows applications coded to the SLF4J API to use
21 Log4j 2 as the implementation.
22
23 Due to a break in compatibility in the SLF4J binding, as of release 2.19.0 two SLF4J to Log4j Adapters are provided.
24
25 1. `log4j-slf4j-impl` should be used with SLF4J 1.7.x releases or older.
26 1. `log4j-slf4j2-impl` should be used with SLF4J 2.0.x releases or newer.
27
28 Applications that take advantage of the Java Module System should use SLF4J 2.0.x and log4j-slf4j2-impl.
29
30 As of release 2.19.0 the `log4j-slf4j18-impl` module targetting the unreleased SLF4J 1.8.x series has been removed.
31
32 ## Requirements
33
34 The Log4j 2 SLF4J Binding has a dependency on the Log4j 2 API as well as the SLF4J API.
35 For more information, see [Runtime Dependencies](../runtime-dependencies.html).
36
37 ## Usage
38
39 The SLF4J binding provided in this component cause all the SLF4J APIs to be routed to Log4j 2. Simply
40 include the Log4j 2 SLF4J Binding jar along with the Log4j 2 jars and SLF4J API jar to cause all SLF4J
41 logging to be handled by Log4j 2.
42
43 <div class="alert alert-danger">
44 Use of the Log4j 2 SLF4J Binding (log4j-slf4j-impl-2.0.jar) together with
45 the SLF4J adapter (log4j-to-slf4j-2.0.jar) should
46 never be attempted, as it will cause events to endlessly be routed between
47 SLF4J and Log4j 2.
48 </div>
0 <!--
1 Licensed to the Apache Software Foundation (ASF) under one or more
2 contributor license agreements. See the NOTICE file distributed with
3 this work for additional information regarding copyright ownership.
4 The ASF licenses this file to You under the Apache License, Version 2.0
5 (the "License"); you may not use this file except in compliance with
6 the License. You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15
16 -->
17 <project name="SLF4J Binding Using Log4j"
18 xmlns="http://maven.apache.org/DECORATION/1.4.0"
19 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
20 xsi:schemaLocation="http://maven.apache.org/DECORATION/1.4.0 http://maven.apache.org/xsd/decoration-1.4.0.xsd">
21 <body>
22 <links>
23 <item name="Apache" href="http://www.apache.org/" />
24 <item name="Logging Services" href="http://logging.apache.org/"/>
25 <item name="Log4j" href="../index.html"/>
26 </links>
27
28 <!-- Component-specific reports -->
29 <menu ref="reports"/>
30
31 <!-- Overall Project Info -->
32 <menu name="Log4j Project Information" img="icon-info-sign">
33 <item name="Dependencies" href="../dependencies.html" />
34 <item name="Dependency Convergence" href="../dependency-convergence.html" />
35 <item name="Dependency Management" href="../dependency-management.html" />
36 <item name="Project Team" href="../team-list.html" />
37 <item name="Mailing Lists" href="../mail-lists.html" />
38 <item name="Issue Tracking" href="../issue-tracking.html" />
39 <item name="Project License" href="../license.html" />
40 <item name="Source Repository" href="../source-repository.html" />
41 <item name="Project Summary" href="../project-summary.html" />
42 </menu>
43
44 <menu name="Log4j Project Reports" img="icon-cog">
45 <item name="Changes Report" href="../changes-report.html" />
46 <item name="JIRA Report" href="../jira-report.html" />
47 <item name="Surefire Report" href="../surefire-report.html" />
48 <item name="RAT Report" href="../rat-report.html" />
49 </menu>
50 </body>
51 </project>
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.other.pkg;
17
18 import org.apache.logging.log4j.Level;
19 import org.apache.logging.log4j.status.StatusData;
20 import org.apache.logging.log4j.status.StatusListener;
21 import org.apache.logging.log4j.status.StatusLogger;
22 import org.junit.Test;
23 import org.slf4j.LoggerFactory;
24
25 import java.util.List;
26 import java.util.concurrent.CopyOnWriteArrayList;
27
28 import static org.junit.Assert.assertEquals;
29
30 /**
31 * Test LoggerContext lookups by verifying the anchor class representing calling code.
32 */
33 public class LoggerContextAnchorTest {
34 private static final String PREFIX = "Log4jLoggerFactory.getContext() found anchor class ";
35
36 @Test
37 public void testLoggerFactoryLookupClass() {
38 String fqcn = getAnchorFqcn(() -> LoggerFactory.getLogger(LoggerContextAnchorTest.class));
39 assertEquals(getClass().getName(), fqcn);
40 }
41
42 @Test
43 public void testLoggerFactoryLookupString() {
44 String fqcn = getAnchorFqcn(() -> LoggerFactory.getLogger("custom.logger"));
45 assertEquals(getClass().getName(), fqcn);
46 }
47
48 @Test
49 public void testLoggerFactoryGetILoggerFactoryLookup() {
50 String fqcn = getAnchorFqcn(() -> LoggerFactory.getILoggerFactory().getLogger("custom.logger"));
51 assertEquals(getClass().getName(), fqcn);
52 }
53
54 private static String getAnchorFqcn(Runnable runnable) {
55 List<String> results = new CopyOnWriteArrayList<>();
56 StatusListener listener = new StatusListener() {
57 @Override
58 public void log(StatusData data) {
59 String formattedMessage = data.getMessage().getFormattedMessage();
60 if (formattedMessage.startsWith(PREFIX)) {
61 results.add(formattedMessage.substring(PREFIX.length()));
62 }
63 }
64
65 @Override
66 public Level getStatusLevel() {
67 return Level.TRACE;
68 }
69
70 @Override
71 public void close() {
72 // nop
73 }
74 };
75 StatusLogger statusLogger = StatusLogger.getLogger();
76 statusLogger.registerListener(listener);
77 try {
78 runnable.run();
79 if (results.isEmpty()) {
80 throw new AssertionError("Failed to locate an anchor lookup status message");
81 }
82 if (results.size() > 1) {
83 throw new AssertionError("Found multiple anchor lines: " + results);
84 }
85 return results.get(0);
86 } finally {
87 statusLogger.removeListener(listener);
88 }
89 }
90 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import static org.junit.Assert.assertEquals;
19
20 import java.util.List;
21
22 import org.apache.logging.log4j.junit.LoggerContextRule;
23 import org.apache.logging.log4j.test.appender.ListAppender;
24 import org.junit.ClassRule;
25 import org.junit.Test;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 public class CallerInformationTest {
30
31 // config from log4j-core test-jar
32 private static final String CONFIG = "log4j2-calling-class.xml";
33
34 @ClassRule
35 public static final LoggerContextRule ctx = new LoggerContextRule(CONFIG);
36
37 @Test
38 public void testClassLogger() throws Exception {
39 final ListAppender app = ctx.getListAppender("Class").clear();
40 final Logger logger = LoggerFactory.getLogger("ClassLogger");
41 logger.info("Ignored message contents.");
42 logger.warn("Verifying the caller class is still correct.");
43 logger.error("Hopefully nobody breaks me!");
44 logger.atInfo().log("Ignored message contents.");
45 logger.atWarn().log("Verifying the caller class is still correct.");
46 logger.atError().log("Hopefully nobody breaks me!");
47 final List<String> messages = app.getMessages();
48 assertEquals("Incorrect number of messages.", 6, messages.size());
49 for (final String message : messages) {
50 assertEquals("Incorrect caller class name.", this.getClass().getName(), message);
51 }
52 }
53
54 @Test
55 public void testMethodLogger() throws Exception {
56 final ListAppender app = ctx.getListAppender("Method").clear();
57 final Logger logger = LoggerFactory.getLogger("MethodLogger");
58 logger.info("More messages.");
59 logger.warn("CATASTROPHE INCOMING!");
60 logger.error("ZOMBIES!!!");
61 logger.warn("brains~~~");
62 logger.info("Itchy. Tasty.");
63 logger.atInfo().log("More messages.");
64 logger.atWarn().log("CATASTROPHE INCOMING!");
65 logger.atError().log("ZOMBIES!!!");
66 logger.atWarn().log("brains~~~");
67 logger.atInfo().log("Itchy. Tasty.");
68 final List<String> messages = app.getMessages();
69 assertEquals("Incorrect number of messages.", 10, messages.size());
70 for (final String message : messages) {
71 assertEquals("Incorrect caller method name.", "testMethodLogger", message);
72 }
73 }
74 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16
17 package org.apache.logging.slf4j;
18
19 import java.util.Iterator;
20
21 import org.slf4j.Marker;
22
23 /**
24 * Test Marker that may contain no reference/parent Markers.
25 * @see <a href="https://issues.apache.org/jira/browse/LOG4J2-793">LOG4J2-793</a>
26 */
27 public class CustomFlatMarker implements Marker {
28 private static final long serialVersionUID = -4115520883240247266L;
29
30 private final String name;
31
32 public CustomFlatMarker(final String name) {
33 this.name = name;
34 }
35
36 @Override
37 public String getName() {
38 return name;
39 }
40
41 @Override
42 public void add(final Marker reference) {
43 throw new UnsupportedOperationException();
44 }
45
46 @Override
47 public boolean remove(final Marker reference) {
48 throw new UnsupportedOperationException();
49 }
50
51 @Override
52 public boolean hasChildren() {
53 return hasReferences();
54 }
55
56 @Override
57 public boolean hasReferences() {
58 return false;
59 }
60
61 @Override
62 public Iterator<Marker> iterator() {
63 throw new UnsupportedOperationException();
64 }
65
66 @Override
67 public boolean contains(final Marker other) {
68 return false;
69 }
70
71 @Override
72 public boolean contains(final String name) {
73 return false;
74 }
75 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import org.junit.Test;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 import static org.junit.Assert.*;
23
24 /**
25 * Tests logging during shutdown.
26 */
27 public class Log4j1222Test
28 {
29
30 @Test
31 public void homepageRendersSuccessfully()
32 {
33 System.setProperty("log4j.configurationFile", "log4j2-console.xml");
34 Runtime.getRuntime().addShutdownHook(new ShutdownHook());
35 }
36
37 private static class ShutdownHook extends Thread {
38
39 private static class Holder {
40 private static final Logger LOGGER = LoggerFactory.getLogger(Log4j1222Test.class);
41 }
42
43 @Override
44 public void run()
45 {
46 super.run();
47 trigger();
48 }
49
50 private void trigger() {
51 Holder.LOGGER.info("Attempt to trigger");
52 assertTrue("Logger is of type " + Holder.LOGGER.getClass().getName(), Holder.LOGGER instanceof Log4jLogger);
53
54 }
55 }
56 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16
17 package org.apache.logging.slf4j;
18
19 import org.apache.logging.log4j.core.layout.Log4j2_1482_Test;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 /**
24 * Tests https://issues.apache.org/jira/browse/LOG4J2-1482
25 */
26 public class Log4j2_1482_Slf4jTest extends Log4j2_1482_Test {
27
28 @Override
29 protected void log(final int runNumber) {
30 if (runNumber == 2) {
31 // System.out.println("Set a breakpoint here.");
32 }
33 final Logger logger = LoggerFactory.getLogger("auditcsvfile");
34 final int val1 = 9, val2 = 11, val3 = 12;
35 logger.info("Info Message!", val1, val2, val3);
36 logger.info("Info Message!", val1, val2, val3);
37 logger.info("Info Message!", val1, val2, val3);
38 }
39
40 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import static org.assertj.core.api.Assertions.assertThat;
19
20 import java.util.List;
21
22 import org.apache.logging.log4j.core.Appender;
23 import org.apache.logging.log4j.core.LogEvent;
24 import org.apache.logging.log4j.junit.LoggerContextSource;
25 import org.apache.logging.log4j.junit.Named;
26 import org.apache.logging.log4j.test.appender.ListAppender;
27 import org.junit.jupiter.api.BeforeEach;
28 import org.junit.jupiter.api.Test;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 // Config from `log4j-core` test jar.
33 @LoggerContextSource("log4j2-config.xml")
34 public class Log4jEventBuilderTest {
35
36 private final Logger logger;
37 private final ListAppender appender;
38
39 public Log4jEventBuilderTest(@Named("List") Appender appender) {
40 logger = LoggerFactory.getLogger("org.apache.test.Log4jEventBuilderTest");
41 this.appender = (ListAppender) appender;
42 }
43
44 @BeforeEach
45 public void setUp() {
46 appender.clear();
47 }
48
49 @Test
50 public void testKeyValuePairs() {
51 logger.atDebug().addKeyValue("testKeyValuePairs", "ok").log();
52 final List<LogEvent> events = appender.getEvents();
53 assertThat(events).hasSize(1);
54 assertThat(events.get(0).getContextData().toMap()).containsEntry("testKeyValuePairs", "ok");
55 }
56
57 @Test
58 public void testArguments() {
59 logger.atDebug().setMessage("{}-{}").addArgument("a").addArgument("b").log();
60 logger.atDebug().log("{}-{}", "a", "b");
61 logger.atDebug().addArgument("a").log("{}-{}", "b");
62 logger.atDebug().log("{}-{}", new Object[] {"a", "b"});
63 assertThat(appender.getEvents()).hasSize(4)
64 .allMatch(event -> "a-b".equals(event.getMessage().getFormattedMessage()));
65 }
66 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import static org.assertj.core.api.Assertions.assertThat;
19
20 import java.util.ArrayDeque;
21 import java.util.Deque;
22 import java.util.stream.IntStream;
23 import java.util.stream.Stream;
24
25 import org.junit.jupiter.params.ParameterizedTest;
26 import org.junit.jupiter.params.provider.MethodSource;
27
28 public class Log4jMDCAdapterTest {
29
30 private static final Log4jMDCAdapter MDC_ADAPTER = new Log4jMDCAdapter();
31 private static final String KEY = "Log4j2";
32
33 private static Deque<String> createDeque(int size) {
34 final Deque<String> result = new ArrayDeque<>(size);
35 IntStream.range(0, size).mapToObj(Integer::toString).forEach(result::addLast);
36 return result;
37 }
38
39 private static Deque<String> popDeque(String key) {
40 final Deque<String> result = new ArrayDeque<>();
41 String value;
42 while ((value = MDC_ADAPTER.popByKey(key)) != null) {
43 result.addLast(value);
44 }
45 return result;
46 }
47
48 static Stream<String> keys() {
49 return Stream.of(KEY, "", null);
50 }
51
52 @ParameterizedTest
53 @MethodSource("keys")
54 public void testPushPopByKey(final String key) {
55 MDC_ADAPTER.clearDequeByKey(key);
56 final Deque<String> expectedValues = createDeque(100);
57 expectedValues.descendingIterator().forEachRemaining(v -> MDC_ADAPTER.pushByKey(key, v));
58 assertThat(MDC_ADAPTER.getCopyOfDequeByKey(key)).containsExactlyElementsOf(expectedValues);
59 assertThat(popDeque(key)).containsExactlyElementsOf(expectedValues);
60 }
61
62 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import org.apache.logging.log4j.Marker;
19 import org.apache.logging.log4j.MarkerManager;
20 import org.junit.Assert;
21 import org.junit.BeforeClass;
22 import org.junit.Test;
23
24 public class Log4jMarkerTest {
25
26 private static Log4jMarkerFactory markerFactory;
27
28 @BeforeClass
29 public static void startup() {
30 markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory();
31
32 }
33
34 @Test
35 public void testEquals() {
36 final Marker markerA = MarkerManager.getMarker(Log4jMarkerTest.class.getName() + "-A");
37 final Marker markerB = MarkerManager.getMarker(Log4jMarkerTest.class.getName() + "-B");
38 final Log4jMarker marker1 = new Log4jMarker(markerFactory, markerA);
39 final Log4jMarker marker2 = new Log4jMarker(markerFactory, markerA);
40 final Log4jMarker marker3 = new Log4jMarker(markerFactory, markerB);
41 Assert.assertEquals(marker1, marker2);
42 Assert.assertNotEquals(marker1, null);
43 Assert.assertNotEquals(null, marker1);
44 Assert.assertNotEquals(marker1, marker3);
45 }
46 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import org.apache.logging.log4j.core.LifeCycle;
19 import org.apache.logging.log4j.spi.LoggerContext;
20 import org.junit.Test;
21 import org.slf4j.LoggerFactory;
22
23 import java.util.Set;
24
25 import static org.junit.Assert.assertTrue;
26
27 /**
28 * Tests cleanup of the LoggerContexts.
29 */
30 public class LoggerContextTest {
31
32 @Test
33 public void testCleanup() throws Exception {
34 Log4jLoggerFactory factory = (Log4jLoggerFactory) LoggerFactory.getILoggerFactory();
35 factory.getLogger("test");
36 Set<LoggerContext> set = factory.getLoggerContexts();
37 LoggerContext ctx1 = set.toArray(LoggerContext.EMPTY_ARRAY)[0];
38 assertTrue("LoggerContext is not enabled for shutdown", ctx1 instanceof LifeCycle);
39 ((LifeCycle) ctx1).stop();
40 set = factory.getLoggerContexts();
41 assertTrue("Expected no LoggerContexts", set.isEmpty());
42 }
43 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertNotNull;
20 import static org.junit.Assert.assertTrue;
21
22 import java.util.List;
23
24 import org.apache.logging.log4j.core.LogEvent;
25 import org.apache.logging.log4j.junit.LoggerContextRule;
26 import org.apache.logging.log4j.test.appender.ListAppender;
27 import org.apache.logging.log4j.util.Strings;
28 import org.junit.After;
29 import org.junit.Before;
30 import org.junit.ClassRule;
31 import org.junit.Test;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import org.slf4j.MDC;
35 import org.slf4j.Marker;
36 import org.slf4j.ext.XLogger;
37 import org.slf4j.ext.XLoggerFactory;
38 import org.slf4j.spi.LocationAwareLogger;
39
40 /**
41 *
42 */
43 public class LoggerTest {
44
45 private static final String CONFIG = "log4j-test1.xml";
46
47 @ClassRule
48 public static LoggerContextRule ctx = new LoggerContextRule(CONFIG);
49
50 Logger logger = LoggerFactory.getLogger("LoggerTest");
51 XLogger xlogger = XLoggerFactory.getXLogger("LoggerTest");
52
53 @Test
54 public void basicFlow() {
55 xlogger.entry();
56 verify("List", "o.a.l.s.LoggerTest entry MDC{}" + Strings.LINE_SEPARATOR);
57 xlogger.exit();
58 verify("List", "o.a.l.s.LoggerTest exit MDC{}" + Strings.LINE_SEPARATOR);
59 }
60
61 @Test
62 public void simpleFlow() {
63 xlogger.entry(CONFIG);
64 verify("List", "o.a.l.s.LoggerTest entry with (log4j-test1.xml) MDC{}" + Strings.LINE_SEPARATOR);
65 xlogger.exit(0);
66 verify("List", "o.a.l.s.LoggerTest exit with (0) MDC{}" + Strings.LINE_SEPARATOR);
67 }
68
69 @Test
70 public void throwing() {
71 xlogger.throwing(new IllegalArgumentException("Test Exception"));
72 verify("List", "o.a.l.s.LoggerTest throwing MDC{}" + Strings.LINE_SEPARATOR);
73 }
74
75 @Test
76 public void catching() {
77 try {
78 throw new NullPointerException();
79 } catch (final Exception e) {
80 xlogger.catching(e);
81 verify("List", "o.a.l.s.LoggerTest catching MDC{}" + Strings.LINE_SEPARATOR);
82 }
83 }
84
85 @Test
86 public void debug() {
87 logger.debug("Debug message");
88 verify("List", "o.a.l.s.LoggerTest Debug message MDC{}" + Strings.LINE_SEPARATOR);
89 }
90
91 @Test
92 public void debugNoParms() {
93 logger.debug("Debug message {}");
94 verify("List", "o.a.l.s.LoggerTest Debug message {} MDC{}" + Strings.LINE_SEPARATOR);
95 logger.debug("Debug message {}", (Object[]) null);
96 verify("List", "o.a.l.s.LoggerTest Debug message {} MDC{}" + Strings.LINE_SEPARATOR);
97 ((LocationAwareLogger)logger).log(null, Log4jLogger.class.getName(), LocationAwareLogger.DEBUG_INT,
98 "Debug message {}", null, null);
99 verify("List", "o.a.l.s.LoggerTest Debug message {} MDC{}" + Strings.LINE_SEPARATOR);
100 }
101
102
103 @Test
104 public void debugWithParms() {
105 logger.debug("Hello, {}", "World");
106 verify("List", "o.a.l.s.LoggerTest Hello, World MDC{}" + Strings.LINE_SEPARATOR);
107 }
108
109 @Test
110 public void mdc() {
111
112 MDC.put("TestYear", "2010");
113 logger.debug("Debug message");
114 verify("List", "o.a.l.s.LoggerTest Debug message MDC{TestYear=2010}" + Strings.LINE_SEPARATOR);
115 MDC.clear();
116 logger.debug("Debug message");
117 verify("List", "o.a.l.s.LoggerTest Debug message MDC{}" + Strings.LINE_SEPARATOR);
118 }
119
120 @Test
121 public void mdcStack() {
122 MDC.pushByKey("TestYear", "2010");
123 logger.debug("Debug message");
124 verify("List", "o.a.l.s.LoggerTest Debug message MDC{TestYear=2010}" + Strings.LINE_SEPARATOR);
125 MDC.pushByKey("TestYear", "2011");
126 logger.debug("Debug message");
127 verify("List", "o.a.l.s.LoggerTest Debug message MDC{TestYear=2011}" + Strings.LINE_SEPARATOR);
128 MDC.popByKey("TestYear");
129 logger.debug("Debug message");
130 verify("List", "o.a.l.s.LoggerTest Debug message MDC{TestYear=2010}" + Strings.LINE_SEPARATOR);
131 MDC.clear();
132 logger.debug("Debug message");
133 verify("List", "o.a.l.s.LoggerTest Debug message MDC{}" + Strings.LINE_SEPARATOR);
134 }
135
136 /**
137 * @see <a href="https://issues.apache.org/jira/browse/LOG4J2-793">LOG4J2-793</a>
138 */
139 @Test
140 public void supportsCustomSLF4JMarkers() {
141 final Marker marker = new CustomFlatMarker("TEST");
142 logger.debug(marker, "Test");
143 verify("List", "o.a.l.s.LoggerTest Test MDC{}" + Strings.LINE_SEPARATOR);
144 }
145
146 @Test
147 public void testRootLogger() {
148 final Logger l = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
149 assertNotNull("No Root Logger", l);
150 assertEquals(Logger.ROOT_LOGGER_NAME, l.getName());
151 }
152
153 @Test
154 public void doubleSubst() {
155 logger.debug("Hello, {}", "Log4j {}");
156 verify("List", "o.a.l.s.LoggerTest Hello, Log4j {} MDC{}" + Strings.LINE_SEPARATOR);
157 xlogger.debug("Hello, {}", "Log4j {}");
158 verify("List", "o.a.l.s.LoggerTest Hello, Log4j {} MDC{}" + Strings.LINE_SEPARATOR);
159 }
160
161 @Test
162 public void testThrowable() {
163 final Throwable expected = new RuntimeException();
164 logger.debug("Hello {}", expected);
165 verifyThrowable(expected);
166 logger.debug("Hello {}", (Object) expected);
167 verifyThrowable(null);
168 logger.debug("Hello", expected);
169 verifyThrowable(expected);
170 logger.debug("Hello {}! {}", "World!", expected);
171 verifyThrowable(null);
172 logger.debug("Hello {}!", "World!", expected);
173 verifyThrowable(expected);
174 final LocationAwareLogger lal = (LocationAwareLogger) logger;
175 lal.log(null, LoggerTest.class.getName(), LocationAwareLogger.DEBUG_INT, "Hello {}", null, expected);
176 verifyThrowable(expected);
177 lal.log(null, LoggerTest.class.getName(), LocationAwareLogger.DEBUG_INT, "Hello {}", new Object[] { expected },
178 null);
179 verifyThrowable(null);
180 lal.log(null, LoggerTest.class.getName(), LocationAwareLogger.DEBUG_INT, "Hello {}",
181 new Object[] { "World!", expected }, null);
182 verifyThrowable(expected);
183 }
184
185 private ListAppender getAppenderByName(final String name) {
186 final ListAppender listApp = ctx.getListAppender(name);
187 assertNotNull("Missing Appender", listApp);
188 return listApp;
189 }
190
191 private void verify(final String name, final String expected) {
192 final ListAppender listApp = getAppenderByName(name);
193 final List<String> events = listApp.getMessages();
194 assertTrue("Incorrect number of messages. Expected 1 Actual " + events.size(), events.size()== 1);
195 final String actual = events.get(0);
196 assertEquals("Incorrect message. Expected " + expected + ". Actual " + actual, expected, actual);
197 listApp.clear();
198 }
199
200 private void verifyThrowable(final Throwable expected) {
201 final ListAppender listApp = getAppenderByName("UnformattedList");
202 final List<LogEvent> events = listApp.getEvents();
203 assertEquals("Incorrect number of messages", 1, events.size());
204 final LogEvent actual = events.get(0);
205 assertEquals("Incorrect throwable.", expected, actual.getThrown());
206 listApp.clear();
207 }
208
209 @Before
210 @After
211 public void cleanup() {
212 MDC.clear();
213 ctx.getListAppender("List").clear();
214 ctx.getListAppender("UnformattedList").clear();
215 }
216 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import org.apache.logging.log4j.Marker;
19 import org.apache.logging.log4j.MarkerManager;
20 import org.junit.After;
21 import org.junit.Assert;
22 import org.junit.Before;
23 import org.junit.BeforeClass;
24 import org.junit.Test;
25
26 import static org.junit.Assert.*;
27
28 /**
29 *
30 */
31 public class MarkerTest {
32
33 private static final String CHILD_MAKER_NAME = MarkerTest.class.getSimpleName() + "-TEST";
34 private static final String PARENT_MARKER_NAME = MarkerTest.class.getSimpleName() + "-PARENT";
35 private static Log4jMarkerFactory markerFactory;
36
37 @BeforeClass
38 public static void startup() {
39 markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory();
40
41 }
42
43 @Before
44 @After
45 public void clearMarkers() {
46 MarkerManager.clear();
47 }
48
49 @Test
50 public void testAddMarker() {
51 final String childMakerName = CHILD_MAKER_NAME + "-AM";
52 final String parentMarkerName = PARENT_MARKER_NAME + "-AM";
53 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMakerName);
54 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMarkerName);
55 slf4jMarker.add(slf4jParent);
56 final Marker log4jParent = MarkerManager.getMarker(parentMarkerName);
57 final Marker log4jMarker = MarkerManager.getMarker(childMakerName);
58
59 assertTrue("Incorrect Marker class", slf4jMarker instanceof Log4jMarker);
60 assertTrue(String.format("%s (log4jMarker=%s) is not an instance of %s (log4jParent=%s) in Log4j",
61 childMakerName, parentMarkerName, log4jMarker, log4jParent), log4jMarker.isInstanceOf(log4jParent));
62 assertTrue(String.format("%s (slf4jMarker=%s) is not an instance of %s (log4jParent=%s) in SLF4J",
63 childMakerName, parentMarkerName, slf4jMarker, slf4jParent), slf4jMarker.contains(slf4jParent));
64 }
65
66 @Test
67 public void testAddNullMarker() {
68 final String childMarkerName = CHILD_MAKER_NAME + "-ANM";
69 final String parentMakerName = PARENT_MARKER_NAME + "-ANM";
70 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
71 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
72 slf4jMarker.add(slf4jParent);
73 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
74 final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
75 final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
76 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
77 final org.slf4j.Marker nullMarker = null;
78 try {
79 log4jSlf4jParent.add(nullMarker);
80 fail("Expected " + IllegalArgumentException.class.getName());
81 } catch (final IllegalArgumentException e) {
82 // expected
83 }
84 try {
85 log4jSlf4jMarker.add(nullMarker);
86 fail("Expected " + IllegalArgumentException.class.getName());
87 } catch (final IllegalArgumentException e) {
88 // expected
89 }
90 }
91
92 @Test
93 public void testAddSameMarker() {
94 final String childMarkerName = CHILD_MAKER_NAME + "-ASM";
95 final String parentMakerName = PARENT_MARKER_NAME + "-ASM";
96 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
97 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
98 slf4jMarker.add(slf4jParent);
99 slf4jMarker.add(slf4jParent);
100 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
101 final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
102 assertTrue(String.format("%s (log4jMarker=%s) is not an instance of %s (log4jParent=%s) in Log4j",
103 childMarkerName, parentMakerName, log4jMarker, log4jParent), log4jMarker.isInstanceOf(log4jParent));
104 assertTrue(String.format("%s (slf4jMarker=%s) is not an instance of %s (log4jParent=%s) in SLF4J",
105 childMarkerName, parentMakerName, slf4jMarker, slf4jParent), slf4jMarker.contains(slf4jParent));
106 }
107
108 @Test
109 public void testEquals() {
110 final String childMarkerName = CHILD_MAKER_NAME + "-ASM";
111 final String parentMakerName = PARENT_MARKER_NAME + "-ASM";
112 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
113 final org.slf4j.Marker slf4jMarker2 = org.slf4j.MarkerFactory.getMarker(childMarkerName);
114 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
115 slf4jMarker.add(slf4jParent);
116 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
117 final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
118 final Marker log4jMarker2 = MarkerManager.getMarker(childMarkerName);
119 assertEquals(log4jParent, log4jParent);
120 assertEquals(log4jMarker, log4jMarker);
121 assertEquals(log4jMarker, log4jMarker2);
122 assertEquals(slf4jMarker, slf4jMarker2);
123 assertNotEquals(log4jParent, log4jMarker);
124 assertNotEquals(log4jMarker, log4jParent);
125 }
126
127 @Test
128 public void testContainsNullMarker() {
129 final String childMarkerName = CHILD_MAKER_NAME + "-CM";
130 final String parentMakerName = PARENT_MARKER_NAME + "-CM";
131 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
132 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
133 slf4jMarker.add(slf4jParent);
134 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
135 final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
136 final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
137 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
138 final org.slf4j.Marker nullMarker = null;
139 try {
140 Assert.assertFalse(log4jSlf4jParent.contains(nullMarker));
141 fail("Expected " + IllegalArgumentException.class.getName());
142 } catch (final IllegalArgumentException e) {
143 // expected
144 }
145 try {
146 Assert.assertFalse(log4jSlf4jMarker.contains(nullMarker));
147 fail("Expected " + IllegalArgumentException.class.getName());
148 } catch (final IllegalArgumentException e) {
149 // expected
150 }
151 }
152
153 @Test
154 public void testContainsNullString() {
155 final String childMarkerName = CHILD_MAKER_NAME + "-CS";
156 final String parentMakerName = PARENT_MARKER_NAME + "-CS";
157 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
158 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
159 slf4jMarker.add(slf4jParent);
160 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
161 final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
162 final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
163 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
164 final String nullStr = null;
165 Assert.assertFalse(log4jSlf4jParent.contains(nullStr));
166 Assert.assertFalse(log4jSlf4jMarker.contains(nullStr));
167 }
168
169 @Test
170 public void testRemoveNullMarker() {
171 final String childMakerName = CHILD_MAKER_NAME + "-CM";
172 final String parentMakerName = PARENT_MARKER_NAME + "-CM";
173 final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMakerName);
174 final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
175 slf4jMarker.add(slf4jParent);
176 final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
177 final Marker log4jMarker = MarkerManager.getMarker(childMakerName);
178 final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
179 final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
180 final org.slf4j.Marker nullMarker = null;
181 Assert.assertFalse(log4jSlf4jParent.remove(nullMarker));
182 Assert.assertFalse(log4jSlf4jMarker.remove(nullMarker));
183 }
184
185 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import static org.junit.Assert.fail;
19
20 import org.apache.logging.log4j.LoggingException;
21 import org.junit.Test;
22 import org.slf4j.LoggerFactory;
23
24 /**
25 * Tests StackOverflow when slf4j-impl and to-slf4j are both present.
26 */
27 public class OverflowTest {
28
29 @Test
30 public void log() {
31 try {
32 LoggerFactory.getLogger(OverflowTest.class);
33 fail("Failed to detect inclusion of log4j-to-slf4j");
34 } catch (LoggingException ex) {
35 // Expected exception.
36 } catch (StackOverflowError error) {
37 fail("Failed to detect inclusion of log4j-to-slf4j, caught StackOverflowError");
38 }
39 }
40
41 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.slf4j;
17
18 import static org.apache.logging.log4j.SerializableMatchers.serializesRoundTrip;
19 import static org.hamcrest.MatcherAssert.assertThat;
20
21 import java.io.Serializable;
22
23 import org.apache.logging.log4j.junit.LoggerContextRule;
24 import org.junit.ClassRule;
25 import org.junit.Test;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30 *
31 */
32 public class SerializeTest {
33
34 private static final String CONFIG = "log4j-test1.xml";
35
36 @ClassRule
37 public static final LoggerContextRule CTX = new LoggerContextRule(CONFIG);
38
39 Logger logger = LoggerFactory.getLogger("LoggerTest");
40
41 @Test
42 public void testLogger() throws Exception {
43 assertThat((Serializable) logger, serializesRoundTrip());
44 }
45 }
0 <?xml version="1.0" encoding="UTF-8"?>
1 <configuration status="error" name="LoggerTest">
2 <properties>
3 <property name="filename">target/test.log</property>
4 </properties>
5 <ThresholdFilter level="trace"/>
6
7 <Appenders>
8 <Console name="STDOUT">
9 <PatternLayout pattern="%C{1.} %m MDC%X%n"/>
10 </Console>
11 <File name="File" fileName="${filename}">
12 <PatternLayout>
13 <pattern>%d %p %C{1.} [%t] %m%n</pattern>
14 </PatternLayout>
15 </File>
16 <List name="List">
17 <PatternLayout pattern="%C{1.} %m MDC%X%n%ex{0}"/>
18 </List>
19 <List name="UnformattedList" />
20 <SLF4J name="SLF4J"/>
21 </Appenders>
22
23 <Loggers>
24 <Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
25 <AppenderRef ref="File"/>
26 </Logger>
27
28 <Root level="trace">
29 <AppenderRef ref="List"/>
30 <AppenderRef ref="UnformattedList"/>
31 </Root>
32 </Loggers>
33
34 </configuration>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <Configuration status="warn" name="MyApp" packages="">
2 <Properties>
3 <Property name="audit-path">target/log4j2-1482</Property>
4 <Property name="file-name">audit</Property>
5 <Property name="file-header">param1,param2,param3${sys:line.separator}
6 </Property>
7 </Properties>
8
9 <Appenders>
10 <RollingFile name="auditfile" fileName="${audit-path}/${file-name}.tmp"
11 filePattern="${audit-path}/${file-name}-%d{yyyy-MM-dd}-%i.csv">
12 <CsvParameterLayout delimiter="," header="${file-header}">
13 </CsvParameterLayout>
14 <Policies>
15 <SizeBasedTriggeringPolicy size="80 B" />
16 </Policies>
17 <DefaultRolloverStrategy max="2" />
18 </RollingFile>
19 </Appenders>
20
21 <Loggers>
22 <Root level="info">
23 <AppenderRef ref="auditfile" />
24 </Root>
25 </Loggers>
26 </Configuration>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-spring-boot</artifactId>
2525 <packaging>jar</packaging>
5555 <dependency>
5656 <groupId>org.junit.vintage</groupId>
5757 <artifactId>junit-vintage-engine</artifactId>
58 <scope>test</scope>
5859 </dependency>
5960 <dependency>
6061 <groupId>org.junit.jupiter</groupId>
6162 <artifactId>junit-jupiter-engine</artifactId>
63 <scope>test</scope>
6264 </dependency>
6365 <dependency>
6466 <groupId>org.junit.jupiter</groupId>
6567 <artifactId>junit-jupiter-api</artifactId>
68 <scope>test</scope>
6669 </dependency>
6770 <dependency>
6871 <groupId>org.apache.logging.log4j</groupId>
+0
-269
log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/Log4j2CloudConfigLoggingSystem.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j.spring.boot;
17
18 import java.io.File;
19 import java.io.FileNotFoundException;
20 import java.io.IOException;
21 import java.io.UnsupportedEncodingException;
22 import java.net.MalformedURLException;
23 import java.net.URISyntaxException;
24 import java.net.URL;
25 import java.net.URLConnection;
26 import java.net.URLDecoder;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.Properties;
32 import javax.net.ssl.HttpsURLConnection;
33
34 import org.apache.logging.log4j.LogManager;
35 import org.apache.logging.log4j.Logger;
36 import org.apache.logging.log4j.core.LoggerContext;
37 import org.apache.logging.log4j.core.config.AbstractConfiguration;
38 import org.apache.logging.log4j.core.config.Configuration;
39 import org.apache.logging.log4j.core.config.ConfigurationFactory;
40 import org.apache.logging.log4j.core.config.ConfigurationSource;
41 import org.apache.logging.log4j.core.config.composite.CompositeConfiguration;
42 import org.apache.logging.log4j.core.net.UrlConnectionFactory;
43 import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
44 import org.apache.logging.log4j.core.net.ssl.SslConfigurationFactory;
45 import org.apache.logging.log4j.core.util.AuthorizationProvider;
46 import org.apache.logging.log4j.core.util.FileUtils;
47 import org.apache.logging.log4j.internal.LogManagerStatus;
48 import org.apache.logging.log4j.status.StatusLogger;
49 import org.apache.logging.log4j.util.PropertiesUtil;
50 import org.apache.logging.log4j.util.Strings;
51 import org.springframework.boot.context.properties.bind.BindResult;
52 import org.springframework.boot.context.properties.bind.Bindable;
53 import org.springframework.boot.context.properties.bind.Binder;
54 import org.springframework.boot.logging.LogFile;
55 import org.springframework.boot.logging.LoggingInitializationContext;
56 import org.springframework.boot.logging.LoggingSystem;
57 import org.springframework.boot.logging.LoggingSystemFactory;
58 import org.springframework.boot.logging.log4j2.Log4J2LoggingSystem;
59 import org.springframework.core.annotation.Order;
60 import org.springframework.util.Assert;
61 import org.springframework.util.ClassUtils;
62 import org.springframework.util.ResourceUtils;
63
64 /**
65 * Override Spring's implementation of the Log4j 2 Logging System to properly support Spring Cloud Config.
66 */
67 public class Log4j2CloudConfigLoggingSystem extends Log4J2LoggingSystem {
68
69 /**
70 * Property that disables the usage of this {@link LoggingSystem}.
71 */
72 public static final String LOG4J2_DISABLE_CLOUD_CONFIG_LOGGING_SYSTEM = "log4j2.disableCloudConfigLoggingSystem";
73
74 public static final String ENVIRONMENT_KEY = "SpringEnvironment";
75 private static final String HTTPS = "https";
76 private static final String OVERRIDE_PARAM = "override";
77 private static Logger LOGGER = StatusLogger.getLogger();
78 private static final int PRECEDENCE = 0;
79
80 public Log4j2CloudConfigLoggingSystem(ClassLoader loader) {
81 super(loader);
82 }
83
84 /**
85 * Set the environment into the ExternalContext field so that it can be obtained by SpringLookup when it
86 * is constructed. Spring will replace the ExternalContext field with a String once initialization is
87 * complete.
88 * @param initializationContext The initialization context.
89 * @param configLocation The configuration location.
90 * @param logFile the log file.
91 */
92 @Override
93 public void initialize(LoggingInitializationContext initializationContext, String configLocation, LogFile logFile) {
94 getLoggerContext().putObjectIfAbsent(ENVIRONMENT_KEY, initializationContext.getEnvironment());
95 super.initialize(initializationContext, configLocation, logFile);
96 }
97
98 @Override
99 protected String[] getStandardConfigLocations() {
100 String[] locations = super.getStandardConfigLocations();
101 PropertiesUtil props = new PropertiesUtil(new Properties());
102 String location = props.getStringProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
103 if (location != null) {
104 List<String> list = new ArrayList<>(Arrays.asList(super.getStandardConfigLocations()));
105 list.add(location);
106 locations = list.toArray(Strings.EMPTY_ARRAY);
107 }
108 return locations;
109 }
110
111 @Override
112 protected void loadDefaults(LoggingInitializationContext initializationContext, LogFile logFile) {
113 if (logFile != null) {
114 this.loadConfiguration(this.getBootPackagedConfigFile("log4j2-file.xml"), logFile);
115 } else {
116 this.loadConfiguration(this.getBootPackagedConfigFile("log4j2.xml"), logFile);
117 }
118 }
119
120 private String getBootPackagedConfigFile(String fileName) {
121 String defaultPath = ClassUtils.getPackageName(Log4J2LoggingSystem.class);
122 defaultPath = defaultPath.replace('.', '/');
123 defaultPath = defaultPath + "/" + fileName;
124 defaultPath = "classpath:" + defaultPath;
125 return defaultPath;
126 }
127
128 /**
129 * This method is removed from Spring in 3.x and is scheduled to be removed in 2.8.x. It must be left in
130 * to support older Spring releases.
131 * @param location the location
132 * @param logFile log file configuration
133 */
134 @Override
135 protected void loadConfiguration(String location, LogFile logFile) {
136 loadConfiguration(location, logFile, Collections.emptyList());
137 }
138
139 /**
140 * Added in Spring 2.6.0, the overrides parameter allows override files to be specified in the
141 * "logging.log4j2.config.override" property. However, spring does not support passing credentials
142 * when accessing the location. We do.
143 * @param location The location of the primary configuration.
144 * @param logFile log file configuration.
145 * @param overrides Any override files.
146 */
147 @Override
148 protected void loadConfiguration(String location, LogFile logFile, List<String> overrides) {
149 Assert.notNull(location, "Location must not be null");
150 try {
151 LoggerContext ctx = getLoggerContext();
152 List<String> locations = parseConfigLocations(location);
153 if (overrides != null) {
154 locations.addAll(overrides);
155 }
156 if (locations.size() == 1) {
157 final URL url = ResourceUtils.getURL(location);
158 final ConfigurationSource source = getConfigurationSource(url);
159 if (source != null) {
160 ctx.start(ConfigurationFactory.getInstance().getConfiguration(ctx, source));
161 }
162 } else {
163 final List<AbstractConfiguration> configs = new ArrayList<>();
164 boolean first = true;
165 for (final String sourceLocation : locations) {
166 final ConfigurationSource source = getConfigurationSource(ResourceUtils.getURL(sourceLocation));
167 if (source != null) {
168 try {
169 final Configuration config = ConfigurationFactory.getInstance().getConfiguration(ctx, source);
170 if (config instanceof AbstractConfiguration) {
171 configs.add((AbstractConfiguration) config);
172 } else {
173 LOGGER.warn("Configuration at {} cannot be combined in a CompositeConfiguration", sourceLocation);
174 return;
175 }
176 } catch (Exception ex) {
177 if (!first) {
178 LOGGER.warn("Error accessing {}: {}. Ignoring override", sourceLocation, ex.getMessage());
179 } else {
180 throw ex;
181 }
182 }
183 }
184 first = false;
185 }
186 if (configs.size() > 1) {
187 ctx.start(new CompositeConfiguration(configs));
188 } else {
189 ctx.start(configs.get(0));
190 }
191 }
192 }
193 catch (Exception ex) {
194 throw new IllegalStateException(
195 "Could not initialize Log4J2 logging from " + location, ex);
196 }
197 }
198
199 @Override
200 public void cleanUp() {
201 getLoggerContext().removeObject(ENVIRONMENT_KEY);
202 super.cleanUp();
203 }
204
205 private List<String> parseConfigLocations(String configLocations) {
206 final String[] uris = configLocations.split("\\?");
207 final List<String> locations = new ArrayList<>();
208 locations.add(uris[0]);
209 if (uris.length > 1) {
210 try {
211 final URL url = new URL(configLocations);
212 final String[] pairs = url.getQuery().split("&");
213 for (String pair : pairs) {
214 final int idx = pair.indexOf("=");
215 try {
216 final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
217 if (key.equalsIgnoreCase(OVERRIDE_PARAM)) {
218 locations.add(URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
219 }
220 } catch (UnsupportedEncodingException ex) {
221 LOGGER.warn("Bad data in configuration string: {}", pair);
222 }
223 }
224 return locations;
225 } catch (MalformedURLException ex) {
226 LOGGER.warn("Unable to parse configuration URL {}", configLocations);
227 }
228 }
229 return locations;
230 }
231
232 private ConfigurationSource getConfigurationSource(URL url) throws IOException, URISyntaxException {
233 AuthorizationProvider provider = ConfigurationFactory.authorizationProvider(PropertiesUtil.getProperties());
234 SslConfiguration sslConfiguration = url.getProtocol().equals(HTTPS)
235 ? SslConfigurationFactory.getSslConfiguration() : null;
236 URLConnection urlConnection = UrlConnectionFactory.createConnection(url, 0, sslConfiguration,
237 provider);
238
239 File file = FileUtils.fileFromUri(url.toURI());
240 try {
241 if (file != null) {
242 return new ConfigurationSource(urlConnection.getInputStream(), FileUtils.fileFromUri(url.toURI()));
243 }
244 return new ConfigurationSource(urlConnection.getInputStream(), url, urlConnection.getLastModified());
245 } catch (FileNotFoundException ex) {
246 LOGGER.info("Unable to locate file {}, ignoring.", url.toString());
247 return null;
248 }
249 }
250
251 private LoggerContext getLoggerContext() {
252 return (LoggerContext) LogManager.getContext(false);
253 }
254
255 @Order(PRECEDENCE)
256 public static class Factory implements LoggingSystemFactory {
257
258 @Override
259 public LoggingSystem getLoggingSystem(ClassLoader classLoader) {
260 if (PropertiesUtil.getProperties().getBooleanProperty(LOG4J2_DISABLE_CLOUD_CONFIG_LOGGING_SYSTEM)) {
261 return null;
262 }
263 return new Log4j2CloudConfigLoggingSystem(classLoader);
264 }
265
266 }
267
268 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j.spring.boot;
17
18 import java.io.File;
19 import java.io.FileNotFoundException;
20 import java.io.IOException;
21 import java.io.UnsupportedEncodingException;
22 import java.net.MalformedURLException;
23 import java.net.URISyntaxException;
24 import java.net.URL;
25 import java.net.URLConnection;
26 import java.net.URLDecoder;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.Properties;
32
33 import org.apache.logging.log4j.LogManager;
34 import org.apache.logging.log4j.Logger;
35 import org.apache.logging.log4j.core.LoggerContext;
36 import org.apache.logging.log4j.core.config.AbstractConfiguration;
37 import org.apache.logging.log4j.core.config.Configuration;
38 import org.apache.logging.log4j.core.config.ConfigurationFactory;
39 import org.apache.logging.log4j.core.config.ConfigurationSource;
40 import org.apache.logging.log4j.core.config.composite.CompositeConfiguration;
41 import org.apache.logging.log4j.core.net.UrlConnectionFactory;
42 import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
43 import org.apache.logging.log4j.core.net.ssl.SslConfigurationFactory;
44 import org.apache.logging.log4j.core.util.AuthorizationProvider;
45 import org.apache.logging.log4j.core.util.FileUtils;
46 import org.apache.logging.log4j.status.StatusLogger;
47 import org.apache.logging.log4j.util.PropertiesUtil;
48 import org.apache.logging.log4j.util.Strings;
49 import org.springframework.boot.logging.LogFile;
50 import org.springframework.boot.logging.LoggingInitializationContext;
51 import org.springframework.boot.logging.LoggingSystem;
52 import org.springframework.boot.logging.LoggingSystemFactory;
53 import org.springframework.boot.logging.log4j2.Log4J2LoggingSystem;
54 import org.springframework.core.annotation.Order;
55 import org.springframework.core.env.Environment;
56 import org.springframework.util.Assert;
57 import org.springframework.util.ClassUtils;
58 import org.springframework.util.ResourceUtils;
59
60 /**
61 * Override Spring's implementation of the Log4j 2 Logging System to properly support Spring Cloud Config.
62 */
63 public class Log4j2SpringBootLoggingSystem extends Log4J2LoggingSystem {
64
65 /**
66 * Property that disables the usage of this {@link LoggingSystem}.
67 */
68 public static final String LOG4J2_DISABLE_CLOUD_CONFIG_LOGGING_SYSTEM = "log4j2.disableCloudConfigLoggingSystem";
69
70 public static final String ENVIRONMENT_KEY = "SpringEnvironment";
71 private static final String HTTPS = "https";
72 private static final String OVERRIDE_PARAM = "override";
73 private static Logger LOGGER = StatusLogger.getLogger();
74 private static final int PRECEDENCE = 0;
75
76 public Log4j2SpringBootLoggingSystem(ClassLoader loader) {
77 super(loader);
78 }
79
80 /**
81 * Set the environment into the ExternalContext field so that it can be obtained by SpringLookup when it
82 * is constructed. Spring will replace the ExternalContext field with a String once initialization is
83 * complete.
84 * @param initializationContext The initialization context.
85 * @param configLocation The configuration location.
86 * @param logFile the log file.
87 */
88 @Override
89 public void initialize(LoggingInitializationContext initializationContext, String configLocation, LogFile logFile) {
90 Environment environment = initializationContext.getEnvironment();
91 PropertiesUtil.getProperties().addPropertySource(new SpringPropertySource(environment));
92 getLoggerContext().putObjectIfAbsent(ENVIRONMENT_KEY, environment);
93 super.initialize(initializationContext, configLocation, logFile);
94 }
95
96 @Override
97 protected String[] getStandardConfigLocations() {
98 String[] locations = super.getStandardConfigLocations();
99 PropertiesUtil props = new PropertiesUtil(new Properties());
100 String location = props.getStringProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
101 if (location != null) {
102 List<String> list = new ArrayList<>(Arrays.asList(super.getStandardConfigLocations()));
103 list.add(location);
104 locations = list.toArray(Strings.EMPTY_ARRAY);
105 }
106 return locations;
107 }
108
109 @Override
110 protected void loadDefaults(LoggingInitializationContext initializationContext, LogFile logFile) {
111 if (logFile != null) {
112 this.loadConfiguration(this.getBootPackagedConfigFile("log4j2-file.xml"), logFile);
113 } else {
114 this.loadConfiguration(this.getBootPackagedConfigFile("log4j2.xml"), logFile);
115 }
116 }
117
118 private String getBootPackagedConfigFile(String fileName) {
119 String defaultPath = ClassUtils.getPackageName(Log4J2LoggingSystem.class);
120 defaultPath = defaultPath.replace('.', '/');
121 defaultPath = defaultPath + "/" + fileName;
122 defaultPath = "classpath:" + defaultPath;
123 return defaultPath;
124 }
125
126 /**
127 * This method is removed from Spring in 3.x and is scheduled to be removed in 2.8.x. It must be left in
128 * to support older Spring releases.
129 * @param location the location
130 * @param logFile log file configuration
131 */
132 @Override
133 protected void loadConfiguration(String location, LogFile logFile) {
134 loadConfiguration(location, logFile, Collections.emptyList());
135 }
136
137 /**
138 * Added in Spring 2.6.0, the overrides parameter allows override files to be specified in the
139 * "logging.log4j2.config.override" property. However, spring does not support passing credentials
140 * when accessing the location. We do.
141 * @param location The location of the primary configuration.
142 * @param logFile log file configuration.
143 * @param overrides Any override files.
144 */
145 @Override
146 protected void loadConfiguration(String location, LogFile logFile, List<String> overrides) {
147 Assert.notNull(location, "Location must not be null");
148 try {
149 LoggerContext ctx = getLoggerContext();
150 List<String> locations = parseConfigLocations(location);
151 if (overrides != null) {
152 locations.addAll(overrides);
153 }
154 if (locations.size() == 1) {
155 final URL url = ResourceUtils.getURL(location);
156 final ConfigurationSource source = getConfigurationSource(url);
157 if (source != null) {
158 ctx.start(ConfigurationFactory.getInstance().getConfiguration(ctx, source));
159 }
160 } else {
161 final List<AbstractConfiguration> configs = new ArrayList<>();
162 boolean first = true;
163 for (final String sourceLocation : locations) {
164 final ConfigurationSource source = getConfigurationSource(ResourceUtils.getURL(sourceLocation));
165 if (source != null) {
166 try {
167 final Configuration config = ConfigurationFactory.getInstance().getConfiguration(ctx, source);
168 if (config instanceof AbstractConfiguration) {
169 configs.add((AbstractConfiguration) config);
170 } else {
171 LOGGER.warn("Configuration at {} cannot be combined in a CompositeConfiguration", sourceLocation);
172 return;
173 }
174 } catch (Exception ex) {
175 if (!first) {
176 LOGGER.warn("Error accessing {}: {}. Ignoring override", sourceLocation, ex.getMessage());
177 } else {
178 throw ex;
179 }
180 }
181 }
182 first = false;
183 }
184 if (configs.size() > 1) {
185 ctx.start(new CompositeConfiguration(configs));
186 } else {
187 ctx.start(configs.get(0));
188 }
189 }
190 }
191 catch (Exception ex) {
192 throw new IllegalStateException(
193 "Could not initialize Log4J2 logging from " + location, ex);
194 }
195 }
196
197 @Override
198 public void cleanUp() {
199 getLoggerContext().removeObject(ENVIRONMENT_KEY);
200 super.cleanUp();
201 }
202
203 private List<String> parseConfigLocations(String configLocations) {
204 final String[] uris = configLocations.split("\\?");
205 final List<String> locations = new ArrayList<>();
206 locations.add(uris[0]);
207 if (uris.length > 1) {
208 try {
209 final URL url = new URL(configLocations);
210 final String[] pairs = url.getQuery().split("&");
211 for (String pair : pairs) {
212 final int idx = pair.indexOf("=");
213 try {
214 final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
215 if (key.equalsIgnoreCase(OVERRIDE_PARAM)) {
216 locations.add(URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
217 }
218 } catch (UnsupportedEncodingException ex) {
219 LOGGER.warn("Bad data in configuration string: {}", pair);
220 }
221 }
222 return locations;
223 } catch (MalformedURLException ex) {
224 LOGGER.warn("Unable to parse configuration URL {}", configLocations);
225 }
226 }
227 return locations;
228 }
229
230 private ConfigurationSource getConfigurationSource(URL url) throws IOException, URISyntaxException {
231 AuthorizationProvider provider = ConfigurationFactory.authorizationProvider(PropertiesUtil.getProperties());
232 SslConfiguration sslConfiguration = url.getProtocol().equals(HTTPS)
233 ? SslConfigurationFactory.getSslConfiguration() : null;
234 URLConnection urlConnection = UrlConnectionFactory.createConnection(url, 0, sslConfiguration,
235 provider);
236
237 File file = FileUtils.fileFromUri(url.toURI());
238 try {
239 if (file != null) {
240 return new ConfigurationSource(urlConnection.getInputStream(), FileUtils.fileFromUri(url.toURI()));
241 }
242 return new ConfigurationSource(urlConnection.getInputStream(), url, urlConnection.getLastModified());
243 } catch (FileNotFoundException ex) {
244 LOGGER.info("Unable to locate file {}, ignoring.", url.toString());
245 return null;
246 }
247 }
248
249 private LoggerContext getLoggerContext() {
250 return (LoggerContext) LogManager.getContext(false);
251 }
252
253 @Order(PRECEDENCE)
254 public static class Factory implements LoggingSystemFactory {
255
256 @Override
257 public LoggingSystem getLoggingSystem(ClassLoader classLoader) {
258 if (PropertiesUtil.getProperties().getBooleanProperty(LOG4J2_DISABLE_CLOUD_CONFIG_LOGGING_SYSTEM)) {
259 return null;
260 }
261 return new Log4j2SpringBootLoggingSystem(classLoader);
262 }
263
264 }
265
266 }
+0
-50
log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/SpringEnvironmentHolder.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j.spring.boot;
17
18 import java.util.concurrent.locks.Lock;
19 import java.util.concurrent.locks.ReentrantLock;
20
21 import org.apache.logging.log4j.LogManager;
22 import org.apache.logging.log4j.internal.LogManagerStatus;
23 import org.springframework.core.env.Environment;
24
25 /**
26 * Provides access to the Spring Environment.
27 */
28 public class SpringEnvironmentHolder {
29
30 private volatile Environment environment;
31 private Lock lock = new ReentrantLock();
32
33
34 protected Environment getEnvironment() {
35 if (environment == null && LogManagerStatus.isInitialized() && LogManager.getFactory() != null &&
36 LogManager.getFactory().hasContext(SpringEnvironmentHolder.class.getName(), null, false)) {
37 lock.lock();
38 try {
39 if (environment == null) {
40 Object obj = LogManager.getContext(false).getObject(Log4j2CloudConfigLoggingSystem.ENVIRONMENT_KEY);
41 environment = obj instanceof Environment ? (Environment) obj : null;
42 }
43 } finally {
44 lock.unlock();
45 }
46 }
47 return environment;
48 }
49 }
2020
2121 import org.apache.logging.log4j.Logger;
2222 import org.apache.logging.log4j.core.LogEvent;
23 import org.apache.logging.log4j.core.LoggerContext;
24 import org.apache.logging.log4j.core.config.LoggerContextAware;
2325 import org.apache.logging.log4j.core.config.plugins.Plugin;
2426 import org.apache.logging.log4j.core.lookup.StrLookup;
2527 import org.apache.logging.log4j.core.util.Integers;
3032 * Lookup for Spring properties.
3133 */
3234 @Plugin(name = "spring", category = StrLookup.CATEGORY)
33 public class SpringLookup extends SpringEnvironmentHolder implements StrLookup {
35 public class SpringLookup implements LoggerContextAware, StrLookup {
3436
3537 private static final Logger LOGGER = StatusLogger.getLogger();
3638 private static final String ACTIVE = "profiles.active";
3941 private static final Pattern ACTIVE_PATTERN = Pattern.compile(ACTIVE + PATTERN);
4042 private static final Pattern DEFAULT_PATTERN = Pattern.compile(DEFAULT + PATTERN);
4143
42 public SpringLookup() {
43 getEnvironment();
44 }
44 private volatile Environment environment;
4545
4646 @Override
4747 public String lookup(String key) {
48 Environment env = getEnvironment();
49 if (env != null) {
48 if (environment != null) {
5049 String lowerKey = key.toLowerCase();
5150 if (lowerKey.startsWith(ACTIVE)) {
52 switch (env.getActiveProfiles().length) {
51 switch (environment.getActiveProfiles().length) {
5352 case 0: {
5453 return null;
5554 }
5655 case 1: {
57 return env.getActiveProfiles()[0];
56 return environment.getActiveProfiles()[0];
5857 }
5958 default: {
6059 Matcher matcher = ACTIVE_PATTERN.matcher(key);
6160 if (matcher.matches()) {
6261 try {
6362 int index = Integers.parseInt(matcher.group(1));
64 if (index < env.getActiveProfiles().length) {
65 return env.getActiveProfiles()[index];
63 if (index < environment.getActiveProfiles().length) {
64 return environment.getActiveProfiles()[index];
6665 }
6766 LOGGER.warn("Index out of bounds for Spring active profiles: {}", index);
6867 return null;
7271 }
7372
7473 }
75 return String.join(",", env.getActiveProfiles());
74 return String.join(",", environment.getActiveProfiles());
7675 }
7776 }
7877 } else if (lowerKey.startsWith(DEFAULT)) {
79 switch (env.getDefaultProfiles().length) {
78 switch (environment.getDefaultProfiles().length) {
8079 case 0: {
8180 return null;
8281 }
8382 case 1: {
84 return env.getDefaultProfiles()[0];
83 return environment.getDefaultProfiles()[0];
8584 }
8685 default: {
8786 Matcher matcher = DEFAULT_PATTERN.matcher(key);
8887 if (matcher.matches()) {
8988 try {
9089 int index = Integer.parseInt(matcher.group(1));
91 if (index < env.getDefaultProfiles().length) {
92 return env.getDefaultProfiles()[index];
90 if (index < environment.getDefaultProfiles().length) {
91 return environment.getDefaultProfiles()[index];
9392 }
9493 LOGGER.warn("Index out of bounds for Spring default profiles: {}", index);
9594 return null;
9998 }
10099
101100 }
102 return String.join(",", env.getDefaultProfiles());
101 return String.join(",", environment.getDefaultProfiles());
103102 }
104103 }
105104 }
106105
107 return env.getProperty(key);
106 return environment.getProperty(key);
108107
109108 }
110109 return null;
114113 public String lookup(LogEvent event, String key) {
115114 return lookup((key));
116115 }
116
117 @Override
118 public void setLoggerContext(final LoggerContext loggerContext) {
119 if (loggerContext != null) {
120 environment = (Environment) loggerContext.getObject(Log4j2SpringBootLoggingSystem.ENVIRONMENT_KEY);
121 } else {
122 LOGGER.warn("Attempt to set LoggerContext reference to null in SpringLookup");
123 }
124 }
117125 }
1515 */
1616 package org.apache.logging.log4j.spring.boot;
1717
18 import org.apache.logging.log4j.Logger;
19 import org.apache.logging.log4j.core.LoggerContext;
1820 import org.apache.logging.log4j.core.config.Configuration;
1921 import org.apache.logging.log4j.core.config.Node;
2022 import org.apache.logging.log4j.core.config.arbiters.Arbiter;
2224 import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
2325 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
2426 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
27 import org.apache.logging.log4j.core.config.plugins.PluginLoggerContext;
28 import org.apache.logging.log4j.status.StatusLogger;
2529 import org.springframework.core.env.Environment;
2630 import org.springframework.core.env.Profiles;
2731 import org.springframework.util.StringUtils;
3135 */
3236 @Plugin(name = "SpringProfile", category = Node.CATEGORY, elementType = Arbiter.ELEMENT_TYPE,
3337 deferChildren = true, printObject = true)
34 public class SpringProfileArbiter extends SpringEnvironmentHolder implements Arbiter {
38 public class SpringProfileArbiter implements Arbiter {
3539
3640 private final String[] profileNames;
41 private final Environment environment;
3742
38 private SpringProfileArbiter(final String[] profiles) {
43 private SpringProfileArbiter(final String[] profiles, Environment environment) {
3944 this.profileNames = profiles;
40
45 this.environment = environment;
4146 }
4247
4348 @Override
4449 public boolean isCondition() {
45 Environment environment = getEnvironment();
4650 if (environment == null) {
4751 return false;
4852 }
6064
6165 public static class Builder implements org.apache.logging.log4j.core.util.Builder<SpringProfileArbiter> {
6266
67 private final Logger LOGGER = StatusLogger.getLogger();
6368 public static final String ATTR_NAME = "name";
6469
6570 @PluginBuilderAttribute(ATTR_NAME)
6671 private String name;
6772
6873 @PluginConfiguration
69 private Configuration configuration;;
74 private Configuration configuration;
75
76 @PluginLoggerContext
77 private LoggerContext loggerContext;
7078
7179 /**
7280 * Sets the Profile Name or Names.
8391 return asBuilder();
8492 }
8593
94 public Builder setLoggerContext(final LoggerContext loggerContext) {
95 this.loggerContext = loggerContext;
96 return asBuilder();
97 }
98
8699 private SpringProfileArbiter.Builder asBuilder() {
87100 return this;
88101 }
90103 public SpringProfileArbiter build() {
91104 String[] profileNames = StringUtils.trimArrayElements(
92105 StringUtils.commaDelimitedListToStringArray(configuration.getStrSubstitutor().replace(name)));
93 return new SpringProfileArbiter(profileNames);
106 Environment environment = null;
107 if (loggerContext != null) {
108 environment = (Environment) loggerContext.getObject(Log4j2SpringBootLoggingSystem.ENVIRONMENT_KEY);
109 if (environment == null) {
110 LOGGER.warn("Cannot create Arbiter, no Spring Environment provided");
111 return null;
112 }
113
114 return new SpringProfileArbiter(profileNames, environment);
115 } else {
116 LOGGER.warn("Cannot create Arbiter, LoggerContext is not available");
117 }
118 return null;
94119 }
95120 }
96121 }
2121 /**
2222 * Returns properties from Spring.
2323 */
24 public class SpringPropertySource extends SpringEnvironmentHolder implements PropertySource {
24 public class SpringPropertySource implements PropertySource {
2525
2626 private static final int DEFAULT_PRIORITY = -100;
27
28 private final Environment environment;
29
30 public SpringPropertySource(Environment environment) {
31 this.environment = environment;
32 }
2733
2834 /**
2935 * System properties take precendence followed by properties in Log4j properties files. Spring properties
3743
3844 @Override
3945 public String getProperty(String key) {
40 Environment environment = getEnvironment();
4146 if (environment != null) {
4247 return environment.getProperty(key);
4348 }
4651
4752 @Override
4853 public boolean containsProperty(String key) {
49 Environment environment = getEnvironment();
5054 if (environment != null) {
5155 return environment.containsProperty(key);
5256 }
+0
-15
log4j-spring-boot/src/main/resources/META-INF/services/org.apache.logging.log4j.util.PropertySource less more
0 # Licensed to the Apache Software Foundation (ASF) under one or more
1 # contributor license agreements. See the NOTICE file distributed with
2 # this work for additional information regarding copyright ownership.
3 # The ASF licenses this file to You under the Apache license, Version 2.0
4 # (the "License"); you may not use this file except in compliance with
5 # the License. You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the license for the specific language governing permissions and
13 # limitations under the license.
14 org.apache.logging.log4j.spring.boot.SpringPropertySource
1313 # See the license for the specific language governing permissions and
1414 # limitations under the license.
1515 #
16 org.springframework.boot.logging.LoggingSystemFactory=org.apache.logging.log4j.spring.boot.Log4j2CloudConfigLoggingSystem.Factory
16 org.springframework.boot.logging.LoggingSystemFactory=org.apache.logging.log4j.spring.boot.Log4j2SpringBootLoggingSystem.Factory
+0
-59
log4j-spring-boot/src/test/java/org/apache/logging/log4j/spring/boot/Log4j2CloudConfigLoggingSystemTest.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j.spring.boot;
17
18 import org.apache.logging.log4j.LogManager;
19 import org.apache.logging.log4j.core.config.ConfigurationFactory;
20 import org.apache.logging.log4j.spi.LoggerContext;
21 import org.junit.jupiter.api.Test;
22 import org.junitpioneer.jupiter.SetSystemProperty;
23 import org.springframework.boot.logging.LoggingSystem;
24 import org.springframework.boot.logging.log4j2.Log4J2LoggingSystem;
25
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27
28 import java.util.Arrays;
29 import java.util.List;
30
31 public class Log4j2CloudConfigLoggingSystemTest {
32
33 @Test
34 public void getStandardConfigLocations() {
35 String customLog4j2Location = "classpath:my_custom_log4j2.properties";
36 LoggerContext lc = LogManager.getContext(); // Initialize LogManager to here to prevent a failure trying to
37 // initialize it from StatusLogger.
38 System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY, customLog4j2Location);
39 Log4j2CloudConfigLoggingSystem cloudLoggingSystem = new Log4j2CloudConfigLoggingSystem(
40 this.getClass().getClassLoader());
41 List<String> standardConfigLocations = Arrays.asList(cloudLoggingSystem.getStandardConfigLocations());
42 assertTrue(standardConfigLocations.contains(customLog4j2Location));
43
44 }
45
46 @Test
47 @SetSystemProperty(key = Log4j2CloudConfigLoggingSystem.LOG4J2_DISABLE_CLOUD_CONFIG_LOGGING_SYSTEM, value = "true")
48 public void testUseLog4j2LoggingSystem() {
49 LoggingSystem loggingSystem = LoggingSystem.get(getClass().getClassLoader());
50 assertTrue(loggingSystem.getClass().equals(Log4J2LoggingSystem.class));
51 }
52
53 @Test
54 public void testLoggingSystemEnabled() {
55 LoggingSystem loggingSystem = LoggingSystem.get(getClass().getClassLoader());
56 assertTrue(loggingSystem.getClass().equals(Log4j2CloudConfigLoggingSystem.class));
57 }
58 }
5353
5454 @Override
5555 public void run(ApplicationArguments args) throws Exception {
56 LoggerContext context = (LoggerContext) LogManager.getContext(false);
5657 SpringLookup lookup = new SpringLookup();
58 lookup.setLoggerContext(context);
5759 LOGGER.info("Started: {}", lookup.lookup("spring.application.name"));
5860 }
5961 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j.spring.boot;
17
18 import org.apache.logging.log4j.LogManager;
19 import org.apache.logging.log4j.core.config.ConfigurationFactory;
20 import org.apache.logging.log4j.spi.LoggerContext;
21 import org.junit.jupiter.api.Test;
22 import org.junitpioneer.jupiter.SetSystemProperty;
23 import org.springframework.boot.logging.LoggingSystem;
24 import org.springframework.boot.logging.log4j2.Log4J2LoggingSystem;
25
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27
28 import java.util.Arrays;
29 import java.util.List;
30
31 public class Log4j2SpringBootLoggingSystemTest {
32
33 @Test
34 public void getStandardConfigLocations() {
35 String customLog4j2Location = "classpath:my_custom_log4j2.properties";
36 LoggerContext lc = LogManager.getContext(); // Initialize LogManager to here to prevent a failure trying to
37 // initialize it from StatusLogger.
38 System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY, customLog4j2Location);
39 Log4j2SpringBootLoggingSystem cloudLoggingSystem = new Log4j2SpringBootLoggingSystem(
40 this.getClass().getClassLoader());
41 List<String> standardConfigLocations = Arrays.asList(cloudLoggingSystem.getStandardConfigLocations());
42 assertTrue(standardConfigLocations.contains(customLog4j2Location));
43
44 }
45
46 @Test
47 @SetSystemProperty(key = Log4j2SpringBootLoggingSystem.LOG4J2_DISABLE_CLOUD_CONFIG_LOGGING_SYSTEM, value = "true")
48 public void testUseLog4j2LoggingSystem() {
49 LoggingSystem loggingSystem = LoggingSystem.get(getClass().getClassLoader());
50 assertTrue(loggingSystem.getClass().equals(Log4J2LoggingSystem.class));
51 }
52
53 @Test
54 public void testLoggingSystemEnabled() {
55 LoggingSystem loggingSystem = LoggingSystem.get(getClass().getClassLoader());
56 assertTrue(loggingSystem.getClass().equals(Log4j2SpringBootLoggingSystem.class));
57 }
58 }
3838 env.setDefaultProfiles("one", "two");
3939 env.setProperty("app.property", "test");
4040 LoggerContext context = (LoggerContext) LogManager.getContext(false);
41 context.putObject(Log4j2CloudConfigLoggingSystem.ENVIRONMENT_KEY, env);
41 context.putObject(Log4j2SpringBootLoggingSystem.ENVIRONMENT_KEY, env);
4242 SpringLookup lookup = new SpringLookup();
43 lookup.setLoggerContext(context);
4344 String result = lookup.lookup("profiles.active");
4445 assertNotNull("No active profiles", result);
4546 assertEquals("Incorrect active profile", "test", result);
6566 env.setActiveProfiles("test");
6667 env.setProperty("app.property", "test");
6768 LoggerContext context = (LoggerContext) LogManager.getContext(false);
68 context.putObject(Log4j2CloudConfigLoggingSystem.ENVIRONMENT_KEY, env);
69
70 StrLookup lookup = new Interpolator();
69 context.putObject(Log4j2SpringBootLoggingSystem.ENVIRONMENT_KEY, env);
70 Interpolator lookup = new Interpolator();
71 lookup.setConfiguration(context.getConfiguration());
72 lookup.setLoggerContext(context);
7173 String result = lookup.lookup("spring:profiles.active");
7274 assertNotNull("No active profiles", result);
7375 assertEquals("Incorrect active profile", "test", result);
4242 public static void before() {
4343 loggerContext = (LoggerContext) LogManager.getContext(false);
4444 env = new MockEnvironment();
45 loggerContext.putObject(Log4j2CloudConfigLoggingSystem.ENVIRONMENT_KEY, env);
45 loggerContext.putObject(Log4j2SpringBootLoggingSystem.ENVIRONMENT_KEY, env);
4646 }
4747
4848
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j-spring-cloud-config</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-spring-cloud-config-client</artifactId>
2525 <packaging>jar</packaging>
3535 <dependency>
3636 <groupId>org.junit.vintage</groupId>
3737 <artifactId>junit-vintage-engine</artifactId>
38 <scope>test</scope>
3839 </dependency>
3940 <dependency>
4041 <groupId>org.junit.jupiter</groupId>
4142 <artifactId>junit-jupiter-engine</artifactId>
43 <scope>test</scope>
4244 </dependency>
4345 <dependency>
4446 <groupId>org.apache.logging.log4j</groupId>
2020 <parent>
2121 <groupId>org.apache.logging.log4j.samples</groupId>
2222 <artifactId>log4j-spring-cloud-config-samples</artifactId>
23 <version>2.18.0</version>
23 <version>2.19.0</version>
2424 </parent>
2525
2626 <artifactId>sample-app</artifactId>
2020 <groupId>org.apache.logging.log4j.samples</groupId>
2121 <artifactId>log4j-spring-cloud-config-sample-server</artifactId>
2222 <packaging>jar</packaging>
23 <version>2.18.0</version>
23 <version>2.19.0</version>
2424
2525 <name>Apache Log4j Sample Configuration Service</name>
2626 <description>Sample Cloud Config Server</description>
304304 </profiles>
305305
306306 <scm>
307 <tag>log4j-2.18.0-rc1</tag>
307 <tag>log4j-2.19.0-rc2</tag>
308308 </scm>
309309 </project>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j-spring-cloud-config</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <groupId>org.apache.logging.log4j.samples</groupId>
2525 <artifactId>log4j-spring-cloud-config-samples</artifactId>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-spring-cloud-config</artifactId>
2525 <packaging>pom</packaging>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-taglib</artifactId>
2525 <packaging>jar</packaging>
6666 <dependency>
6767 <groupId>org.junit.vintage</groupId>
6868 <artifactId>junit-vintage-engine</artifactId>
69 <scope>test</scope>
6970 </dependency>
7071 <dependency>
7172 <groupId>org.junit.jupiter</groupId>
7273 <artifactId>junit-jupiter-engine</artifactId>
74 <scope>test</scope>
7375 </dependency>
7476 <dependency>
7577 <groupId>org.springframework</groupId>
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-to-jul</artifactId>
2525 <packaging>jar</packaging>
4040 <artifactId>log4j-api</artifactId>
4141 </dependency>
4242 <dependency>
43 <groupId>org.osgi</groupId>
44 <artifactId>org.osgi.core</artifactId>
45 </dependency>
46 <dependency>
4347 <groupId>com.google.guava</groupId>
4448 <artifactId>guava-testlib</artifactId>
4549 <scope>test</scope>
4751 <dependency>
4852 <groupId>org.junit.vintage</groupId>
4953 <artifactId>junit-vintage-engine</artifactId>
54 <scope>test</scope>
5055 </dependency>
5156 <dependency>
5257 <groupId>org.junit.jupiter</groupId>
5358 <artifactId>junit-jupiter-engine</artifactId>
59 <scope>test</scope>
5460 </dependency>
5561 <dependency>
5662 <groupId>org.assertj</groupId>
8086 <artifactId>maven-bundle-plugin</artifactId>
8187 <configuration>
8288 <instructions>
89 <Bundle-Activator>org.apache.logging.log4j.tojul.Activator</Bundle-Activator>
8390 <Export-Package>org.apache.logging.log4j.tojul</Export-Package>
84 <Require-Capability>
85 osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)"
86 </Require-Capability>
87 <Provide-Capability>
88 osgi.serviceloader;osgi.serviceloader=org.apache.logging.log4j.spi.Provider
89 </Provide-Capability>
9091 </instructions>
9192 </configuration>
9293 </plugin>
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j.tojul;
17
18 import org.apache.logging.log4j.util.ProviderActivator;
19
20 public class Activator extends ProviderActivator {
21
22 public Activator() {
23 super(new JULProvider());
24 }
25 }
152152 return current.getLevel();
153153 }
154154 // This is a safety fallback that is typically never reached, because usually the root Logger.getLogger("") has a Level.
155 return Logger.getGlobal().getLevel();
155 // Since JDK 8 the LogManager$RootLogger does not have a default level, just a default effective level of INFO.
156 return java.util.logging.Level.INFO;
156157 }
157158
158159 private boolean isEnabledFor(final Level level, final Marker marker) {
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16 package org.apache.logging.log4j.tojul;
17
18 import static org.junit.jupiter.api.Assertions.assertEquals;
19
20 import org.apache.logging.log4j.Level;
21 import org.junit.jupiter.api.Test;
22
23 public class JULLoggerTest {
24
25 @Test
26 public void testNotNullEffectiveLevel() {
27 // Emulates the root logger found in Tomcat, with a null level
28 // See: https://bz.apache.org/bugzilla/show_bug.cgi?id=66184
29 final java.util.logging.Logger julLogger = new java.util.logging.Logger("", null) {
30 };
31 final JULLogger logger = new JULLogger("", julLogger);
32 assertEquals(Level.INFO, logger.getLevel());
33 }
34 }
1919 <parent>
2020 <groupId>org.apache.logging.log4j</groupId>
2121 <artifactId>log4j</artifactId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <artifactId>log4j-to-slf4j</artifactId>
2525 <packaging>jar</packaging>
4242 <artifactId>log4j-api</artifactId>
4343 </dependency>
4444 <dependency>
45 <groupId>org.osgi</groupId>
46 <artifactId>org.osgi.core</artifactId>
47 </dependency>
48 <dependency>
4549 <groupId>ch.qos.logback</groupId>
4650 <artifactId>logback-core</artifactId>
4751 <scope>test</scope>
6064 <dependency>
6165 <groupId>org.junit.vintage</groupId>
6266 <artifactId>junit-vintage-engine</artifactId>
67 <scope>test</scope>
6368 </dependency>
6469 <dependency>
6570 <groupId>org.junit.jupiter</groupId>
6671 <artifactId>junit-jupiter-engine</artifactId>
72 <scope>test</scope>
6773 </dependency>
6874 <dependency>
6975 <groupId>org.hamcrest</groupId>
9399 <artifactId>maven-bundle-plugin</artifactId>
94100 <configuration>
95101 <instructions>
102 <Bundle-Activator>org.apache.logging.slf4j.Activator</Bundle-Activator>
96103 <Export-Package>org.apache.logging.slf4j</Export-Package>
97 <Require-Capability>
98 osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)"
99 </Require-Capability>
100 <Provide-Capability>
101 osgi.serviceloader;osgi.serviceloader=org.apache.logging.log4j.spi.Provider
102 </Provide-Capability>
103104 </instructions>
104105 </configuration>
105106 </plugin>
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache license, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16
17 package org.apache.logging.slf4j;
18
19 import org.apache.logging.log4j.util.ProviderActivator;
20
21 public class Activator extends ProviderActivator {
22
23 public Activator() {
24 super(new SLF4JProvider());
25 }
26
27 }
1919 <parent>
2020 <artifactId>log4j</artifactId>
2121 <groupId>org.apache.logging.log4j</groupId>
22 <version>2.18.0</version>
22 <version>2.19.0</version>
2323 </parent>
2424 <modelVersion>4.0.0</modelVersion>
2525
5858 <scope>test</scope>
5959 </dependency>
6060 <dependency>
61 <groupId>org.hamcrest</groupId>
62 <artifactId>hamcrest</artifactId>
61 <groupId>org.hamcrest</groupId>
62 <artifactId>hamcrest</artifactId>
63 <scope>test</scope>
6364 </dependency>
6465 <dependency>
6566 <groupId>org.junit.jupiter</groupId>
6667 <artifactId>junit-jupiter-engine</artifactId>
68 <scope>test</scope>
6769 </dependency>
6870 <dependency>
6971 <groupId>org.mockito</groupId>
7072 <artifactId>mockito-junit-jupiter</artifactId>
71 </dependency>
73 <scope>test</scope>
74 </dependency>
7275 <dependency>
7376 <groupId>org.springframework</groupId>
7477 <artifactId>spring-test</artifactId>
3434 */
3535 public class Log4jServletContextListener implements ServletContextListener {
3636
37 private static final int DEFAULT_STOP_TIMEOUT = 30;
37 private static final int DEFAULT_STOP_TIMEOUT = 30;
3838 private static final TimeUnit DEFAULT_STOP_TIMEOUT_TIMEUNIT = TimeUnit.SECONDS;
3939
40 private static final String KEY_STOP_TIMEOUT = "log4j.stop.timeout";
41 private static final String KEY_STOP_TIMEOUT_TIMEUNIT = "log4j.stop.timeout.timeunit";
40 private static final String KEY_STOP_TIMEOUT = "log4j.stop.timeout";
41 private static final String KEY_STOP_TIMEOUT_TIMEUNIT = "log4j.stop.timeout.timeunit";
4242
43 private static final Logger LOGGER = StatusLogger.getLogger();
43 private static final Logger LOGGER = StatusLogger.getLogger();
4444
4545 private ServletContext servletContext;
4646 private Log4jWebLifeCycle initializer;
5252
5353 if ("true".equalsIgnoreCase(servletContext.getInitParameter(
5454 Log4jWebSupport.IS_LOG4J_AUTO_SHUTDOWN_DISABLED))) {
55 throw new IllegalStateException("Do not use " + getClass().getSimpleName() + " when "
56 + Log4jWebSupport.IS_LOG4J_AUTO_SHUTDOWN_DISABLED + " is true. Please use "
57 + Log4jShutdownOnContextDestroyedListener.class.getSimpleName() + " instead of "
58 + getClass().getSimpleName() + ".");
55 throw new IllegalStateException("Do not use " + getClass().getSimpleName() + " when "
56 + Log4jWebSupport.IS_LOG4J_AUTO_SHUTDOWN_DISABLED + " is true. Please use "
57 + Log4jShutdownOnContextDestroyedListener.class.getSimpleName() + " instead of "
58 + getClass().getSimpleName() + ".");
5959 }
6060
6161 this.initializer = WebLoggerContextUtils.getWebLifeCycle(this.servletContext);
6868 }
6969
7070 @Override
71 public void contextDestroyed(final ServletContextEvent event) {
72 if (this.servletContext == null || this.initializer == null) {
73 LOGGER.warn("Context destroyed before it was initialized.");
74 return;
75 }
76 LOGGER.debug("Log4jServletContextListener ensuring that Log4j shuts down properly.");
71 public void contextDestroyed(final ServletContextEvent event) {
72 if (this.servletContext == null || this.initializer == null) {
73 LOGGER.warn("Context destroyed before it was initialized.");
74 return;
75 }
76 LOGGER.debug("Log4jServletContextListener ensuring that Log4j shuts down properly.");
7777
78 this.initializer.clearLoggerContext(); // the application is finished
79 // shutting down now
80 if (initializer instanceof LifeCycle2) {
81 final String stopTimeoutStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT);
82 final long stopTimeout = Strings.isEmpty(stopTimeoutStr) ? DEFAULT_STOP_TIMEOUT
83 : Long.parseLong(stopTimeoutStr);
84 final String timeoutTimeUnitStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT_TIMEUNIT);
85 final TimeUnit timeoutTimeUnit = Strings.isEmpty(timeoutTimeUnitStr) ? DEFAULT_STOP_TIMEOUT_TIMEUNIT
86 : TimeUnit.valueOf(timeoutTimeUnitStr.toUpperCase(Locale.ROOT));
87 ((LifeCycle2) this.initializer).stop(stopTimeout, timeoutTimeUnit);
88 } else {
89 this.initializer.stop();
90 }
91 }
78 this.initializer.clearLoggerContext(); // the application is finished
79 // shutting down now
80 if (initializer instanceof LifeCycle2) {
81 final String stopTimeoutStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT);
82 final long stopTimeout = Strings.isEmpty(stopTimeoutStr) ? DEFAULT_STOP_TIMEOUT
83 : Long.parseLong(stopTimeoutStr);
84 final String timeoutTimeUnitStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT_TIMEUNIT);
85 final TimeUnit timeoutTimeUnit = Strings.isEmpty(timeoutTimeUnitStr) ? DEFAULT_STOP_TIMEOUT_TIMEUNIT
86 : TimeUnit.valueOf(timeoutTimeUnitStr.toUpperCase(Locale.ROOT));
87 ((LifeCycle2) this.initializer).stop(stopTimeout, timeoutTimeUnit);
88 } else {
89 this.initializer.stop();
90 }
91 }
9292 }
7070 chain.doFilter(request, response);
7171 } finally {
7272 this.initializer.clearLoggerContext();
73 // Execute once per thread
74 request.removeAttribute(ALREADY_FILTERED_ATTRIBUTE);
7375 }
7476 }
7577 }
4343 @Override
4444 public void contextInitialized(final ServletContextEvent event) {
4545 LOGGER.debug(Log4jShutdownOnContextDestroyedListener.class.getSimpleName() +
46 " ensuring that Log4j started up properly.");
46 " ensuring that Log4j started up properly.");
4747 servletContext = event.getServletContext();
4848 if (null == servletContext.getAttribute(Log4jWebSupport.SUPPORT_ATTRIBUTE)) {
49 throw new IllegalStateException(
50 "Context did not contain required Log4jWebLifeCycle in the "
51 + Log4jWebSupport.SUPPORT_ATTRIBUTE + " attribute.");
49 throw new IllegalStateException(
50 "Context did not contain required Log4jWebLifeCycle in the "
51 + Log4jWebSupport.SUPPORT_ATTRIBUTE + " attribute.");
5252 }
5353 this.initializer = WebLoggerContextUtils.getWebLifeCycle(servletContext);
5454 }
6060 return;
6161 }
6262 LOGGER.debug(Log4jShutdownOnContextDestroyedListener.class.getSimpleName() +
63 " ensuring that Log4j shuts down properly.");
63 " ensuring that Log4j shuts down properly.");
6464
6565 this.initializer.clearLoggerContext(); // the application is finished
6666 // shutting down now
3737 @Plugin(name = "Servlet", category = "Core", elementType = "appender", printObject = true)
3838 public class ServletAppender extends AbstractAppender {
3939
40 public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
41 implements org.apache.logging.log4j.core.util.Builder<ServletAppender> {
40 public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
41 implements org.apache.logging.log4j.core.util.Builder<ServletAppender> {
4242
4343 @PluginBuilderAttribute
4444 private boolean logThrowables;
4545
46 @Override
47 public ServletAppender build() {
48 final String name = getName();
49 if (name == null) {
50 LOGGER.error("No name provided for ServletAppender");
51 }
52 final ServletContext servletContext = WebLoggerContextUtils.getServletContext();
53 if (servletContext == null) {
54 LOGGER.error("No servlet context is available");
55 return null;
56 }
57 final Layout<? extends Serializable> layout = getOrCreateLayout();
58 if (!(layout instanceof StringLayout)) {
59 LOGGER.error("Layout must be a StringLayout to log to ServletContext");
60 return null;
61 }
62 return new ServletAppender(name, layout, getFilter(), servletContext, isIgnoreExceptions(), logThrowables);
63 }
46 @Override
47 public ServletAppender build() {
48 final String name = getName();
49 if (name == null) {
50 LOGGER.error("No name provided for ServletAppender");
51 }
52 final ServletContext servletContext = WebLoggerContextUtils.getServletContext();
53 if (servletContext == null) {
54 LOGGER.error("No servlet context is available");
55 return null;
56 }
57 final Layout<? extends Serializable> layout = getOrCreateLayout();
58 if (!(layout instanceof StringLayout)) {
59 LOGGER.error("Layout must be a StringLayout to log to ServletContext");
60 return null;
61 }
62 return new ServletAppender(name, layout, getFilter(), servletContext, isIgnoreExceptions(), logThrowables);
63 }
6464
6565 /**
6666 * Logs with {@link ServletContext#log(String, Throwable)} if true and with {@link ServletContext#log(String)} if false.
7878 this.logThrowables = logThrowables;
7979 }
8080
81 }
81 }
8282
8383 @PluginBuilderFactory
8484 public static <B extends Builder<B>> B newBuilder() {
119119 public static ServletAppender createAppender(final Layout<? extends Serializable> layout, final Filter filter,
120120 final String name, final boolean ignoreExceptions) {
121121 // @formatter:off
122 return newBuilder().setFilter(filter).setIgnoreExceptions(ignoreExceptions).setLayout(layout).setName(name)
123 .build();
124 // @formatter:on
122 return newBuilder().setFilter(filter).setIgnoreExceptions(ignoreExceptions).setLayout(layout).setName(name)
123 .build();
124 // @formatter:on
125125 }
126126
127127 }
3333
3434 @ExtendWith(MockitoExtension.class)
3535 public class Log4jServletContextListenerTest {
36 /* event and servletContext are marked lenient because they aren't used in the
37 * testDestroyWithNoInit but are only accessed during initialization
38 */
39 @Mock(lenient = true)
40 private ServletContextEvent event;
41 @Mock(lenient = true)
36 /* event and servletContext are marked lenient because they aren't used in the
37 * testDestroyWithNoInit but are only accessed during initialization
38 */
39 @Mock(lenient = true)
40 private ServletContextEvent event;
41 @Mock(lenient = true)
4242 private ServletContext servletContext;
4343 @Mock
4444 private Log4jWebLifeCycle initializer;
7171
7272 @Test
7373 public void testDestroy() {
74 assertThrows(IllegalStateException.class, () -> {
75 this.filter.destroy();
76 });
74 assertThrows(IllegalStateException.class, () -> {
75 this.filter.destroy();
76 });
7777 }
7878
7979 @Test
9292 then(chain).should().doFilter(same(request), same(response));
9393 then(chain).shouldHaveNoMoreInteractions();
9494 then(initializer).should().clearLoggerContext();
95 then(request).should().removeAttribute(Log4jServletFilter.ALREADY_FILTERED_ATTRIBUTE);
9596 }
9697
9798 @Test
4242 public void setUp(boolean mockInitializer) {
4343 this.listener = new Log4jShutdownOnContextDestroyedListener();
4444 given(event.getServletContext()).willReturn(servletContext);
45 if (mockInitializer) {
46 given(servletContext.getAttribute(Log4jWebSupport.SUPPORT_ATTRIBUTE))
47 .willReturn(initializer);
45 if (mockInitializer) {
46 given(servletContext.getAttribute(Log4jWebSupport.SUPPORT_ATTRIBUTE))
47 .willReturn(initializer);
4848 }
4949 }
50
50
5151 @Test
5252 public void testInitAndDestroy() throws Exception {
53 setUp(true);
53 setUp(true);
5454 this.listener.contextInitialized(this.event);
5555
5656 then(initializer).should(never()).start();
6464
6565 @Test
6666 public void testDestroy() throws Exception {
67 setUp(true);
67 setUp(true);
6868 this.listener.contextDestroyed(this.event);
6969
7070 then(initializer).should(never()).clearLoggerContext();
7373
7474 @Test
7575 public void whenNoInitializerInContextTheContextInitializedShouldThrowAnException() {
76 setUp(false);
77
78 assertThrows(IllegalStateException.class, () -> {
79 this.listener.contextInitialized(this.event);
80 });
76 setUp(false);
77
78 assertThrows(IllegalStateException.class, () -> {
79 this.listener.contextInitialized(this.event);
80 });
8181 }
8282 }
4444
4545 @ExtendWith(MockitoExtension.class)
4646 public class Log4jWebInitializerImplTest {
47 /* Marking servletContext lenient because otherwise testCompositeLocationParameterWithEmptyUriListSetsDefaultConfiguration fails
48 * when null is passed in as the initial param because Mockito deciced null isn't a String rather than the absence of a string.
49 */
50 @Mock(lenient = true)
51 private ServletContext servletContext;
47 /* Marking servletContext lenient because otherwise testCompositeLocationParameterWithEmptyUriListSetsDefaultConfiguration fails
48 * when null is passed in as the initial param because Mockito deciced null isn't a String rather than the absence of a string.
49 */
50 @Mock(lenient = true)
51 private ServletContext servletContext;
5252 @Captor
5353 private ArgumentCaptor<Log4jWebLifeCycle> initializerCaptor;
5454 @Captor
7272
7373 @Test
7474 public void testDeinitializeBeforeInitialize() {
75 assertThrows(IllegalStateException.class, () -> {
76 this.initializerImpl.stop();
77 });
75 assertThrows(IllegalStateException.class, () -> {
76 this.initializerImpl.stop();
77 });
7878 }
7979
8080 @Test
213213
214214 then(servletContext).should().removeAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE));
215215
216 assertThrows(IllegalStateException.class, () -> {
217 this.initializerImpl.start();
218 });
216 assertThrows(IllegalStateException.class, () -> {
217 this.initializerImpl.start();
218 });
219219 }
220220
221221 @Test
247247 given(servletContext.getResourcePaths("/WEB-INF/")).willReturn(null);
248248 assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null.");
249249
250 assertThrows(IllegalStateException.class, () -> {
251 this.initializerImpl.start();
252 });
250 assertThrows(IllegalStateException.class, () -> {
251 this.initializerImpl.start();
252 });
253253 }
254254
255255 @Test
2020 <artifactId>log4j</artifactId>
2121 <packaging>pom</packaging>
2222 <name>Apache Log4j 2</name>
23 <version>2.18.0</version>
23 <version>2.19.0</version>
2424 <parent>
2525 <groupId>org.apache.logging</groupId>
2626 <artifactId>logging-parent</artifactId>
159159 <name>Piotr P. Karwasz</name>
160160 <email>pkarwasz@apache.org</email>
161161 <roles>
162 <role>Committer</role>
162 <role>PMC Member</role>
163163 </roles>
164164 <timezone>Europe/Warsaw</timezone>
165165 </developer>
223223 <connection>scm:git:https://gitbox.apache.org/repos/asf/logging-log4j2.git</connection>
224224 <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/logging-log4j2.git</developerConnection>
225225 <url>https://gitbox.apache.org/repos/asf?p=logging-log4j2.git</url>
226 <tag>log4j-2.18.0-rc1</tag>
226 <tag>log4j-2.19.0-rc2</tag>
227227 </scm>
228228 <properties>
229229 <!-- make sure to update these for each release! -->
230230 <log4jParentDir>${basedir}</log4jParentDir>
231 <Log4jReleaseVersion>2.18.0</Log4jReleaseVersion>
231 <Log4jReleaseVersion>2.19.0</Log4jReleaseVersion>
232232 <Log4jReleaseVersionJava7>2.12.4</Log4jReleaseVersionJava7>
233233 <Log4jReleaseVersionJava6>2.3.2</Log4jReleaseVersionJava6>
234234 <Log4jReleaseManager>Ralph Goers</Log4jReleaseManager>
238238 <slf4jVersion>1.7.36</slf4jVersion>
239239 <logbackVersion>1.2.11</logbackVersion>
240240 <jackson1Version>1.9.13</jackson1Version>
241 <jackson2Version>2.13.3</jackson2Version>
241 <jackson2Version>2.13.4</jackson2Version>
242242 <spring-boot.version>2.6.7</spring-boot.version>
243243 <springVersion>5.3.20</springVersion>
244244 <kubernetes-client.version>5.12.2</kubernetes-client.version>
245 <flumeVersion>1.10.0</flumeVersion>
245 <flumeVersion>1.10.1</flumeVersion>
246246 <disruptorVersion>3.4.4</disruptorVersion>
247247 <conversantDisruptorVersion>1.2.15</conversantDisruptorVersion> <!-- Version 1.2.16 requires Java 9 -->
248 <elastic.version>7.17.4</elastic.version>
248 <elastic.version>7.17.6</elastic.version>
249249 <mongodb3.version>3.12.11</mongodb3.version>
250250 <mongodb4.version>4.5.0</mongodb4.version>
251251 <!-- POM for jackson-dataformat-xml 2.13.1 depends on woodstox-core 6.2.7 -->
252 <woodstox.version>6.2.8</woodstox.version>
252 <woodstox.version>6.3.1</woodstox.version>
253253 <groovy.version>3.0.10</groovy.version>
254254 <compiler.plugin.version>3.10.1</compiler.plugin.version>
255255 <pmd.plugin.version>3.16.0</pmd.plugin.version>
295295 <activemq.version>5.17.1</activemq.version>
296296 <jctoolsVersion>3.3.0</jctoolsVersion>
297297 <junitVersion>4.13.2</junitVersion>
298 <junitJupiterVersion>5.8.2</junitJupiterVersion>
298 <junit5Version>5.9.0</junit5Version>
299299 <junitPioneerVersion>1.6.2</junitPioneerVersion>
300300 <mockitoVersion>4.4.0</mockitoVersion>
301301 <xmlunitVersion>2.9.0</xmlunitVersion>
302302 <!-- Java EE 8 artifacts -->
303303 <javax.activation.version>1.2.0</javax.activation.version>
304 <javax.inject.version>1</javax.inject.version>
304305 <javax.jms.version>2.0.1</javax.jms.version>
305306 <javax.jsp.version>2.3.3</javax.jsp.version>
306307 <javax.mail.version>1.6.2</javax.mail.version>
314315 <module.name />
315316 <!-- Used in `log4j-appserver`, so that it does not override `wiremock`'s deps-->
316317 <jetty.version>9.4.48.v20220622</jetty.version>
317 <netty-all.version>4.1.72.Final</netty-all.version>
318 <netty-all.version>4.1.80.Final</netty-all.version>
318319 </properties>
319320 <pluginRepositories>
320321 <pluginRepository>
333334 <dependencyManagement>
334335 <dependencies>
335336 <dependency>
337 <groupId>org.apache.logging.log4j</groupId>
338 <artifactId>log4j-bom</artifactId>
339 <version>${project.version}</version>
340 <type>pom</type>
341 <scope>import</scope>
342 </dependency>
343 <dependency>
336344 <groupId>org.slf4j</groupId>
337345 <artifactId>slf4j-api</artifactId>
338346 <version>${slf4jVersion}</version>
458466 </dependency>
459467 <dependency>
460468 <groupId>org.apache.logging.log4j</groupId>
461 <artifactId>log4j-slf4j18-impl</artifactId>
469 <artifactId>log4j-slf4j2-impl</artifactId>
462470 <version>${project.version}</version>
463471 </dependency>
464472 <dependency>
465473 <groupId>org.apache.logging.log4j</groupId>
466474 <artifactId>log4j-jcl</artifactId>
475 <version>${project.version}</version>
476 </dependency>
477 <dependency>
478 <groupId>org.apache.logging.log4j</groupId>
479 <artifactId>log4j-to-jul</artifactId>
480 <version>${project.version}</version>
481 </dependency>
482 <dependency>
483 <groupId>org.apache.logging.log4j</groupId>
484 <artifactId>log4j-to-slf4j</artifactId>
467485 <version>${project.version}</version>
468486 </dependency>
469487 <dependency>
713731 <scope>provided</scope>
714732 </dependency>
715733 <dependency>
734 <groupId>javax.inject</groupId>
735 <artifactId>javax.inject</artifactId>
736 <version>${javax.inject.version}</version>
737 <scope>provided</scope>
738 </dependency>
739 <dependency>
716740 <groupId>javax.jms</groupId>
717741 <artifactId>javax.jms-api</artifactId>
718742 <version>${javax.jms.version}</version>
804828 </dependency>
805829 <!-- JUnit 5 engine -->
806830 <dependency>
807 <groupId>org.junit.jupiter</groupId>
808 <artifactId>junit-jupiter-engine</artifactId>
809 <version>${junitJupiterVersion}</version>
810 <scope>test</scope>
811 </dependency>
812 <dependency>
813 <groupId>org.junit.jupiter</groupId>
814 <artifactId>junit-jupiter-api</artifactId>
815 <version>${junitJupiterVersion}</version>
816 <scope>test</scope>
817 </dependency>
818 <dependency>
819 <groupId>org.junit.platform</groupId>
820 <artifactId>junit-platform-commons</artifactId>
821 <version>1.8.2</version>
822 <scope>test</scope>
823 </dependency>
824 <!-- JUnit 4 to 5 migration support -->
825 <dependency>
826 <groupId>org.junit.jupiter</groupId>
827 <artifactId>junit-jupiter-migrationsupport</artifactId>
828 <version>${junitJupiterVersion}</version>
829 <scope>test</scope>
830 </dependency>
831 <!-- JUnit 5 parameterized test support -->
832 <dependency>
833 <groupId>org.junit.jupiter</groupId>
834 <artifactId>junit-jupiter-params</artifactId>
835 <version>${junitJupiterVersion}</version>
836 <scope>test</scope>
831 <groupId>org.junit</groupId>
832 <artifactId>junit-bom</artifactId>
833 <version>${junit5Version}</version>
834 <type>pom</type>
835 <scope>import</scope>
837836 </dependency>
838837 <!-- Environment and system properties support for Jupiter -->
839838 <dependency>
847846 <groupId>junit</groupId>
848847 <artifactId>junit</artifactId>
849848 <version>${junitVersion}</version>
850 <scope>test</scope>
851 </dependency>
852 <!-- JUnit 4 engine -->
853 <dependency>
854 <groupId>org.junit.vintage</groupId>
855 <artifactId>junit-vintage-engine</artifactId>
856 <version>${junitJupiterVersion}</version>
857849 <scope>test</scope>
858850 </dependency>
859851 <dependency>
987979 <dependency>
988980 <groupId>net.javacrumbs.json-unit</groupId>
989981 <artifactId>json-unit</artifactId>
990 <version>2.32.0</version>
982 <version>2.35.0</version>
991983 <scope>test</scope>
992984 </dependency>
993985 <dependency>
10121004 <dependency>
10131005 <groupId>co.elastic.logging</groupId>
10141006 <artifactId>log4j2-ecs-layout</artifactId>
1015 <version>1.4.0</version>
1007 <version>1.5.0</version>
10161008 </dependency>
10171009 <dependency>
10181010 <groupId>org.elasticsearch.client</groupId>
12991291 <plugin>
13001292 <groupId>io.fabric8</groupId>
13011293 <artifactId>docker-maven-plugin</artifactId>
1302 <version>0.40.1</version>
1294 <version>0.40.2</version>
13031295 </plugin>
13041296 </plugins>
13051297 </pluginManagement>
17001692 <module>log4j-core-its</module>
17011693 <module>log4j-1.2-api</module>
17021694 <module>log4j-slf4j-impl</module>
1703 <module>log4j-slf4j18-impl</module>
1695 <module>log4j-slf4j2-impl</module>
17041696 <module>log4j-to-slf4j</module>
17051697 <module>log4j-to-jul</module>
17061698 <module>log4j-jcl</module>
6767 This release primarily contains bug fixes and minor enhancements.
6868
6969 Due to a break in compatibility in the SLF4J binding, Log4j now ships with two versions of the SLF4J to Log4j adapters.
70 log4j-slf4j-impl should be used with SLF4J 1.7.x and earlier and log4j-slf4j18-impl should be used with SLF4J 1.8.x and
71 later. SLF4J-2.0.0 alpha releases are not fully supported. See https://issues.apache.org/jira/browse/LOG4J2-2975 and
72 https://jira.qos.ch/browse/SLF4J-511.
70 log4j-slf4j-impl should be used with SLF4J 1.7.x and earlier and log4j-slf4j2-impl should be used with SLF4J 2.x and
71 later. SLF4J-1.8.x is no longer supported as a GA release never occurred.
7372
7473 The Log4j ${relVersion} API, as well as many core components, maintains binary compatibility with previous releases.
7574
2828 - "update" - Change
2929 - "remove" - Removed
3030 -->
31 <release version="2.19.0" date="2022-09-09" description="GA Release 2.19.0">
32 <action issue="LOG4J2-3572" dev="rgeors" type="update">
33 Add getExplicitLevel method to LoggerConfig.
34 </action>
35 <action issue="LOG4J2-3589" dev="rgoers" type="update">
36 Allow Plugins to be injected with the LoggerContext reference.
37 </action>
38 <action issue="LOG4J2-3588" dev="rgoers" type="update">
39 Allow PropertySources to be added.
40 </action>
41 <action issue="LOG4J2-3578" dev="rgoers" type="fix">
42 Generate new SSL certs for testing.
43 </action>
44 <action issue="LOG4J2-3556" dev="vy" type="fix" due-to=" Arthur Gavlyukovskiy">
45 Make JsonTemplateLayout stack trace truncation operate for each label block.
46 </action>
47 <action issue="LOG4J2-3573" dev="vy" type="remove" due-to=" Wolff Bock von Wuelfingen">
48 Removed build page in favor of a single build instructions file.
49 </action>
50 <action issue="LOG4J2-3550" dev="rgoers" type="fix" due-to="DongjianPeng">
51 SystemPropertyArbiter was assigning the value as the name.
52 </action>
53 <action issue="LOG4J2-3560" dev="ckozak" type="fix" due-to="David Schlosnagle">
54 Logger$PrivateConfig.filter(Level, Marker, String) was allocating empty varargs array.
55 </action>
56 <action issue="LOG4J2-3561" dev="pkarwasz" type="fix" due-to="Robert Papp">
57 Allows a space separated list of style specifiers in the %style pattern for consistency with %highlight.
58 </action>
59 <action issue="LOG4J2-3564" dev="pkarwasz" type="fix">
60 Fix NPE in `log4j-to-jul` in the case the root logger level is null.
61 </action>
62 <action issue="LOG4J2-3545" dev="pkarwasz" type="fix" due-to="Johan Compagner">
63 Add correct manifest entries for OSGi to log4j-jcl
64 </action>
65 <action issue="LOG4J2-3565" dev="dafengsu7" type="fix">
66 Fix RollingRandomAccessFileAppender with DirectWriteRolloverStrategy can't create the first log file of different directory.
67 </action>
68 <action issue="LOG4J2-3579" dev="pkarwasz" type="fix" due-to="Boris Unckel">
69 Fix ServiceLoaderUtil behavior in the presence of a SecurityManager.
70 </action>
71 <action issue="LOG4J2-3559" dev="pkarwasz" type="fix" due-to="Gary Gregory">
72 Fix resolution of properties not starting with `log4j2.`.
73 </action>
74 <action issue="LOG4J2-3583" dev="pkarwasz" type="add" due-to="Pierrick Terrettaz">
75 Add support for SLF4J2 stack-valued MDC.
76 </action>
77 <action issue="LOG4J2-2975" dev="pkarwasz" type="add" due-to="Daniel Gray">
78 Add implementation of SLF4J2 fluent API.
79 </action>
80 <action issue="LOG4J2-3590" dev="pkarwasz" type="remove">
81 Remove SLF4J 1.8.x binding.
82 </action>
83 <action issue="LOG4J2-3557" dev="pkarwasz" type="fix" due-to="Andreas Leitgeb">
84 Fix recursion between Log4j 1.2 LogManager and Category.
85 </action>
86 <action issue="LOG4J2-3587" dev="pkarwasz" type="fix" due-to="Tomas Micko">
87 Fix regression in Rfc5424Layout default values.
88 </action>
89 <action issue="LOG4J2-3548" dev="pkarwasz" type="fix" due-to="Kristof Farkas-Pall">
90 Improve support for passwordless keystores.
91 </action>
92 <action issue="LOG4J2-708" dev="pkarwasz" type="fix">
93 Add async support to `Log4jServletFilter`.
94 </action>
95 </release>
3196 <release version="2.18.0" date="2022-06-28" description="GA Release 2.18.0">
3297 <action issue="LOG4J2-3339" dev="rgoers" type="fix">
3398 DirectWriteRolloverStrategy should use the current time when creating files.
407472 Add optional additional fields to NoSQLAppender.
408473 </action>
409474 <!-- UPDATES -->
410 <action issue="LOG4J2-3368" dev="vy" type="udpate">
475 <action issue="LOG4J2-3368" dev="vy" type="update">
411476 Bump Tomcat from 8.5.20 to 10.0.14 in log4j-appserver along with some dependency clean-up.
412477 </action>
413 <action dev="ggregory" type="udpate" due-to="Dependabot">
478 <action dev="ggregory" type="update" due-to="Dependabot">
414479 Bump mongodb3.version from 3.12.4 to 3.12.10 #605.
415480 </action>
416 <action dev="ggregory" type="udpate" due-to="Dependabot">
481 <action dev="ggregory" type="update" due-to="Dependabot">
417482 Bump awaitility from 4.0.3 to 4.1.1 #663.
418483 </action>
419 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
484 <action dev="ggregory" type="update" due-to="Gary Gregory">
420485 Bump Mockito from 3.11.2 to 4.2.0.
421486 </action>
422 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
487 <action dev="ggregory" type="update" due-to="Gary Gregory">
423488 Bump Jackson from 2.12.4 to 2.13.1.
424489 </action>
425 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
490 <action dev="ggregory" type="update" due-to="Gary Gregory">
426491 Bump org.junit.jupiter:junit-* from 5.7.2 to 5.8.2.
427492 </action>
428 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
493 <action dev="ggregory" type="update" due-to="Gary Gregory">
429494 Bump org.springframework:spring-* from 5.3.13 to 5.3.15.
430495 </action>
431 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
496 <action dev="ggregory" type="update" due-to="Gary Gregory">
432497 Bump de.flapdoodle.embed:de.flapdoodle.embed.mongo from 3.0.0 to 3.4.1. Update tests for binary incompatibilities in APIs.
433498 </action>
434 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
499 <action dev="ggregory" type="update" due-to="Gary Gregory">
435500 Bump org.fusesource.jansi:jansi from 2.3.4 to 2.4.0.
436501 </action>
437 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
502 <action dev="ggregory" type="update" due-to="Gary Gregory">
438503 Bump net.javacrumbs.json-unit:json-unit from 2.27.0 to 2.28.0.
439504 </action>
440 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
505 <action dev="ggregory" type="update" due-to="Gary Gregory">
441506 Bump org.assertj:assertj-core from 3.20.2 to 3.22.0.
442507 </action>
443 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
508 <action dev="ggregory" type="update" due-to="Gary Gregory">
444509 Bump org.xmlunit:xmlunit-* from 2.8.3 to 2.8.4.
445510 </action>
446 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
511 <action dev="ggregory" type="update" due-to="Gary Gregory">
447512 Bump org.codehaus.groovy:groovy-* from 3.0.8 to 3.0.9.
448513 </action>
449 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
514 <action dev="ggregory" type="update" due-to="Gary Gregory">
450515 Bump org.mongodb:bson from 4.2.2 to 4.5.0.
451516 </action>
452 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
517 <action dev="ggregory" type="update" due-to="Gary Gregory">
453518 Bump org.mongodb:mongodb-driver-sync from 4.2.2 to 4.5.0.
454519 </action>
455 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
520 <action dev="ggregory" type="update" due-to="Gary Gregory">
456521 Bump Woodstox 6.2.6 to 6.2.8.
457522 </action>
458 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
523 <action dev="ggregory" type="update" due-to="Gary Gregory">
459524 Bump maven-compiler-plugin from 3.8.1 to 3.9.0.
460525 </action>
461 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
526 <action dev="ggregory" type="update" due-to="Gary Gregory">
462527 Bump org.eclipse.persistence:org.eclipse.persistence.jpa from 2.7.9 to 2.7.10.
463528 </action>
464 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
529 <action dev="ggregory" type="update" due-to="Gary Gregory">
465530 Bump org.junit-pioneer:junit-pioneer from 1.5.0 to 1.6.1.
466531 </action>
467 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
532 <action dev="ggregory" type="update" due-to="Gary Gregory">
468533 Bump org.apache.activemq:activemq-broker from 5.16.3 to 5.16.4.
469534 </action>
470 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
535 <action dev="ggregory" type="update" due-to="Gary Gregory">
471536 Bump org.jacoco:jacoco-maven-plugin from 0.8.6 to 0.8.7.
472537 </action>
473 <action dev="ggregory" type="udpate" due-to="Gary Gregory">
538 <action dev="ggregory" type="update" due-to="Gary Gregory">
474539 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.3.1 to 3.3.2.
475540 </action>
476541 </release>
499564 Fix MapLookup to lookup MapMessage before DefaultMap
500565 </action>
501566 <action issue="LOG4J2-3274" dev="rgoers" type="fix" due-to="Faisal Khan Thayub Khan">
502 Buffered I/O checked had inverted logic in RollingFileAppenderBuidler.
567 Buffered I/O checked had inverted logic in RollingFileAppenderBuilder.
503568 </action>
504569 <action dev="ggregory" type="fix">
505570 Fix NPE when input is null in StrSubstitutor.replace(String, Properties).
551616 using '%m{lookups}'.
552617 </action>
553618 <action issue="LOG4J2-3194" dev="rgoers" type="add" due-to="markuss">
554 Allow fractional attributes for size attribute of SizeBsaedTriggeringPolicy.
619 Allow fractional attributes for size attribute of SizeBasedTriggeringPolicy.
555620 </action>
556621 <action issue="LOG4J2-2978" dev="rgoers" type="add" due-to="Michael Seele">
557622 Add support for Jakarta EE 9 (Tomcat 10 / Jetty 11)
598663 Allow MapMessage and ThreadContext attributes to be prefixed.
599664 </action>
600665 <action issue="LOG4J2=3048" dev="rgoers" type="add">
601 Add improved MapMessge support to GelfLayout.
666 Add improved MapMessage support to GelfLayout.
602667 </action>
603668 <action issue="LOG4J2-3044" dev="rgoers" type="add">
604669 Add RepeatPatternConverter.
633698 Fix Log Event Level vs Logger Config Level table.
634699 </action>
635700 <action issue="LOG4J2-2540" dev="rgoers">
636 Minor documentation correctsion regarding log levels.
701 Minor documentation corrections regarding log levels.
637702 </action>
638703 <action issue="LOG4J2-2541" dev="rgoers" due-to="Gerold Broser">
639704 Minor documentation corrections in the configuration section.
10681133 Move Spring Lookup and Spring PropertySource to its own module.
10691134 </action>
10701135 <action issue="LOG4J2-2910" dev="rgoers" type="fix">
1071 Log4j-web should now stores the servlet context as a map entry instead of in the single external context field.
1136 Log4j-web should now store the servlet context as a map entry instead of in the single external context field.
10721137 </action>
10731138 <action issue="LOG4J2-2822" dev="rgoers" type="fix">
10741139 Javadoc link in ThreadContext description was incorrect.
10841149 size based rollover after a time based rollover had occurred.
10851150 </action>
10861151 <action issue="LOG4J2-2875" dev="rgoers" type="fix">
1087 Rollover was failing to create directories when using a DirectFileeRolloverStrategy.
1152 Rollover was failing to create directories when using a DirectFileRolloverStrategy.
10881153 </action>
10891154 <action issue="LOG4J2-2859" dev="rgoers" type="fix" due-to="Yanming Zhou">
10901155 Fixed typos where mergeFactory should be mergeStrategy.
12591324 <action issue="LOG4J2-2717" dev="rgoers" type="fix">
12601325 Slow initialization on Windows due to accessing network interfaces.
12611326 </action>
1262 <action issue="LOG4J2-2789" dev="rgeors" type="update" due-to="Marius Volkhart">
1327 <action issue="LOG4J2-2789" dev="rgoers" type="update" due-to="Marius Volkhart">
12631328 Conditionally perform status logging calculations in PluginRegistry.
12641329 </action>
12651330 <action issue="LOG4J2-2756" dev="rgoers" type="fix">
12961361 PluginProcessor should use Messager instead of System.out.
12971362 </action>
12981363 <action issue="LOG4J2-2703" dev="rgoers" type="fix" due-to="Volkan Yazici">
1299 MapMessage.getFormattedMesssage() would incorrectly format objects.
1364 MapMessage.getFormattedMessage() would incorrectly format objects.
13001365 </action>
13011366 <action issue="LOG4J2-2760" dev="rgoers" type="fix" due-to="Christoph Kaser">
13021367 Always write header on a new OutputStream.
13121377 NullPointerException when using a custom DirectFileRolloverStrategy without a file name.
13131378 </action>
13141379 <action issue="LOG4J2-2768" dev="rgoers" type="fix" due-to="Marius Volkhart">
1315 Add mulit-parameter overloads to LogBuilder.
1380 Add multi-parameter overloads to LogBuilder.
13161381 </action>
13171382 <action issue="LOG4J2-2770" dev="rgoers" type="fix" due-to="Bill Kuker">
13181383 Fixed NullPointerException after reconfiguring via JMX.
13871452 Add ThreadContext.putIfNotNull method.
13881453 </action>
13891454 <action issue="LOG4J2-2731" dev="rgoers" type="add">
1390 Add a Level Patttern Selector.
1455 Add a Level Pattern Selector.
13911456 </action>
13921457 <action issue="LOG4J2-2701" dev="rgoers" type="update">
13931458 Update Jackson to 2.9.10.
14831548 Restore constructor to ThrowablePatternConverter that was removed in 2.8.2.
14841549 </action>
14851550 <action issue="LOG4J2-2622" dev="rgoers" type="fix">
1486 StructuredDataId was ignoring maxLength atribute.
1551 StructuredDataId was ignoring maxLength attribute.
14871552 </action>
14881553 <action issue="LOG4J2-2636" dev="rgoers" type="fix">
14891554 RFC5424Layout was not properly setting default Structured Element id for the MDC
15531618 PatternConverter instanceOf methods with unknown parameter types no longer elide those with known parameters.
15541619 </action>
15551620 <action issue="LOG4J2-2611" dev="ckozak" type="add">
1556 AsyncQueueFullPolicy configuration short values "Default" and "Discard" are case insensitive to avoid confusion.
1621 AsyncQueueFullPolicy configuration short values "Default" and "Discard" are case-insensitive to avoid confusion.
15571622 </action>
15581623 <action issue="LOG4J2-2612" dev="ggregory" type="fix">
15591624 NullPointerException at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeInternal(JdbcDatabaseManager.java:803).
18671932 logged throwable and provided varargs array.
18681933 </action>
18691934 <action issue="LOG4J2-2368" dev="ckozak" type="fix">
1870 Nested logging doesn't clobber AbstractStringLayout cached StringBuidlers
1935 Nested logging doesn't clobber AbstractStringLayout cached StringBuilders
18711936 </action>
18721937 <action issue="LOG4J2-2373" dev="ckozak" type="fix" due-to="Kevin Meurer">
18731938 StringBuilders.escapeJson implementation runs in linear time. Escaping large JSON strings
21032168 MapMessage should use deep toString for values.
21042169 </action>
21052170 <action issue="LOG4J2-2107" dev="mikes" type="fix" due-to="Carter Douglas Kozak">
2106 MapMessage supports both StringBuilderFormattable and MultiformatMessage.
2171 MapMessage supports both StringBuilderFormattable and MultiFormatMessage.
21072172 </action>
21082173 <action issue="LOG4J2-2102" dev="mikes" type="fix" due-to="Carter Douglas Kozak">
21092174 MapMessage JSON encoding will escape keys and values.
23482413 Consider the StringBuilder's capacity instead of content length when trimming.
23492414 </action>
23502415 <action issue="LOG4J2-1971" dev="rgoers" type="fix">
2351 Register log4j-core as an OSGi service. Skip tests for LOG4J2-1766 on MacOS. Use group "staff" for LOG4J2-1699 test on MacOS.
2416 Register log4j-core as an OSGi service. Skip tests for LOG4J2-1766 on macOS. Use group "staff" for LOG4J2-1699 test on macOS.
23522417 </action>
23532418 <action issue="LOG4J2-1994" dev="ggregory" type="fix">
23542419 TcpSocketServer does not close accepted Sockets.
24082473 JMS Appender does not know how to recover from a broken connection.
24092474 </action>
24102475 <action issue="LOG4J2-1955" dev="ggregory" type="add">
2411 JMS Appender should be able connect to a broker (later) even it is not present at configuration time.
2476 JMS Appender should be able to connect to a broker (later) even it is not present at configuration time.
24122477 </action>
24132478 <action issue="LOG4J2-1956" dev="ggregory" type="update">
24142479 JMS Appender broker password should be a char[], not a String.
33053370 minSize attribute.
33063371 </action>
33073372 <action issue="LOG4J2-1414" dev="rpopma" type="fix" due-to="Ralph Goers">
3308 Fixed minor issues with the 2.6.1 web site.
3373 Fixed minor issues with the 2.6.1 website.
33093374 </action>
33103375 <action issue="LOG4J2-1434" dev="rpopma" type="fix" due-to="Luke Butters">
33113376 Ensure that the thread-local StringBuilders used by Layouts to format log events to text will not
33893454 Added documentation about plugin builders compared to factories.
33903455 </action>
33913456 <action issue="LOG4J2-1394" dev="mattsicker,mikes" type="fix">
3392 Fixed minor issues with the 2.6 web site.
3457 Fixed minor issues with the 2.6 website.
33933458 </action>
33943459 </release>
33953460 <release version="2.6" date="2016-05-25" description="GA Release 2.6">
41104175 Avoid creating temporary array object in org.apache.logging.slf4j.Log4jMarker.iterator().
41114176 </action>
41124177 <action issue="LOG4J2-890" dev="ggregory" type="update" due-to="Hassan Kalaldeh, Robert Andersson, Remko Popma">
4113 log4j-web-2.1 should workaround a bug in JBOSS EAP 6.2.
4178 log4j-web-2.1 should work around a bug in JBOSS EAP 6.2.
41144179 </action>
41154180 <action issue="LOG4J2-403" dev="ggregory" type="update" due-to="Poorna Subhash P, Jeremy Lautman">
41164181 MongoDB appender, username and password should be optional.
43614426 Documentation: add sections on the JUL Adapter, IO Streams and NoSQL Appenders to the Maven and Ivy page.
43624427 </action>
43634428 <action issue="LOG4J2-797" dev="rpopma" type="fix" due-to="Andreas Rytina">
4364 Documentation: clarified why log4j-core is a compile time dependency in Maven and Ivy page.
4429 Documentation: clarified why log4j-core is a compile-time dependency in Maven and Ivy page.
43654430 </action>
43664431 <action issue="LOG4J2-855" dev="rpopma" type="fix">
43674432 Documentation: fix broken links on Appenders manual page.
43864451 Documentation: added section on XInclude to user manual Configuration page.
43874452 </action>
43884453 <action issue="LOG4J2-678" dev="rpopma" type="fix" due-to="Matt Sicker">
4389 Documentation: fixed minor issues with Log4j2 web site/documentation.
4454 Documentation: fixed minor issues with Log4j2 website/documentation.
43904455 </action>
43914456 <action issue="LOG4J2-844" dev="rpopma" type="update">
43924457 Update JMH to 1.1 from 0.7.2.
47344799 Create an appender to route log events to the ServletContext log.
47354800 </action>
47364801 <action issue="LOG4J2-419" dev="rgoers" type="update" due-to="Woonsan Ko">
4737 Support default value for missing key in look ups with fallback to looking in the properties map.
4802 Support default value for missing key in look-ups with fallback to looking in the properties map.
47384803 </action>
47394804 <action issue="LOG4J2-563" dev="rgoers" type="fix" due-to="Michael Friedmann">
47404805 FlumeAvroManager now always uses a client type of default_failover.
52125277 [Pattern Layout] Customize level names to lower-case.
52135278 </action>
52145279 <action issue="LOG4J2-355" dev="ggregory" type="update" due-to="Tibor Benke">
5215 Add support for multiple SD-ELEMENTs in a RFC 5424 syslog message.
5280 Add support for multiple SD-ELEMENTs in an RFC 5424 syslog message.
52165281 </action>
52175282 <action dev="nickwilliams" type="update">
52185283 Cleaned up tests and cleared up documentation for the JPA appender following the resolution of EclipseLink
55565621 Improved error reporting when misconfigured.
55575622 </action>
55585623 <action issue="LOG4J2-222" dev="rgoers" type="fix" due-to="Steven Yang">
5559 Disruptor will now shutdown during Tomcat shutdown.
5624 Disruptor will now shut down during Tomcat shutdown.
55605625 </action>
55615626 <action dev="rpopma" type="update">
55625627 Renamed AsynchAppender to AsyncAppender. Plugin name became Async (was Asynch).
58535918 Created combined jar to combine API and Core contents for users who only want the Log4j implementation.
58545919 </action>
58555920 <action issue="LOG4J2-104" dev="rgoers" type="fix">
5856 Convert LogManager binding to use "regular" java properties instead of XML properties to workaround a
5921 Convert LogManager binding to use "regular" java properties instead of XML properties to work around a
58575922 bug in Oracle's xmlparserv2 jar.
58585923 </action>
58595924 <action issue="LOG4J2-28" dev="rgoers" type="add">
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!--
2 ~ Licensed to the Apache Software Foundation (ASF) under one or more
3 ~ contributor license agreements. See the NOTICE file distributed with
4 ~ this work for additional information regarding copyright ownership.
5 ~ The ASF licenses this file to You under the Apache license, Version 2.0
6 ~ (the "License"); you may not use this file except in compliance with
7 ~ the License. You may obtain a copy of the License at
8 ~
9 ~ http://www.apache.org/licenses/LICENSE-2.0
10 ~
11 ~ Unless required by applicable law or agreed to in writing, software
12 ~ distributed under the License is distributed on an "AS IS" BASIS,
13 ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ~ See the license for the specific language governing permissions and
15 ~ limitations under the license.
16 -->
17 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
18 xmlns:pom="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
19 xmlns:xalan="http://xml.apache.org/xslt" exclude-result-prefixes="pom xalan">
20 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" xalan:indent-amount="2" />
21 <xsl:template match="pom:dependencies">
22 <dependencies>
23 <xsl:apply-templates select="pom:dependency[pom:scope = 'import']">
24 <xsl:sort select="concat(pom:artifactId, ' ', pom:groupId)" />
25 </xsl:apply-templates>
26 <xsl:apply-templates select="pom:dependency[pom:scope = 'provided']">
27 <xsl:sort select="concat(pom:artifactId, ' ', pom:groupId)" />
28 </xsl:apply-templates>
29 <xsl:apply-templates select="pom:dependency[not(pom:scope) or pom:scope = 'compile']">
30 <xsl:sort select="concat(pom:artifactId, ' ', pom:groupId)" />
31 </xsl:apply-templates>
32 <xsl:apply-templates select="pom:dependency[pom:scope = 'runtime']">
33 <xsl:sort select="concat(pom:artifactId, ' ', pom:groupId)" />
34 </xsl:apply-templates>
35 <xsl:apply-templates select="pom:dependency[pom:scope = 'test']">
36 <xsl:sort select="concat(pom:artifactId, ' ', pom:groupId)" />
37 </xsl:apply-templates>
38 </dependencies>
39 </xsl:template>
40 <xsl:template match="pom:exclusions">
41 <exclusions>
42 <xsl:apply-templates select="pom:exclusion">
43 <xsl:sort select="concat(pom:artifactId, ' ', pom:groupId)" />
44 </xsl:apply-templates>
45 </exclusions>
46 </xsl:template>
47 <!-- standard copy template -->
48 <xsl:template match="@*|node()">
49 <xsl:copy>
50 <xsl:apply-templates select="@*" />
51 <xsl:apply-templates />
52 </xsl:copy>
53 </xsl:template>
54 </xsl:stylesheet>