New upstream version 2.19.0
Emmanuel Bourg
1 year, 4 months ago
27 | 27 | steps: |
28 | 28 | |
29 | 29 | - name: Checkout repository |
30 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1 | |
30 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2 | |
31 | 31 | |
32 | 32 | # JDK 11 is needed for the build. |
33 | 33 | # Search `maven-toolchains-plugin` usages for details. |
34 | 34 | - name: Set up JDK 11 |
35 | uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1 | |
35 | uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1 | |
36 | 36 | with: |
37 | 37 | distribution: temurin |
38 | 38 | java-version: 11 |
43 | 43 | # JDK 8 is needed for the build, and it is the primary bytecode target. |
44 | 44 | # Hence, JDK 8 is set up after 11, so that JAVA_HOME used by Maven during build will point to 8. |
45 | 45 | - name: Set up JDK 8 |
46 | uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1 | |
46 | uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1 | |
47 | 47 | with: |
48 | 48 | distribution: temurin |
49 | 49 | java-version: 8 |
63 | 63 | package |
64 | 64 | |
65 | 65 | - name: Upload built sources |
66 | uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # 3.0.0 | |
66 | uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # 3.1.0 | |
67 | 67 | with: |
68 | 68 | name: benchmarks.jar |
69 | 69 | path: log4j-perf/target/benchmarks.jar |
86 | 86 | steps: |
87 | 87 | |
88 | 88 | - name: Checkout repository |
89 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1 | |
89 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2 | |
90 | 90 | |
91 | 91 | - name: Download built sources |
92 | 92 | uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 # 3.0.0 |
95 | 95 | path: log4j-perf/target |
96 | 96 | |
97 | 97 | - name: Set up JDK ${{ matrix.jdk }} |
98 | uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1 | |
98 | uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1 | |
99 | 99 | with: |
100 | 100 | distribution: temurin |
101 | 101 | java-version: ${{ matrix.jdk }} |
191 | 191 | steps: |
192 | 192 | |
193 | 193 | - name: Checkout repository |
194 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1 | |
194 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2 | |
195 | 195 | with: |
196 | 196 | ref: gh-pages |
197 | 197 | |
198 | 198 | - name: Setup Python 3 |
199 | uses: actions/setup-python@d09bd5e6005b175076f227b13d9730d56e9dcfcb # 4.0.0 | |
199 | uses: actions/setup-python@b55428b1882923874294fa556849718a1d7f2ca5 # 4.2.0 | |
200 | 200 | with: |
201 | 201 | python-version: 3.x |
202 | 202 |
27 | 27 | build: |
28 | 28 | |
29 | 29 | 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 | |
31 | 33 | strategy: |
32 | 34 | matrix: |
33 | 35 | os: [ ubuntu-latest, windows-latest, macos-latest ] |
35 | 37 | steps: |
36 | 38 | |
37 | 39 | - name: Checkout repository |
38 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1 | |
40 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2 | |
39 | 41 | |
40 | 42 | # JDK 11 is needed for the build. |
41 | 43 | # Search `maven-toolchains-plugin` usages for details. |
42 | 44 | - name: Setup JDK 11 |
43 | uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1 | |
45 | uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1 | |
44 | 46 | with: |
45 | 47 | distribution: temurin |
46 | 48 | java-version: 11 |
51 | 53 | # JDK 8 is needed for the build, and it is the primary bytecode target. |
52 | 54 | # Hence, JDK 8 is set up after 11, so that JAVA_HOME used by Maven during build will point to 8. |
53 | 55 | - name: Setup JDK 8 |
54 | uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1 | |
56 | uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1 | |
55 | 57 | with: |
56 | 58 | distribution: temurin |
57 | 59 | java-version: 8 |
101 | 103 | deploy: |
102 | 104 | |
103 | 105 | runs-on: ubuntu-latest |
106 | env: | |
107 | MAVEN_OPTS: -Xms3072m -Xmx3072m | |
104 | 108 | needs: build |
105 | 109 | if: github.repository == 'apache/logging-log4j2' && github.ref == 'refs/heads/release-2.x' |
106 | 110 | |
107 | 111 | steps: |
108 | 112 | |
109 | 113 | - name: Checkout repository |
110 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1 | |
114 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2 | |
111 | 115 | |
112 | 116 | # JDK 11 is needed for the build. |
113 | 117 | # Search `maven-toolchains-plugin` usages for details. |
114 | 118 | - name: Setup JDK 11 |
115 | uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1 | |
119 | uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1 | |
116 | 120 | with: |
117 | 121 | distribution: temurin |
118 | 122 | java-version: 11 |
123 | 127 | # JDK 8 is needed for the build, and it is the primary bytecode target. |
124 | 128 | # Hence, JDK 8 is set up after 11, so that JAVA_HOME used by Maven during build will point to 8. |
125 | 129 | - name: Setup JDK 8 |
126 | uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1 | |
130 | uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1 | |
127 | 131 | with: |
128 | 132 | distribution: temurin |
129 | 133 | java-version: 8 |
44 | 44 | steps: |
45 | 45 | |
46 | 46 | - name: Checkout repository |
47 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1 | |
47 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2 | |
48 | 48 | |
49 | 49 | # Initializes the CodeQL tools for scanning. |
50 | 50 | - name: Initialize CodeQL |
51 | uses: github/codeql-action/init@v2 | |
51 | uses: github/codeql-action/init@b398f525a5587552e573b247ac661067fafa920b # 2.1.22 | |
52 | 52 | with: |
53 | 53 | languages: ${{ matrix.language }} |
54 | 54 | # If you wish to specify custom queries, you can do so here or in a config file. |
59 | 59 | # JDK 11 is needed for the build. |
60 | 60 | # Search `maven-toolchains-plugin` usages for details. |
61 | 61 | - name: Setup JDK 11 |
62 | uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1 | |
62 | uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1 | |
63 | 63 | with: |
64 | 64 | distribution: temurin |
65 | 65 | java-version: 11 |
70 | 70 | # JDK 8 is needed for the build, and it is the primary bytecode target. |
71 | 71 | # Hence, JDK 8 is set up after 11, so that JAVA_HOME used by Maven during build will point to 8. |
72 | 72 | - name: Setup JDK 8 |
73 | uses: actions/setup-java@860f60056505705214d223b91ed7a30f173f6142 # 3.1.1 | |
73 | uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # 3.4.1 | |
74 | 74 | with: |
75 | 75 | distribution: temurin |
76 | 76 | java-version: 8 |
88 | 88 | --global-toolchains ".github/workflows/maven-toolchains.xml" |
89 | 89 | |
90 | 90 | - name: Perform CodeQL Analysis |
91 | uses: github/codeql-action/analyze@935969c6f771d9f0a35efa2ae9cf7c10d9886ca3 # 2.8.5 | |
91 | uses: github/codeql-action/analyze@b398f525a5587552e573b247ac661067fafa920b # 2.1.22 |
37 | 37 | steps: |
38 | 38 | |
39 | 39 | - name: "Checkout code" |
40 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.1 | |
40 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # 3.0.2 | |
41 | 41 | with: |
42 | 42 | persist-credentials: false |
43 | 43 | |
44 | 44 | - name: "Run analysis" |
45 | uses: ossf/scorecard-action@3e15ea8318eee9b333819ec77a36aca8d39df13e # 1.1.1 | |
45 | uses: ossf/scorecard-action@ce330fde6b1a5c9c75b417e7efc510b822a35564 # 1.1.2 | |
46 | 46 | with: |
47 | 47 | results_file: results.sarif |
48 | 48 | results_format: sarif |
54 | 54 | publish_results: true |
55 | 55 | |
56 | 56 | - name: "Upload artifact" |
57 | uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # 3.0.0 | |
57 | uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # 3.1.0 | |
58 | 58 | with: |
59 | 59 | name: SARIF file |
60 | 60 | path: results.sarif |
61 | 61 | retention-days: 5 |
62 | 62 | |
63 | 63 | - 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 | |
65 | 65 | with: |
66 | 66 | sarif_file: results.sarif |
13 | 13 | See the License for the specific language governing permissions and |
14 | 14 | limitations under the License. |
15 | 15 | --> |
16 | ||
16 | 17 | # Requirements |
17 | 18 | |
18 | 19 | * JDK 8 and 9+ |
22 | 23 | <a name="toolchains"></a> |
23 | 24 | # Configuring Maven Toolchains |
24 | 25 | |
25 | Maven Toolchains is used to employ both JDKs during compilation. | |
26 | Maven Toolchains is used to employ multiple JDKs required for compilation. | |
26 | 27 | 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. | |
28 | 29 | 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. |
29 | 30 | |
31 | <a name="building"></a> | |
30 | 32 | # Building the sources |
31 | 33 | |
32 | 34 | You can build and verify the sources as follows: |
33 | 35 | |
34 | 36 | ./mvnw verify |
35 | 37 | |
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: | |
37 | 40 | |
38 | ./mvwn -DskipTests -T8C package | |
41 | ./mvnw -DskipTests package | |
39 | 42 | |
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`. | |
41 | 44 | |
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> | |
42 | 56 | # Building the website and manual |
43 | 57 | |
44 | 58 | 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 | ||
0 | 17 | # [Apache Log4j 2](https://logging.apache.org/log4j/2.x/) |
1 | 18 | |
2 | 19 | Apache Log4j 2 is an upgrade to Log4j that provides significant improvements over its predecessor, Log4j 1.x, |
16 | 33 | ## Usage |
17 | 34 | |
18 | 35 | 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. | |
20 | 37 | |
21 | 38 | Basic usage of the `Logger` API: |
22 | 39 | |
93 | 110 | |
94 | 111 | ## Building From Source |
95 | 112 | |
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. | |
101 | 114 | |
102 | 115 | ## Contributing |
103 | 116 | |
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). |
13 | 13 | See the License for the specific language governing permissions and |
14 | 14 | limitations under the License. |
15 | 15 | --> |
16 | # Apache Log4j 2.18.0 Release Notes | |
16 | # Apache Log4j 2.19.0 Release Notes | |
17 | 17 | |
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! | |
19 | 19 | |
20 | 20 | Apache Log4j is a well known framework for logging application behavior. Log4j 2 is an upgrade |
21 | 21 | to Log4j that provides significant improvements over its predecessor, Log4j 1.x, and provides |
29 | 29 | This release primarily contains bug fixes and minor enhancements. |
30 | 30 | |
31 | 31 | 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. | |
35 | 34 | |
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. | |
37 | 36 | |
38 | ## GA Release 2.18.0 | |
37 | ## GA Release 2.19.0 | |
39 | 38 | |
40 | 39 | Changes in this version include: |
41 | 40 | |
42 | 41 | ### 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. | |
57 | 46 | |
58 | 47 | ### 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`. | |
125 | 76 | |
126 | 77 | ### 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. | |
139 | 84 | |
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. | |
140 | 90 | --- |
141 | 91 | |
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. | |
143 | 93 | Log4j 2.12.4 is the last release to support Java 7. |
144 | 94 | Log4j 2.3.2 is the last release to support Java 6. |
145 | 95 | Java 6 and Java 7 are no longer supported by the Log4j team. |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-1.2-api</artifactId> |
25 | 25 | <packaging>jar</packaging> |
47 | 47 | <dependency> |
48 | 48 | <groupId>org.junit.vintage</groupId> |
49 | 49 | <artifactId>junit-vintage-engine</artifactId> |
50 | <scope>test</scope> | |
50 | 51 | </dependency> |
51 | 52 | <dependency> |
52 | 53 | <groupId>org.junit.jupiter</groupId> |
53 | 54 | <artifactId>junit-jupiter-engine</artifactId> |
55 | <scope>test</scope> | |
54 | 56 | </dependency> |
55 | 57 | <dependency> |
56 | 58 | <groupId>org.junit.jupiter</groupId> |
57 | 59 | <artifactId>junit-jupiter-params</artifactId> |
60 | <scope>test</scope> | |
58 | 61 | </dependency> |
59 | 62 | <dependency> |
60 | 63 | <groupId>org.mockito</groupId> |
61 | 64 | <artifactId>mockito-core</artifactId> |
65 | <scope>test</scope> | |
62 | 66 | </dependency> |
63 | 67 | <dependency> |
64 | 68 | <groupId>org.apache.commons</groupId> |
36 | 36 | import org.apache.log4j.spi.HierarchyEventListener; |
37 | 37 | import org.apache.log4j.spi.LoggerRepository; |
38 | 38 | import org.apache.log4j.spi.LoggingEvent; |
39 | import org.apache.logging.log4j.core.config.LoggerConfig; | |
40 | 39 | import org.apache.logging.log4j.message.LocalizedMessage; |
41 | 40 | import org.apache.logging.log4j.message.MapMessage; |
42 | 41 | import org.apache.logging.log4j.message.Message; |
173 | 172 | protected Category(final LoggerContext context, final String name) { |
174 | 173 | this.name = name; |
175 | 174 | this.logger = context.getLogger(name); |
176 | this.repository = LogManager.getLoggerRepository(); | |
177 | // this.rendererMap = ((RendererSupport) repository).getRendererMap(); | |
178 | 175 | } |
179 | 176 | |
180 | 177 | Category(final org.apache.logging.log4j.Logger logger) { |
181 | 178 | this.logger = logger; |
182 | // rendererMap = ((RendererSupport) LogManager.getLoggerRepository()).getRendererMap(); | |
183 | 179 | } |
184 | 180 | |
185 | 181 | /** |
429 | 425 | } |
430 | 426 | |
431 | 427 | /** |
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. | |
433 | 429 | * |
434 | 430 | * @deprecated Please use {@link #getLoggerRepository()} instead. |
435 | 431 | * @since 1.1 |
452 | 448 | } |
453 | 449 | |
454 | 450 | /** |
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. | |
456 | 452 | * |
457 | 453 | * @since 1.2 |
458 | 454 | */ |
474 | 470 | return null; |
475 | 471 | } |
476 | 472 | 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; | |
479 | 479 | } |
480 | 480 | |
481 | 481 | public final Level getPriority() { |
98 | 98 | return PrivateLogManager.getContext(); |
99 | 99 | } |
100 | 100 | |
101 | static Logger getInstance(final LoggerContext context, final String name) { | |
101 | private Logger getInstance(final LoggerContext context, final String name) { | |
102 | 102 | return getInstance(context, name, LOGGER_ADAPTER); |
103 | 103 | } |
104 | 104 | |
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 | }); | |
111 | 119 | } |
112 | 120 | |
113 | 121 | static ConcurrentMap<String, Logger> getLoggersMap(final LoggerContext context) { |
114 | 122 | synchronized (CONTEXT_MAP) { |
115 | 123 | return CONTEXT_MAP.computeIfAbsent(context, k -> new ConcurrentHashMap<>()); |
116 | 124 | } |
117 | } | |
118 | ||
119 | static Logger getRootLogger(final LoggerContext context) { | |
120 | return getInstance(context, org.apache.logging.log4j.LogManager.ROOT_LOGGER_NAME); | |
121 | 125 | } |
122 | 126 | |
123 | 127 | private final LoggerFactory defaultFactory; |
526 | 530 | } |
527 | 531 | } |
528 | 532 | |
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 | ||
610 | 533 | } |
556 | 556 | * </p> |
557 | 557 | * |
558 | 558 | * <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 | |
560 | 560 | * significant for the class name part, if present. |
561 | 561 | * </p> |
562 | 562 | * |
47 | 47 | |
48 | 48 | /** |
49 | 49 | * 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. | |
51 | 51 | * @param appender The Appender to check. |
52 | 52 | * @return true if the Appender is attached. |
53 | 53 | * |
93 | 93 | public void testForcedLog() { |
94 | 94 | final MockCategory category = new MockCategory("org.example.foo"); |
95 | 95 | category.setAdditivity(false); |
96 | category.setHierarchy(LogManager.getHierarchy()); | |
96 | 97 | ((org.apache.logging.log4j.core.Logger) category.getLogger()).addAppender(appender); |
97 | 98 | // Logging a String |
98 | 99 | category.info("Hello, World"); |
19 | 19 | import org.apache.log4j.Level; |
20 | 20 | |
21 | 21 | /** |
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. | |
23 | 23 | */ |
24 | 24 | public class XLevel extends Level { |
25 | 25 | private static final long serialVersionUID = 7288304330257085144L; |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-api</artifactId> |
25 | 25 | <packaging>jar</packaging> |
46 | 46 | <dependency> |
47 | 47 | <groupId>org.junit.vintage</groupId> |
48 | 48 | <artifactId>junit-vintage-engine</artifactId> |
49 | <scope>test</scope> | |
49 | 50 | </dependency> |
50 | 51 | <dependency> |
51 | 52 | <groupId>org.junit.jupiter</groupId> |
52 | 53 | <artifactId>junit-jupiter-migrationsupport</artifactId> |
54 | <scope>test</scope> | |
53 | 55 | </dependency> |
54 | 56 | <dependency> |
55 | 57 | <groupId>org.junit.jupiter</groupId> |
56 | 58 | <artifactId>junit-jupiter-params</artifactId> |
59 | <scope>test</scope> | |
57 | 60 | </dependency> |
58 | 61 | <dependency> |
59 | 62 | <groupId>org.junit.jupiter</groupId> |
60 | 63 | <artifactId>junit-jupiter-engine</artifactId> |
64 | <scope>test</scope> | |
61 | 65 | </dependency> |
62 | 66 | <dependency> |
63 | 67 | <groupId>uk.org.webcompere</groupId> |
64 | 68 | <artifactId>system-stubs-jupiter</artifactId> |
69 | <scope>test</scope> | |
65 | 70 | </dependency> |
66 | 71 | <dependency> |
67 | 72 | <groupId>org.assertj</groupId> |
68 | 73 | <artifactId>assertj-core</artifactId> |
74 | <scope>test</scope> | |
69 | 75 | </dependency> |
70 | 76 | <dependency> |
71 | 77 | <groupId>org.eclipse.tycho</groupId> |
97 | 103 | <dependency> |
98 | 104 | <groupId>org.junit-pioneer</groupId> |
99 | 105 | <artifactId>junit-pioneer</artifactId> |
106 | <scope>test</scope> | |
100 | 107 | </dependency> |
101 | 108 | </dependencies> |
102 | 109 | <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 | } |
15 | 15 | */ |
16 | 16 | package org.apache.logging.log4j.internal; |
17 | 17 | |
18 | import org.apache.logging.log4j.BridgeAware; | |
18 | 19 | import org.apache.logging.log4j.Level; |
19 | 20 | import org.apache.logging.log4j.LogBuilder; |
20 | 21 | import org.apache.logging.log4j.Logger; |
30 | 31 | /** |
31 | 32 | * Collects data for a log event and then logs it. This class should be considered private. |
32 | 33 | */ |
33 | public class DefaultLogBuilder implements LogBuilder { | |
34 | public class DefaultLogBuilder implements BridgeAware, LogBuilder { | |
34 | 35 | |
35 | 36 | private static Message EMPTY_MESSAGE = new SimpleMessage(""); |
36 | 37 | private static final String FQCN = DefaultLogBuilder.class.getName(); |
43 | 44 | private StackTraceElement location; |
44 | 45 | private volatile boolean inUse; |
45 | 46 | private long threadId; |
47 | private String fqcn = FQCN; | |
46 | 48 | |
47 | 49 | public DefaultLogBuilder(Logger logger, Level level) { |
48 | 50 | this.logger = logger; |
55 | 57 | this.logger = logger; |
56 | 58 | this.inUse = false; |
57 | 59 | this.threadId = Thread.currentThread().getId(); |
60 | } | |
61 | ||
62 | @Override | |
63 | public void setEntryPoint(String fqcn) { | |
64 | this.fqcn = fqcn; | |
58 | 65 | } |
59 | 66 | |
60 | 67 | /** |
230 | 237 | |
231 | 238 | private void logMessage(Message message) { |
232 | 239 | try { |
233 | logger.logMessage(level, marker, FQCN, location, message, throwable); | |
240 | logger.logMessage(level, marker, fqcn, location, message, throwable); | |
234 | 241 | } finally { |
235 | 242 | inUse = false; |
236 | 243 | } |
+3
-1
63 | 63 | @Override |
64 | 64 | public CharSequence getNormalForm(final Iterable<? extends CharSequence> tokens) { |
65 | 65 | final StringBuilder sb = new StringBuilder("LOG4J"); |
66 | boolean empty = true; | |
66 | 67 | for (final CharSequence token : tokens) { |
68 | empty = false; | |
67 | 69 | sb.append('_'); |
68 | 70 | for (int i = 0; i < token.length(); i++) { |
69 | 71 | sb.append(Character.toUpperCase(token.charAt(i))); |
70 | 72 | } |
71 | 73 | } |
72 | return sb.toString(); | |
74 | return empty ? null : sb.toString(); | |
73 | 75 | } |
74 | 76 | |
75 | 77 | @Override |
57 | 57 | |
58 | 58 | @Override |
59 | 59 | 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; | |
61 | 62 | } |
62 | 63 | |
63 | 64 | @Override |
23 | 23 | import java.time.temporal.ChronoUnit; |
24 | 24 | import java.time.temporal.TemporalUnit; |
25 | 25 | import java.util.ArrayList; |
26 | import java.util.Collections; | |
27 | 26 | import java.util.HashSet; |
28 | 27 | import java.util.List; |
29 | 28 | import java.util.Map; |
34 | 33 | import java.util.Set; |
35 | 34 | import java.util.TreeSet; |
36 | 35 | import java.util.concurrent.ConcurrentHashMap; |
36 | import java.util.concurrent.ConcurrentSkipListSet; | |
37 | 37 | |
38 | 38 | /** |
39 | 39 | * <em>Consider this class private.</em> |
122 | 122 | } |
123 | 123 | |
124 | 124 | /** |
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 | /** | |
125 | 135 | * Returns {@code true} if the specified property is defined, regardless of its value (it may not have a value). |
126 | 136 | * |
127 | 137 | * @param name the name of the property to verify |
432 | 442 | */ |
433 | 443 | private static class Environment { |
434 | 444 | |
435 | private final Set<PropertySource> sources = new TreeSet<>(new PropertySource.Comparator()); | |
445 | private final Set<PropertySource> sources = new ConcurrentSkipListSet<>(new PropertySource.Comparator()); | |
436 | 446 | /** |
437 | 447 | * Maps a key to its value in the lowest priority source that contains it. |
438 | 448 | */ |
461 | 471 | .forEach(sources::add); |
462 | 472 | |
463 | 473 | 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); | |
464 | 482 | } |
465 | 483 | |
466 | 484 | private synchronized void reload() { |
480 | 498 | .filter(Objects::nonNull) |
481 | 499 | .forEach(key -> { |
482 | 500 | final List<CharSequence> tokens = PropertySource.Util.tokenize(key); |
501 | final boolean hasTokens = !tokens.isEmpty(); | |
483 | 502 | 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); | |
486 | 505 | literal.putIfAbsent(key, value); |
487 | if (!tokens.isEmpty()) { | |
506 | if (hasTokens) { | |
488 | 507 | tokenized.putIfAbsent(tokens, value); |
489 | 508 | } |
490 | 509 | } |
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)); | |
496 | 514 | } |
497 | 515 | } |
498 | 516 | }); |
507 | 525 | return literal.get(key); |
508 | 526 | } |
509 | 527 | final List<CharSequence> tokens = PropertySource.Util.tokenize(key); |
528 | final boolean hasTokens = !tokens.isEmpty(); | |
510 | 529 | 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 | } | |
517 | 535 | } |
518 | 536 | if (source.containsProperty(key)) { |
519 | final String value = source.getProperty(key); | |
520 | // literal.put(key, value); | |
521 | return value; | |
537 | return source.getProperty(key); | |
522 | 538 | } |
523 | 539 | } |
524 | 540 | 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 | } |
16 | 16 | |
17 | 17 | package org.apache.logging.log4j.util; |
18 | 18 | |
19 | import java.lang.invoke.CallSite; | |
20 | import java.lang.invoke.LambdaMetafactory; | |
19 | 21 | import java.lang.invoke.MethodHandle; |
20 | 22 | import java.lang.invoke.MethodHandles.Lookup; |
21 | 23 | import java.lang.invoke.MethodType; |
24 | import java.security.AccessController; | |
25 | import java.security.PrivilegedAction; | |
22 | 26 | import java.util.Collections; |
23 | 27 | import java.util.HashSet; |
24 | 28 | import java.util.Iterator; |
37 | 41 | * This class should be considered internal. |
38 | 42 | */ |
39 | 43 | public final class ServiceLoaderUtil { |
40 | ||
41 | private static final MethodType LOAD_CLASS_CLASSLOADER = MethodType.methodType(ServiceLoader.class, Class.class, | |
42 | ClassLoader.class); | |
43 | 44 | |
44 | 45 | private ServiceLoaderUtil() { |
45 | 46 | } |
101 | 102 | static <T> Iterable<T> callServiceLoader(Lookup lookup, Class<T> serviceType, ClassLoader classLoader, |
102 | 103 | boolean verbose) { |
103 | 104 | 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 | } | |
106 | 127 | return serviceLoader; |
107 | 128 | } catch (Throwable e) { |
108 | 129 | if (verbose) { |
110 | 131 | } |
111 | 132 | } |
112 | 133 | return Collections.emptyList(); |
113 | ||
114 | 134 | } |
115 | 135 | |
116 | 136 | private static class ServiceLoaderSpliterator<S> implements Spliterator<S> { |
61 | 61 | * {@code null}, empty, or all characters are {@link Character#isWhitespace(char)}. |
62 | 62 | * |
63 | 63 | * @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)} | |
65 | 65 | */ |
66 | 66 | public static boolean isBlank(final String s) { |
67 | 67 | if (s == null || s.isEmpty()) { |
+1
-0
34 | 34 | {"LOG4J_FOO_BAR_PROPERTY", Arrays.asList("foo", "bar", "property")}, |
35 | 35 | {"LOG4J_EXACT", Collections.singletonList("EXACT")}, |
36 | 36 | {"LOG4J_TEST_PROPERTY_NAME", PropertySource.Util.tokenize("Log4jTestPropertyName")}, |
37 | {null, Collections.emptyList()} | |
37 | 38 | }; |
38 | 39 | } |
39 | 40 |
+1
-1
41 | 41 | String value = resourceBundle.getString(key); |
42 | 42 | assertTrue( |
43 | 43 | 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)); | |
45 | 45 | } |
46 | 46 | } |
47 | 47 | } |
+1
-0
35 | 35 | {"log4j2.fooBarProperty", Arrays.asList("foo", "bar", "property")}, |
36 | 36 | {"log4j2.EXACT", Collections.singletonList("EXACT")}, |
37 | 37 | {"log4j2.testPropertyName", PropertySource.Util.tokenize("Log4jTestPropertyName")}, |
38 | {null, Collections.emptyList()} | |
38 | 39 | }; |
39 | 40 | } |
40 | 41 |
+14
-10
22 | 22 | import static org.junit.jupiter.api.Assertions.assertNull; |
23 | 23 | import static org.junit.jupiter.api.Assertions.assertTrue; |
24 | 24 | |
25 | import java.io.InputStream; | |
25 | 26 | import java.util.Properties; |
26 | 27 | |
27 | 28 | import org.junit.jupiter.api.BeforeEach; |
53 | 54 | |
54 | 55 | @Override |
55 | 56 | 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; | |
57 | 59 | } |
58 | 60 | |
59 | 61 | @Override |
81 | 83 | |
82 | 84 | @BeforeEach |
83 | 85 | 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() { | |
89 | 93 | final PropertiesUtil util = new PropertiesUtil(properties); |
90 | 94 | final String legacy = "props.legacy"; |
91 | 95 | final String normalized = "props.normalized"; |
104 | 108 | } |
105 | 109 | |
106 | 110 | @Test |
107 | public void fallsBackToTokenMatching() { | |
111 | public void testFallsBackToTokenMatching() { | |
108 | 112 | final PropertiesUtil util = new PropertiesUtil(properties); |
109 | 113 | for (int i = 1; i <= 4; i++) { |
110 | 114 | final String key = "log4j2.tokenBasedProperty" + i; |
117 | 121 | } |
118 | 122 | |
119 | 123 | @Test |
120 | public void orderOfNormalizedProperties(EnvironmentVariables env, SystemProperties sysProps) { | |
124 | public void testOrderOfNormalizedProperties(EnvironmentVariables env, SystemProperties sysProps) { | |
121 | 125 | properties.remove("log4j2.normalizedProperty"); |
122 | 126 | properties.remove("LOG4J_normalized.property"); |
123 | 127 | final PropertiesUtil util = new PropertiesUtil(properties); |
150 | 154 | } |
151 | 155 | |
152 | 156 | @Test |
153 | public void highPriorityNonEnumerableSource(SystemProperties sysProps) { | |
157 | public void testHighPriorityNonEnumerableSource(SystemProperties sysProps) { | |
154 | 158 | // In both datasources |
155 | 159 | assertNotNull(properties.getProperty("log4j2.normalizedProperty")); |
156 | 160 | assertNotNull(properties.getProperty("log4j.onlyLegacy")); |
187 | 191 | * @param sysProps |
188 | 192 | */ |
189 | 193 | @Test |
190 | public void nullChecks(SystemProperties sysProps) { | |
194 | public void testNullChecks(SystemProperties sysProps) { | |
191 | 195 | sysProps.set("log4j2.someProperty", "sysProps"); |
192 | 196 | sysProps.set("Log4jLegacyProperty", "sysProps"); |
193 | 197 | final PropertiesUtil util = new PropertiesUtil(new NullPropertySource()); |
21 | 21 | import org.junit.jupiter.api.parallel.ResourceAccessMode; |
22 | 22 | import org.junit.jupiter.api.parallel.ResourceLock; |
23 | 23 | import org.junit.jupiter.api.parallel.Resources; |
24 | import org.junitpioneer.jupiter.ReadsSystemProperty; | |
25 | import org.junitpioneer.jupiter.SetSystemProperty; | |
24 | 26 | |
25 | 27 | import java.nio.charset.Charset; |
26 | 28 | import java.nio.charset.StandardCharsets; |
147 | 149 | assertEquals(pair[0], util.getStringProperty(pair[1])); |
148 | 150 | } |
149 | 151 | } |
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 | } | |
150 | 168 | } |
+3
-2
52 | 52 | private static class TestSecurityManager extends SecurityManager { |
53 | 53 | @Override |
54 | 54 | 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); | |
57 | 58 | } |
58 | 59 | } |
59 | 60 | } |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-api-java9</artifactId> |
25 | 25 | <packaging>pom</packaging> |
34 | 34 | <dependency> |
35 | 35 | <groupId>org.junit.jupiter</groupId> |
36 | 36 | <artifactId>junit-jupiter-engine</artifactId> |
37 | <scope>test</scope> | |
37 | 38 | </dependency> |
38 | 39 | <dependency> |
39 | 40 | <groupId>org.assertj</groupId> |
40 | 41 | <artifactId>assertj-core</artifactId> |
42 | <scope>test</scope> | |
41 | 43 | </dependency> |
42 | 44 | </dependencies> |
43 | 45 | <build> |
16 | 16 | |
17 | 17 | package org.apache.logging.log4j.util; |
18 | 18 | |
19 | import java.lang.invoke.CallSite; | |
20 | import java.lang.invoke.LambdaMetafactory; | |
19 | 21 | import java.lang.invoke.MethodHandle; |
20 | 22 | import java.lang.invoke.MethodHandles.Lookup; |
21 | 23 | import java.lang.invoke.MethodType; |
22 | import java.util.Arrays; | |
24 | import java.security.AccessController; | |
25 | import java.security.PrivilegedAction; | |
23 | 26 | import java.util.HashSet; |
24 | 27 | import java.util.Objects; |
25 | 28 | import java.util.ServiceConfigurationError; |
30 | 33 | import org.apache.logging.log4j.status.StatusLogger; |
31 | 34 | |
32 | 35 | public final class ServiceLoaderUtil { |
33 | ||
34 | private static final MethodType LOAD_CLASS_CLASSLOADER = MethodType.methodType(ServiceLoader.class, Class.class, | |
35 | ClassLoader.class); | |
36 | 36 | |
37 | 37 | private ServiceLoaderUtil() { |
38 | 38 | } |
86 | 86 | static <T> Stream<T> loadClassloaderServices(final Class<T> serviceType, final Lookup lookup, |
87 | 87 | final ClassLoader classLoader, final boolean verbose) { |
88 | 88 | 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 | } | |
91 | 111 | return serviceLoader.stream().map(provider -> { |
92 | 112 | try { |
93 | 113 | return provider.get(); |
21 | 21 | <parent> |
22 | 22 | <artifactId>log4j</artifactId> |
23 | 23 | <groupId>org.apache.logging.log4j</groupId> |
24 | <version>2.18.0</version> | |
24 | <version>2.19.0</version> | |
25 | 25 | </parent> |
26 | 26 | |
27 | 27 | <artifactId>log4j-appserver</artifactId> |
33 | 33 | <log4jParentDir>${basedir}/..</log4jParentDir> |
34 | 34 | <docLabel>Web Documentation</docLabel> |
35 | 35 | <projectDir>/log4j-appserver</projectDir> |
36 | <tomcat-juli.version>10.0.21</tomcat-juli.version> | |
36 | <tomcat-juli.version>10.0.23</tomcat-juli.version> | |
37 | 37 | <module.name>org.apache.logging.log4j.appserver</module.name> |
38 | 38 | <maven.doap.skip>true</maven.doap.skip> |
39 | 39 | </properties> |
25 | 25 | <description>Apache Log4j Bill of Materials</description> |
26 | 26 | <groupId>org.apache.logging.log4j</groupId> |
27 | 27 | <artifactId>log4j-bom</artifactId> |
28 | <version>2.18.0</version> | |
28 | <version>2.19.0</version> | |
29 | 29 | <packaging>pom</packaging> |
30 | 30 | |
31 | 31 | <!-- `log4j-bom` doesn't inherit from the room POM, but `org.apache.logging:logging-parent`. |
52 | 52 | <artifactId>log4j-core</artifactId> |
53 | 53 | <version>${project.version}</version> |
54 | 54 | </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> | |
55 | 61 | <!-- JSON template layout --> |
56 | 62 | <dependency> |
57 | 63 | <groupId>org.apache.logging.log4j</groupId> |
94 | 100 | <artifactId>log4j-slf4j-impl</artifactId> |
95 | 101 | <version>${project.version}</version> |
96 | 102 | </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> | |
101 | 107 | <version>${project.version}</version> |
102 | 108 | </dependency> |
103 | 109 | <!-- SLF4J Adapter --> |
106 | 112 | <artifactId>log4j-to-slf4j</artifactId> |
107 | 113 | <version>${project.version}</version> |
108 | 114 | </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> | |
109 | 121 | <!-- Application Service Support --> |
110 | 122 | <dependency> |
111 | 123 | <groupId>org.apache.logging.log4j</groupId> |
116 | 128 | <dependency> |
117 | 129 | <groupId>org.apache.logging.log4j</groupId> |
118 | 130 | <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> | |
119 | 136 | <version>${project.version}</version> |
120 | 137 | </dependency> |
121 | 138 | <!-- CouchDB Appender Plugin --> |
227 | 244 | </build> |
228 | 245 | |
229 | 246 | <scm> |
230 | <tag>log4j-2.18.0-rc1</tag> | |
247 | <tag>log4j-2.19.0-rc2</tag> | |
231 | 248 | </scm> |
232 | 249 | </project> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <modelVersion>4.0.0</modelVersion> |
25 | 25 | |
50 | 50 | <dependency> |
51 | 51 | <groupId>org.junit.vintage</groupId> |
52 | 52 | <artifactId>junit-vintage-engine</artifactId> |
53 | <scope>test</scope> | |
53 | 54 | </dependency> |
54 | 55 | <dependency> |
55 | 56 | <groupId>org.junit.jupiter</groupId> |
56 | 57 | <artifactId>junit-jupiter-engine</artifactId> |
58 | <scope>test</scope> | |
57 | 59 | </dependency> |
58 | 60 | <dependency> |
59 | 61 | <groupId>org.mockito</groupId> |
379 | 379 | # to the number of cores. |
380 | 380 | #memtable_flush_writers: 8 |
381 | 381 | |
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 | |
383 | 383 | # empty, this will default to 5% of the heap size. If the memory usage of |
384 | 384 | # all index summaries exceeds this limit, SSTables with low read rates will |
385 | 385 | # shrink their index summaries in order to meet this limit. However, this |
548 | 548 | |
549 | 549 | # Uncomment to set socket buffer size for internode communication |
550 | 550 | # 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 | |
552 | 552 | # See: |
553 | 553 | # /proc/sys/net/core/wmem_max |
554 | 554 | # /proc/sys/net/core/rmem_max |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-core</artifactId> |
25 | 25 | <packaging>jar</packaging> |
171 | 171 | <dependency> |
172 | 172 | <groupId>org.jmdns</groupId> |
173 | 173 | <artifactId>jmdns</artifactId> |
174 | <version>3.5.7</version> | |
174 | <version>3.5.8</version> | |
175 | 175 | <scope>test</scope> |
176 | 176 | </dependency> |
177 | 177 | <!-- SLF4J tests --> |
184 | 184 | <dependency> |
185 | 185 | <groupId>org.junit.vintage</groupId> |
186 | 186 | <artifactId>junit-vintage-engine</artifactId> |
187 | <scope>test</scope> | |
187 | 188 | </dependency> |
188 | 189 | <dependency> |
189 | 190 | <groupId>org.junit.jupiter</groupId> |
190 | 191 | <artifactId>junit-jupiter-engine</artifactId> |
192 | <scope>test</scope> | |
191 | 193 | </dependency> |
192 | 194 | <dependency> |
193 | 195 | <groupId>org.junit.jupiter</groupId> |
194 | 196 | <artifactId>junit-jupiter-params</artifactId> |
197 | <scope>test</scope> | |
195 | 198 | </dependency> |
196 | 199 | <dependency> |
197 | 200 | <groupId>org.junit.platform</groupId> |
199 | 202 | <scope>test</scope> |
200 | 203 | </dependency> |
201 | 204 | <dependency> |
205 | <groupId>org.assertj</groupId> | |
206 | <artifactId>assertj-core</artifactId> | |
207 | <scope>test</scope> | |
208 | </dependency> | |
209 | <dependency> | |
202 | 210 | <groupId>org.hamcrest</groupId> |
203 | 211 | <artifactId>hamcrest</artifactId> |
204 | 212 | <scope>test</scope> |
206 | 214 | <dependency> |
207 | 215 | <groupId>org.junit-pioneer</groupId> |
208 | 216 | <artifactId>junit-pioneer</artifactId> |
217 | <scope>test</scope> | |
209 | 218 | </dependency> |
210 | 219 | <!-- Mocking framework for use with JUnit --> |
211 | 220 | <dependency> |
212 | 221 | <groupId>org.mockito</groupId> |
213 | 222 | <artifactId>mockito-core</artifactId> |
223 | <scope>test</scope> | |
214 | 224 | </dependency> |
215 | 225 | <dependency> |
216 | 226 | <groupId>org.mockito</groupId> |
217 | 227 | <artifactId>mockito-junit-jupiter</artifactId> |
228 | <scope>test</scope> | |
218 | 229 | </dependency> |
219 | 230 | <!-- Embedded JDBC drivers for database appender tests --> |
220 | 231 | <dependency> |
19 | 19 | import org.apache.logging.log4j.Level; |
20 | 20 | import org.apache.logging.log4j.Marker; |
21 | 21 | import org.apache.logging.log4j.message.Message; |
22 | import org.apache.logging.log4j.util.Constants; | |
22 | 23 | import org.apache.logging.log4j.util.EnglishEnums; |
23 | 24 | |
24 | 25 | /** |
300 | 301 | |
301 | 302 | /** |
302 | 303 | * 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. | |
303 | 316 | * @param event The Event to filter on. |
304 | 317 | * @return the Result. |
305 | 318 | */ |
18 | 18 | import java.io.ObjectStreamException; |
19 | 19 | import java.io.Serializable; |
20 | 20 | import java.util.ArrayList; |
21 | import java.util.Collections; | |
21 | 22 | import java.util.Iterator; |
22 | 23 | import java.util.List; |
23 | 24 | import java.util.Map; |
298 | 299 | public Iterator<Filter> getFilters() { |
299 | 300 | final Filter filter = privateConfig.loggerConfig.getFilter(); |
300 | 301 | if (filter == null) { |
301 | return new ArrayList<Filter>().iterator(); | |
302 | return Collections.emptyIterator(); | |
302 | 303 | } else if (filter instanceof CompositeFilter) { |
303 | 304 | return ((CompositeFilter) filter).iterator(); |
304 | 305 | } else { |
64 | 64 | for (final Node childNode : children) { |
65 | 65 | final String key = childNode.getAttributes().get("name"); |
66 | 66 | 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 {}", | |
68 | 68 | childNode, children); |
69 | 69 | } else { |
70 | 70 | map.put(key, childNode); |
56 | 56 | private String id; |
57 | 57 | |
58 | 58 | @PluginBuilderAttribute(value = "enterpriseNumber") |
59 | private String enterpriseNumber = Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER; | |
59 | private String enterpriseNumber = String.valueOf(Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER); | |
60 | 60 | |
61 | 61 | @PluginBuilderAttribute(value = "includeMdc") |
62 | 62 | private boolean includeMdc = true; |
+5
-5
138 | 138 | protected synchronized void writeToDestination(final byte[] bytes, final int offset, final int length) { |
139 | 139 | try { |
140 | 140 | if (randomAccessFile == null) { |
141 | final String fileName = getFileName(); | |
142 | final File file = new File(fileName); | |
143 | FileUtils.makeParentDirs(file); | |
144 | createFileAfterRollover(fileName); | |
141 | createFileAfterRollover(); | |
145 | 142 | } |
146 | 143 | randomAccessFile.write(bytes, offset, length); |
147 | 144 | size += length; |
153 | 150 | |
154 | 151 | @Override |
155 | 152 | 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); | |
157 | 157 | } |
158 | 158 | |
159 | 159 | private void createFileAfterRollover(final String fileName) throws IOException { |
+1
-1
421 | 421 | * LOG4J2-2629: PurgePolicy implementations can invoke {@link #deleteAppender(String)} after we have looked up |
422 | 422 | * an instance of a target appender but before events are appended, which could result in events not being |
423 | 423 | * 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 | |
425 | 425 | * {@link Appender#stop()} until events have successfully been recorded. |
426 | 426 | * Alternative approaches considered: |
427 | 427 | * - More aggressive synchronization: Appenders may do expensive I/O that shouldn't block routing. |
+1
-1
28 | 28 | /** |
29 | 29 | * Returns either this Thread's context or the default {@link AsyncLoggerContext}. |
30 | 30 | * 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. | |
32 | 32 | */ |
33 | 33 | public class BasicAsyncLoggerContextSelector implements ContextSelector { |
34 | 34 |
+6
-1
131 | 131 | private ConcurrentMap<String, LoggerConfig> loggerConfigs = new ConcurrentHashMap<>(); |
132 | 132 | private List<CustomLevelConfig> customLevels = Collections.emptyList(); |
133 | 133 | private final ConcurrentMap<String, String> propertyMap = new ConcurrentHashMap<>(); |
134 | private final StrLookup tempLookup = new Interpolator(propertyMap); | |
134 | private final Interpolator tempLookup = new Interpolator(propertyMap); | |
135 | 135 | private final StrSubstitutor runtimeStrSubstitutor = new RuntimeStrSubstitutor(tempLookup); |
136 | 136 | private final StrSubstitutor configurationStrSubstitutor = new ConfigurationStrSubstitutor(runtimeStrSubstitutor); |
137 | 137 | private LoggerConfig root = new LoggerConfig(); |
149 | 149 | */ |
150 | 150 | protected AbstractConfiguration(final LoggerContext loggerContext, final ConfigurationSource configurationSource) { |
151 | 151 | this.loggerContext = new WeakReference<>(loggerContext); |
152 | tempLookup.setLoggerContext(loggerContext); | |
152 | 153 | // The loggerContext is null for the NullConfiguration class. |
153 | 154 | // this.loggerContext = new WeakReference(Objects.requireNonNull(loggerContext, "loggerContext is null")); |
154 | 155 | this.configurationSource = Objects.requireNonNull(configurationSource, "configurationSource is null"); |
635 | 636 | createConfiguration(first, null); |
636 | 637 | if (first.getObject() != null) { |
637 | 638 | StrLookup lookup = (StrLookup) first.getObject(); |
639 | if (lookup instanceof LoggerContextAware) { | |
640 | ((LoggerContextAware) lookup).setLoggerContext(loggerContext.get()); | |
641 | } | |
638 | 642 | runtimeStrSubstitutor.setVariableResolver(lookup); |
639 | 643 | configurationStrSubstitutor.setVariableResolver(lookup); |
640 | 644 | } |
642 | 646 | final Map<String, String> map = this.getComponent(CONTEXT_PROPERTIES); |
643 | 647 | final StrLookup lookup = map == null ? null : new PropertiesLookup(map); |
644 | 648 | Interpolator interpolator = new Interpolator(lookup, pluginPackages); |
649 | interpolator.setLoggerContext(loggerContext.get()); | |
645 | 650 | runtimeStrSubstitutor.setVariableResolver(interpolator); |
646 | 651 | configurationStrSubstitutor.setVariableResolver(interpolator); |
647 | 652 | } |
409 | 409 | } |
410 | 410 | |
411 | 411 | /** |
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 | /** | |
412 | 420 | * Returns the LogEventFactory. |
413 | 421 | * |
414 | 422 | * @return the LogEventFactory. |
941 | 949 | } else { |
942 | 950 | LOGGER.warn("levelAndRefs are only allowed in a properties configuration. The value is ignored."); |
943 | 951 | result.level = level; |
944 | result.refs = Arrays.asList(refs); | |
952 | result.refs = refs != null ? Arrays.asList(refs) : new ArrayList<>(); | |
945 | 953 | } |
946 | 954 | } else { |
947 | 955 | result.level = level; |
948 | result.refs = Arrays.asList(refs); | |
956 | result.refs = refs != null ? Arrays.asList(refs) : new ArrayList<>(); | |
949 | 957 | } |
950 | 958 | return result; |
951 | 959 | } |
+35
-0
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 | } |
+2
-2
73 | 73 | |
74 | 74 | /** |
75 | 75 | * Sets the Property Value. |
76 | * @param propertyValue the property name. | |
76 | * @param propertyValue the property value. | |
77 | 77 | * @return this |
78 | 78 | */ |
79 | 79 | public Builder setPropertyValue(final String propertyValue) { |
80 | this.propertyName = propertyValue; | |
80 | this.propertyValue = propertyValue; | |
81 | 81 | return asBuilder(); |
82 | 82 | } |
83 | 83 |
+37
-0
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 | } |
+47
-0
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 | } |
72 | 72 | /** |
73 | 73 | * The default example enterprise number from RFC5424. |
74 | 74 | */ |
75 | public static final String DEFAULT_ENTERPRISE_NUMBER = "32473"; | |
75 | public static final int DEFAULT_ENTERPRISE_NUMBER = 32473; | |
76 | 76 | /** |
77 | 77 | * The default event id. |
78 | 78 | */ |
615 | 615 | // @formatter:off |
616 | 616 | @PluginAttribute(value = "facility", defaultString = "LOCAL0") final Facility facility, |
617 | 617 | @PluginAttribute("id") final String id, |
618 | @PluginAttribute(value = "enterpriseNumber", defaultInt = -1) | |
618 | @PluginAttribute(value = "enterpriseNumber", defaultInt = DEFAULT_ENTERPRISE_NUMBER) | |
619 | 619 | final int enterpriseNumber, |
620 | 620 | @PluginAttribute(value = "includeMDC", defaultBoolean = true) final boolean includeMDC, |
621 | 621 | @PluginAttribute(value = "mdcId", defaultString = DEFAULT_MDCID) final String mdcId, |
646 | 646 | |
647 | 647 | public static class Rfc5424LayoutBuilder { |
648 | 648 | private Configuration config; |
649 | private Facility facility; | |
649 | private Facility facility = Facility.LOCAL0; | |
650 | 650 | 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; | |
653 | 653 | private boolean includeNL; |
654 | 654 | private String escapeNL; |
655 | private String mdcId; | |
655 | private String mdcId = DEFAULT_MDCID; | |
656 | 656 | private String mdcPrefix; |
657 | 657 | private String eventPrefix; |
658 | 658 | private String appName; |
842 | 842 | public Facility getFacility() { |
843 | 843 | return facility; |
844 | 844 | } |
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 | ||
845 | 862 | } |
47 | 47 | } |
48 | 48 | |
49 | 49 | /** |
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. | |
51 | 51 | * @param event The LogEvent for which the date is returned. If null, current date is returned. |
52 | 52 | * @param key the format to use. If null, the default DateFormat will be used. |
53 | 53 | * @return The formatted date, never null. |
15 | 15 | */ |
16 | 16 | package org.apache.logging.log4j.core.lookup; |
17 | 17 | |
18 | import java.lang.ref.WeakReference; | |
18 | 19 | import java.util.Collections; |
19 | 20 | import java.util.HashMap; |
20 | 21 | import java.util.List; |
23 | 24 | |
24 | 25 | import org.apache.logging.log4j.Logger; |
25 | 26 | import org.apache.logging.log4j.core.LogEvent; |
27 | import org.apache.logging.log4j.core.LoggerContext; | |
26 | 28 | import org.apache.logging.log4j.core.config.ConfigurationAware; |
29 | import org.apache.logging.log4j.core.config.LoggerContextAware; | |
27 | 30 | import org.apache.logging.log4j.core.config.plugins.util.PluginManager; |
28 | 31 | import org.apache.logging.log4j.core.config.plugins.util.PluginType; |
29 | 32 | import org.apache.logging.log4j.core.net.JndiManager; |
33 | 36 | /** |
34 | 37 | * Proxies all the other {@link StrLookup}s. |
35 | 38 | */ |
36 | public class Interpolator extends AbstractConfigurationAwareLookup { | |
39 | public class Interpolator extends AbstractConfigurationAwareLookup implements LoggerContextAware { | |
37 | 40 | |
38 | 41 | /** Constant for the prefix separator. */ |
39 | 42 | public static final char PREFIX_SEPARATOR = ':'; |
55 | 58 | private final Map<String, StrLookup> strLookupMap = new HashMap<>(); |
56 | 59 | |
57 | 60 | private final StrLookup defaultLookup; |
61 | ||
62 | protected WeakReference<LoggerContext> loggerContext; | |
58 | 63 | |
59 | 64 | public Interpolator(final StrLookup defaultLookup) { |
60 | 65 | this(defaultLookup, null); |
184 | 189 | if (lookup instanceof ConfigurationAware) { |
185 | 190 | ((ConfigurationAware) lookup).setConfiguration(configuration); |
186 | 191 | } |
192 | if (lookup instanceof LoggerContextAware) { | |
193 | ((LoggerContextAware) lookup).setLoggerContext(loggerContext.get()); | |
194 | } | |
187 | 195 | LookupResult value = null; |
188 | 196 | if (lookup != null) { |
189 | 197 | value = event == null ? lookup.evaluate(name) : lookup.evaluate(event, name); |
198 | 206 | return event == null ? defaultLookup.evaluate(var) : defaultLookup.evaluate(event, var); |
199 | 207 | } |
200 | 208 | 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); | |
201 | 217 | } |
202 | 218 | |
203 | 219 | @Override |
+13
-11
32 | 32 | * Configuration of the KeyStore |
33 | 33 | */ |
34 | 34 | public class AbstractKeyStoreConfiguration extends StoreConfiguration<KeyStore> { |
35 | static final char[] DEFAULT_PASSWORD = "changeit".toCharArray(); | |
36 | 35 | |
37 | 36 | private final KeyStore keyStore; |
38 | 37 | private final String keyStoreType; |
65 | 64 | @Override |
66 | 65 | protected KeyStore load() throws StoreConfigurationException { |
67 | 66 | final String loadLocation = this.getLocation(); |
67 | final char[] password = this.getPasswordAsCharArray(); | |
68 | 68 | LOGGER.debug("Loading keystore from location {}", loadLocation); |
69 | 69 | try { |
70 | final KeyStore ks = KeyStore.getInstance(this.keyStoreType); | |
70 | 71 | 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; | |
72 | 78 | } |
73 | 79 | 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); | |
83 | 81 | LOGGER.debug("KeyStore successfully loaded from location {}", loadLocation); |
84 | 82 | return ks; |
85 | 83 | } |
98 | 96 | } catch (final IOException e) { |
99 | 97 | LOGGER.error("Something is wrong with the format of the keystore or the given password for location {}", loadLocation, e); |
100 | 98 | throw new StoreConfigurationException(loadLocation, e); |
99 | } finally { | |
100 | if (password != null) { | |
101 | Arrays.fill(password, '\0'); | |
102 | } | |
101 | 103 | } |
102 | 104 | } |
103 | 105 |
+1
-1
168 | 168 | final KeyManagerFactory kmFactory = KeyManagerFactory.getInstance(this.keyManagerFactoryAlgorithm); |
169 | 169 | final char[] password = this.getPasswordAsCharArray(); |
170 | 170 | try { |
171 | kmFactory.init(this.getKeyStore(), password != null ? password : DEFAULT_PASSWORD); | |
171 | kmFactory.init(this.getKeyStore(), password); | |
172 | 172 | } finally { |
173 | 173 | if (password != null) { |
174 | 174 | Arrays.fill(password, '\0'); |
+27
-14
18 | 18 | import org.apache.logging.log4j.Logger; |
19 | 19 | import org.apache.logging.log4j.status.StatusLogger; |
20 | 20 | import org.apache.logging.log4j.util.PropertiesUtil; |
21 | import org.apache.logging.log4j.util.Strings; | |
21 | 22 | |
22 | 23 | /** |
23 | 24 | * Creates an SSL configuration from Log4j properties. |
45 | 46 | KeyStoreConfiguration keyStoreConfiguration = null; |
46 | 47 | TrustStoreConfiguration trustStoreConfiguration = null; |
47 | 48 | String location = props.getStringProperty(trustStorelocation); |
48 | if (location != null) { | |
49 | String storeType = props.getStringProperty(trustStoreKeyStoreType); | |
50 | if (Strings.isNotEmpty(location) || storeType != null) { | |
49 | 51 | String password = props.getStringProperty(trustStorePassword); |
50 | char[] passwordChars = null; | |
51 | if (password != null) { | |
52 | passwordChars = password.toCharArray(); | |
53 | } | |
52 | char[] passwordChars = getPassword(password, storeType); | |
54 | 53 | try { |
55 | trustStoreConfiguration = TrustStoreConfiguration.createKeyStoreConfiguration(location, passwordChars, | |
54 | trustStoreConfiguration = TrustStoreConfiguration.createKeyStoreConfiguration(Strings.trimToNull(location), passwordChars, | |
56 | 55 | props.getStringProperty(trustStorePasswordEnvVar), props.getStringProperty(trustStorePasswordFile), |
57 | props.getStringProperty(trustStoreKeyStoreType), props.getStringProperty(trustStoreKeyManagerFactoryAlgorithm)); | |
56 | storeType, props.getStringProperty(trustStoreKeyManagerFactoryAlgorithm)); | |
58 | 57 | } catch (Exception ex) { |
59 | 58 | LOGGER.warn("Unable to create trust store configuration due to: {} {}", ex.getClass().getName(), |
60 | 59 | ex.getMessage()); |
61 | 60 | } |
62 | 61 | } |
63 | 62 | location = props.getStringProperty(keyStoreLocation); |
64 | if (location != null) { | |
63 | storeType = props.getStringProperty(keyStoreType); | |
64 | if (Strings.isNotEmpty(location) || storeType != null) { | |
65 | 65 | String password = props.getStringProperty(keyStorePassword); |
66 | char[] passwordChars = null; | |
67 | if (password != null) { | |
68 | passwordChars = password.toCharArray(); | |
69 | } | |
66 | char[] passwordChars = getPassword(password, storeType); | |
70 | 67 | try { |
71 | keyStoreConfiguration = KeyStoreConfiguration.createKeyStoreConfiguration(location, passwordChars, | |
68 | keyStoreConfiguration = KeyStoreConfiguration.createKeyStoreConfiguration(Strings.trimToNull(location), passwordChars, | |
72 | 69 | props.getStringProperty(keyStorePasswordEnvVar), props.getStringProperty(keyStorePasswordFile), |
73 | props.getStringProperty(keyStoreType), props.getStringProperty(keyStoreKeyManagerFactoryAlgorithm)); | |
70 | storeType, props.getStringProperty(keyStoreKeyManagerFactoryAlgorithm)); | |
74 | 71 | } catch (Exception ex) { |
75 | 72 | LOGGER.warn("Unable to create key store configuration due to: {} {}", ex.getClass().getName(), |
76 | 73 | ex.getMessage()); |
84 | 81 | return null; |
85 | 82 | } |
86 | 83 | |
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 | ||
87 | 100 | public static SslConfiguration getSslConfiguration() { |
88 | 101 | return sslConfiguration; |
89 | 102 | } |
+3
-0
24 | 24 | * |
25 | 25 | */ |
26 | 26 | public class StoreConfiguration<T> { |
27 | ||
28 | static final String PKCS12 = "PKCS12"; | |
29 | static final String JKS = "JKS"; | |
27 | 30 | protected static final StatusLogger LOGGER = StatusLogger.getLogger(); |
28 | 31 | |
29 | 32 | private String location; |
17 | 17 | package org.apache.logging.log4j.core.osgi; |
18 | 18 | |
19 | 19 | import java.util.Collection; |
20 | import java.util.Hashtable; | |
21 | 20 | import java.util.concurrent.atomic.AtomicReference; |
22 | 21 | |
23 | 22 | import org.apache.logging.log4j.LogManager; |
28 | 27 | import org.apache.logging.log4j.core.impl.ThreadContextDataProvider; |
29 | 28 | import org.apache.logging.log4j.core.util.Constants; |
30 | 29 | import org.apache.logging.log4j.core.util.ContextDataProvider; |
31 | import org.apache.logging.log4j.spi.Provider; | |
32 | 30 | import org.apache.logging.log4j.status.StatusLogger; |
33 | 31 | import org.apache.logging.log4j.util.PropertiesUtil; |
32 | import org.apache.logging.log4j.util.ProviderActivator; | |
34 | 33 | import org.osgi.framework.Bundle; |
35 | import org.osgi.framework.BundleActivator; | |
36 | 34 | import org.osgi.framework.BundleContext; |
37 | 35 | import org.osgi.framework.BundleEvent; |
38 | 36 | import org.osgi.framework.InvalidSyntaxException; |
44 | 42 | /** |
45 | 43 | * OSGi BundleActivator. |
46 | 44 | */ |
47 | public final class Activator implements BundleActivator, SynchronousBundleListener { | |
45 | public final class Activator extends ProviderActivator implements SynchronousBundleListener { | |
48 | 46 | |
49 | 47 | private static final Logger LOGGER = StatusLogger.getLogger(); |
50 | 48 | |
51 | 49 | private final AtomicReference<BundleContext> contextRef = new AtomicReference<>(); |
52 | 50 | |
53 | ServiceRegistration provideRegistration = null; | |
54 | ServiceRegistration contextDataRegistration = null; | |
51 | private ServiceRegistration<ContextDataProvider> contextDataRegistration = null; | |
52 | ||
53 | public Activator() { | |
54 | super(new Log4jProvider()); | |
55 | } | |
55 | 56 | |
56 | 57 | @Override |
57 | 58 | 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); | |
61 | 60 | 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); | |
65 | 62 | loadContextProviders(context); |
66 | 63 | // allow the user to override the default ContextSelector (e.g., by using BasicContextSelector for a global cfg) |
67 | 64 | if (PropertiesUtil.getProperties().getStringProperty(Constants.LOG4J_CONTEXT_SELECTOR) == null) { |
113 | 110 | |
114 | 111 | @Override |
115 | 112 | public void stop(final BundleContext context) throws Exception { |
116 | provideRegistration.unregister(); | |
117 | 113 | contextDataRegistration.unregister(); |
118 | 114 | this.contextRef.compareAndSet(context, null); |
119 | 115 | LogManager.shutdown(); |
116 | super.stop(context); | |
120 | 117 | } |
121 | 118 | |
122 | 119 | @Override |
92 | 92 | } |
93 | 93 | final PatternParser parser = PatternLayout.createPatternParser(config); |
94 | 94 | 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)); | |
96 | 96 | final boolean disableAnsi = Arrays.toString(options).contains(PatternParser.DISABLE_ANSI + "=true"); |
97 | 97 | final boolean noConsoleNoAnsi = Arrays.toString(options).contains(PatternParser.NO_CONSOLE_NO_ANSI + "=true"); |
98 | 98 | final boolean hideAnsi = disableAnsi || (noConsoleNoAnsi && System.console() == null); |
79 | 79 | * class ({@code Loader}). Under JDK 1.1, only the class |
80 | 80 | * loader that loaded this class ({@code Loader}) is used.</li> |
81 | 81 | * <li>Try one last time with |
82 | * {@code ClassLoader.getSystemResource(resource)}, that is is | |
82 | * {@code ClassLoader.getSystemResource(resource)}, that is | |
83 | 83 | * using the system class loader in JDK 1.2 and virtual machine's |
84 | 84 | * built-in class loader in JDK 1.1.</li> |
85 | 85 | * </ol> |
141 | 141 | * class ({@code Loader}). Under JDK 1.1, only the class |
142 | 142 | * loader that loaded this class ({@code Loader}) is used.</li> |
143 | 143 | * <li>Try one last time with |
144 | * {@code ClassLoader.getSystemResource(resource)}, that is is | |
144 | * {@code ClassLoader.getSystemResource(resource)}, that is | |
145 | 145 | * using the system class loader in JDK 1.2 and virtual machine's |
146 | 146 | * built-in class loader in JDK 1.1.</li> |
147 | 147 | * </ol> |
28 | 28 | public static final String COMMA_SEPARATOR = toWhitespaceSeparator(","); |
29 | 29 | |
30 | 30 | /** |
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 | /** | |
31 | 36 | * The whitespace pattern string. |
32 | 37 | */ |
33 | 38 | public static final String WHITESPACE = "\\s*"; |
144 | 144 | * Constructs a new {@code Source} from the specified URL. |
145 | 145 | * |
146 | 146 | * @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 | |
148 | 148 | * converted to a URI. |
149 | 149 | */ |
150 | 150 | public Source(final URL url) { |
17 | 17 | |
18 | 18 | import com.google.monitoring.runtime.instrumentation.AllocationRecorder; |
19 | 19 | import com.google.monitoring.runtime.instrumentation.Sampler; |
20 | import org.apache.logging.log4j.Level; | |
20 | 21 | import org.apache.logging.log4j.LogManager; |
21 | 22 | import org.apache.logging.log4j.Marker; |
22 | 23 | import org.apache.logging.log4j.MarkerManager; |
56 | 57 | final Marker testGrandParent = MarkerManager.getMarker("testGrandParent"); |
57 | 58 | final Marker testParent = MarkerManager.getMarker("testParent").setParents(testGrandParent); |
58 | 59 | final Marker test = MarkerManager.getMarker("test").setParents(testParent); // initial creation, value is cached |
60 | final StringMapMessage mapMessage = new StringMapMessage().with("eventId", "Login"); | |
59 | 61 | |
60 | 62 | // initialize LoggerContext etc. |
61 | 63 | // This is not steady-state logging and will allocate objects. |
68 | 70 | logger.error("Sample error message"); |
69 | 71 | logger.error("Test parameterized message {}", "param"); |
70 | 72 | logger.error(new StringMapMessage().with("eventId", "Login")); // initialize GelfLayout's messageStringBuilder |
73 | singleLoggingIteration(logger, myCharSeq, mapMessage); | |
71 | 74 | for (int i = 0; i < 256; i++) { |
72 | 75 | logger.debug("ensure all ringbuffer slots have been used once"); // allocate MutableLogEvent.messageText |
73 | 76 | } |
99 | 102 | new RuntimeException().printStackTrace(); |
100 | 103 | }; |
101 | 104 | Thread.sleep(500); |
102 | final StringMapMessage mapMessage = new StringMapMessage().with("eventId", "Login"); | |
103 | 105 | AllocationRecorder.addSampler(sampler); |
104 | 106 | |
105 | 107 | // now do some steady-state logging |
109 | 111 | |
110 | 112 | final int ITERATIONS = 5; |
111 | 113 | 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); | |
119 | 115 | ThreadContext.remove("aKey"); |
120 | 116 | ThreadContext.put("aKey", "value1"); |
121 | 117 | } |
123 | 119 | samplingEnabled.set(false); // reliably ignore all allocations from now on |
124 | 120 | AllocationRecorder.removeSampler(sampler); |
125 | 121 | 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 | |
126 | 205 | } |
127 | 206 | |
128 | 207 | public static void runTest(final Class<?> cls) throws Exception { |
+1
-1
34 | 34 | import static org.junit.jupiter.api.Assertions.assertTrue; |
35 | 35 | |
36 | 36 | /** |
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, | |
38 | 38 | * that the file is extended by region length when necessary, and that the file is shrunk to its actual usage when done. |
39 | 39 | * |
40 | 40 | * @since 2.1 |
+1
-1
45 | 45 | this.createAndAddAppender(); |
46 | 46 | |
47 | 47 | // 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). | |
49 | 49 | // see OutputStreamManager.writeToDestination(...). |
50 | 50 | Logger logger = (Logger)LogManager.getLogger(this.getClass()); |
51 | 51 | logger.info("test message 1"); |
+95
-0
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 | } |
+48
-0
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 | } |
+21
-0
86 | 86 | assertEquals(value, actualList.get(i).getValue(), "value[" + i + "]"); |
87 | 87 | } |
88 | 88 | } |
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 | } | |
89 | 110 | } |
15 | 15 | */ |
16 | 16 | package org.apache.logging.log4j.core.layout; |
17 | 17 | |
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 | ||
19 | 29 | import org.apache.commons.io.IOUtils; |
20 | 30 | import org.apache.logging.log4j.Level; |
21 | 31 | import org.apache.logging.log4j.ThreadContext; |
32 | 42 | import org.apache.logging.log4j.junit.UsingAnyThreadContext; |
33 | 43 | import org.apache.logging.log4j.test.appender.EncodingListAppender; |
34 | 44 | import org.apache.logging.log4j.test.appender.ListAppender; |
45 | import org.apache.logging.log4j.util.Chars; | |
35 | 46 | import org.junit.jupiter.api.AfterAll; |
36 | 47 | import org.junit.jupiter.api.BeforeAll; |
37 | 48 | import org.junit.jupiter.api.Test; |
38 | 49 | |
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; | |
48 | 51 | |
49 | 52 | @UsingAnyThreadContext |
50 | 53 | public class GelfLayoutTest { |
140 | 143 | final String threadName = Thread.currentThread().getName(); |
141 | 144 | |
142 | 145 | //@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 | } | |
143 | 151 | assertJsonEquals("{" + |
144 | 152 | "\"version\": \"1.1\"," + |
145 | 153 | "\"host\": \"" + host + "\"," + |
151 | 159 | "\"_" + KEY1 + "\": \"" + VALUE1 + "\"," + |
152 | 160 | "\"_" + KEY2 + "\": \"" + javaLookup.getRuntime() + "\"" + |
153 | 161 | "}", |
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 | } | |
156 | 169 | assertJsonEquals("{" + |
157 | 170 | "\"version\": \"1.1\"," + |
158 | 171 | "\"host\": \"" + host + "\"," + |
169 | 182 | "\"_" + KEY1 + "\": \"" + VALUE1 + "\"," + |
170 | 183 | "\"_" + KEY2 + "\": \"" + javaLookup.getRuntime() + "\"" + |
171 | 184 | "}", |
172 | messages.get(1)); | |
185 | message); | |
173 | 186 | //@formatter:on |
174 | 187 | final byte[] compressed = raw.get(2); |
175 | 188 | final byte[] compressed2 = raw2.get(2); |
197 | 210 | final byte[] uncompressed2 = IOUtils.toByteArray(inflaterStream2); |
198 | 211 | inflaterStream.close(); |
199 | 212 | 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()); | |
202 | 215 | //@formatter:off |
203 | 216 | final String expected = "{" + |
204 | 217 | "\"version\": \"1.1\"," + |
218 | 231 | "\"_" + KEY2 + "\": \"" + javaLookup.getRuntime() + "\"" + |
219 | 232 | "}"; |
220 | 233 | //@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 | } | |
221 | 244 | assertJsonEquals(expected, uncompressedString); |
222 | 245 | 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 | } | |
231 | 246 | } |
232 | 247 | |
233 | 248 | @Test |
+28
-0
36 | 36 | import org.apache.logging.log4j.core.Logger; |
37 | 37 | import org.apache.logging.log4j.core.LoggerContext; |
38 | 38 | 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; | |
39 | 44 | import org.apache.logging.log4j.core.net.Facility; |
40 | 45 | import org.apache.logging.log4j.core.util.Integers; |
41 | 46 | import org.apache.logging.log4j.core.util.KeyValuePair; |
568 | 573 | } |
569 | 574 | } |
570 | 575 | |
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 | ||
571 | 599 | @ParameterizedTest |
572 | 600 | @ValueSource(strings = { "123456789", "0", "2147483647", "123.45.6.78.9", "0.0.0.0.0.0.0.0.0.0.0.0.0.0" }) |
573 | 601 | void testLayoutBuilderValidEids(String eid) { |
+76
-10
15 | 15 | */ |
16 | 16 | package org.apache.logging.log4j.core.net.ssl; |
17 | 17 | |
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; | |
19 | 22 | |
20 | 23 | import java.security.KeyStore; |
24 | import java.util.Collections; | |
25 | import java.util.function.Supplier; | |
26 | import java.util.stream.Stream; | |
21 | 27 | |
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; | |
23 | 34 | |
35 | @SetSystemProperty(key = "sun.security.mscapi.keyStoreCompatibilityMode", value = "false") | |
24 | 36 | public class KeyStoreConfigurationTest { |
37 | ||
25 | 38 | @SuppressWarnings("deprecation") |
26 | 39 | @Test |
27 | 40 | public void loadEmptyConfigurationDeprecated() { |
42 | 55 | TestConstants.KEYSTORE_TYPE, null); |
43 | 56 | final KeyStore ks = ksc.getKeyStore(); |
44 | 57 | assertNotNull(ks); |
58 | checkKeystoreConfiguration(ksc); | |
45 | 59 | } |
46 | 60 | |
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); | |
51 | 83 | final KeyStore ks = ksc.getKeyStore(); |
52 | 84 | assertNotNull(ks); |
85 | checkKeystoreConfiguration(ksc); | |
53 | 86 | } |
54 | 87 | |
55 | 88 | @Test |
78 | 111 | () -> new KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, "wrongPassword!", null, null)); |
79 | 112 | } |
80 | 113 | |
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 | }); | |
85 | 151 | } |
86 | 152 | } |
+54
-4
19 | 19 | import static org.junit.jupiter.api.Assertions.assertNull; |
20 | 20 | |
21 | 21 | import java.util.Properties; |
22 | import java.util.stream.Stream; | |
22 | 23 | |
23 | 24 | import org.apache.logging.log4j.util.PropertiesUtil; |
24 | 25 | 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; | |
25 | 31 | |
26 | 32 | public class SslConfigurationFactoryTest { |
27 | 33 | |
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 | ||
28 | 41 | 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); | |
31 | 44 | } |
32 | 45 | |
33 | 46 | 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); | |
36 | 49 | } |
37 | 50 | |
38 | 51 | @Test |
68 | 81 | assertNotNull(sslConfiguration.getKeyStoreConfig()); |
69 | 82 | assertNotNull(sslConfiguration.getTrustStoreConfig()); |
70 | 83 | } |
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 | } | |
71 | 121 | } |
35 | 35 | public static final char[] KEYSTORE_PWD() { return "changeit".toCharArray(); } |
36 | 36 | public static final String KEYSTORE_TYPE = "JKS"; |
37 | 37 | |
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 | ||
38 | 52 | public static final char[] NULL_PWD = null; |
39 | 53 | } |
+22
-25
19 | 19 | import org.apache.logging.log4j.core.impl.Log4jLogEvent; |
20 | 20 | import org.apache.logging.log4j.message.SimpleMessage; |
21 | 21 | 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; | |
22 | 25 | |
23 | 26 | import static org.junit.jupiter.api.Assertions.*; |
27 | ||
28 | import java.util.stream.Stream; | |
24 | 29 | |
25 | 30 | /** |
26 | 31 | * Tests the HighlightConverter. |
75 | 80 | assertEquals(AnsiEscape.createSequence(colorName), converter.getLevelStyle(Level.DEBUG)); |
76 | 81 | } |
77 | 82 | |
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 }; | |
81 | 98 | final HighlightConverter converter = HighlightConverter.newInstance(null, options); |
82 | 99 | assertNotNull(converter); |
83 | 100 | |
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(); | |
86 | 102 | final StringBuilder buffer = new StringBuilder(); |
87 | 103 | 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()); | |
108 | 105 | } |
109 | 106 | |
110 | 107 | @Test |
+26
-0
17 | 17 | |
18 | 18 | import java.util.List; |
19 | 19 | |
20 | import org.apache.logging.log4j.Level; | |
20 | 21 | import org.apache.logging.log4j.Logger; |
22 | import org.apache.logging.log4j.core.LogEvent; | |
21 | 23 | import org.apache.logging.log4j.core.LoggerContext; |
24 | import org.apache.logging.log4j.core.impl.Log4jLogEvent; | |
22 | 25 | import org.apache.logging.log4j.junit.LoggerContextSource; |
23 | 26 | import org.apache.logging.log4j.junit.Named; |
24 | 27 | import org.apache.logging.log4j.test.appender.ListAppender; |
25 | 28 | import org.apache.logging.log4j.util.Strings; |
26 | 29 | import org.junit.jupiter.api.BeforeAll; |
27 | 30 | import org.junit.jupiter.api.Test; |
31 | import org.junit.jupiter.params.ParameterizedTest; | |
32 | import org.junit.jupiter.params.provider.MethodSource; | |
28 | 33 | |
29 | 34 | import static org.junit.jupiter.api.Assertions.*; |
30 | 35 | |
56 | 61 | public void testNull() { |
57 | 62 | assertNull(StyleConverter.newInstance(null, null)); |
58 | 63 | } |
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 | } | |
59 | 85 | } |
+2
-2
42 | 42 | |
43 | 43 | private static class Destination implements ByteBufferDestination { |
44 | 44 | // 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]); | |
46 | 46 | |
47 | 47 | @Override |
48 | 48 | public ByteBuffer getByteBuffer() { |
51 | 51 | |
52 | 52 | @Override |
53 | 53 | 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"); | |
55 | 55 | } |
56 | 56 | |
57 | 57 | @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>⏎ |
+28
-0
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 |
+9
-0
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 |
+9
-0
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
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----- |
log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/client.log4j2-keystore-nopass.p12
less
more
Binary diff not shown
log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/client.log4j2-keystore.jks
less
more
Binary diff not shown
log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/client.log4j2-keystore.p12
less
more
Binary diff not shown
+0
-32
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----- |
+15
-30
0 | 0 | -----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= | |
31 | 16 | -----END CERTIFICATE----- |
+0
-51
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----- |
+23
-0
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
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 | }; |
Binary diff not shown
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-core-its</artifactId> |
25 | 25 | <packaging>jar</packaging> |
124 | 124 | <dependency> |
125 | 125 | <groupId>org.junit.vintage</groupId> |
126 | 126 | <artifactId>junit-vintage-engine</artifactId> |
127 | <scope>test</scope> | |
127 | 128 | </dependency> |
128 | 129 | <dependency> |
129 | 130 | <groupId>org.junit.jupiter</groupId> |
130 | 131 | <artifactId>junit-jupiter-engine</artifactId> |
132 | <scope>test</scope> | |
131 | 133 | </dependency> |
132 | 134 | <dependency> |
133 | 135 | <groupId>org.hamcrest</groupId> |
+1
-1
119 | 119 | * Add an observation to the histogram and increment the counter for the interval it matches. |
120 | 120 | * |
121 | 121 | * @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. | |
123 | 123 | */ |
124 | 124 | public boolean addObservation(final long value) |
125 | 125 | { |
+1
-1
20 | 20 | * |
21 | 21 | * <h3>Note regarding potential for TTSP(Time To Safe Point) issues</h3> |
22 | 22 | * |
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 | |
24 | 24 | * (Time To SafePoint) problem. If this is the case for your application you can solve it by preventing the idle method from |
25 | 25 | * being inlined by using a Hotspot compiler command as a JVM argument e.g: |
26 | 26 | * <code>-XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle</code> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-core-java9</artifactId> |
25 | 25 | <packaging>pom</packaging> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <modelVersion>4.0.0</modelVersion> |
25 | 25 | |
49 | 49 | <dependency> |
50 | 50 | <groupId>org.junit.vintage</groupId> |
51 | 51 | <artifactId>junit-vintage-engine</artifactId> |
52 | <scope>test</scope> | |
52 | 53 | </dependency> |
53 | 54 | <dependency> |
54 | 55 | <groupId>org.junit.jupiter</groupId> |
55 | 56 | <artifactId>junit-jupiter-engine</artifactId> |
57 | <scope>test</scope> | |
56 | 58 | </dependency> |
57 | 59 | <dependency> |
58 | 60 | <groupId>org.mockito</groupId> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-distribution</artifactId> |
25 | 25 | <packaging>pom</packaging> |
170 | 170 | </dependency> |
171 | 171 | <dependency> |
172 | 172 | <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> | |
185 | 185 | <version>${project.version}</version> |
186 | 186 | <classifier>javadoc</classifier> |
187 | 187 | </dependency> |
204 | 204 | </dependency> |
205 | 205 | <dependency> |
206 | 206 | <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> | |
207 | 224 | <artifactId>log4j-jmx-gui</artifactId> |
208 | 225 | <version>${project.version}</version> |
209 | 226 | </dependency> |
255 | 272 | </dependency> |
256 | 273 | <dependency> |
257 | 274 | <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> | |
258 | 309 | <artifactId>log4j-couchdb</artifactId> |
259 | 310 | <version>${project.version}</version> |
260 | 311 | </dependency> |
335 | 386 | <dependency> |
336 | 387 | <groupId>org.apache.logging.log4j</groupId> |
337 | 388 | <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> | |
338 | 406 | <version>${project.version}</version> |
339 | 407 | <classifier>javadoc</classifier> |
340 | 408 | </dependency> |
408 | 476 | </dependency> |
409 | 477 | <dependency> |
410 | 478 | <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> | |
411 | 513 | <artifactId>log4j-spring-boot</artifactId> |
412 | 514 | <version>${project.version}</version> |
413 | 515 | </dependency> |
439 | 541 | <artifactId>log4j-spring-cloud-config-client</artifactId> |
440 | 542 | <version>${project.version}</version> |
441 | 543 | <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> | |
442 | 555 | </dependency> |
443 | 556 | </dependencies> |
444 | 557 | <build> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-docker</artifactId> |
25 | 25 | <packaging>jar</packaging> |
34 | 34 | import com.fasterxml.jackson.databind.ObjectMapper; |
35 | 35 | |
36 | 36 | /** |
37 | * Lookups up keys for for a Docker container. | |
37 | * Lookups up keys for a Docker container. | |
38 | 38 | */ |
39 | 39 | @Plugin(name = "docker", category = StrLookup.CATEGORY) |
40 | 40 | public class DockerLookup extends AbstractLookup { |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-flume-ng</artifactId> |
25 | 25 | <packaging>jar</packaging> |
69 | 69 | <dependency> |
70 | 70 | <groupId>org.junit.vintage</groupId> |
71 | 71 | <artifactId>junit-vintage-engine</artifactId> |
72 | <scope>test</scope> | |
72 | 73 | </dependency> |
73 | 74 | <dependency> |
74 | 75 | <groupId>org.junit.jupiter</groupId> |
75 | 76 | <artifactId>junit-jupiter-engine</artifactId> |
77 | <scope>test</scope> | |
76 | 78 | </dependency> |
77 | 79 | <dependency> |
78 | 80 | <groupId>org.apache.flume</groupId> |
+2
-2
248 | 248 | final int delayMillis = Integers.parseInt(maxDelayMillis, DEFAULT_MAX_DELAY); |
249 | 249 | |
250 | 250 | if (layout == null) { |
251 | final String enterpriseNumber = Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER; | |
251 | final int enterpriseNumber = Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER; | |
252 | 252 | layout = new Rfc5424Layout.Rfc5424LayoutBuilder() |
253 | 253 | .setFacility(Facility.LOCAL0) |
254 | .setEin(enterpriseNumber) | |
254 | .setEin(String.valueOf(enterpriseNumber)) | |
255 | 255 | .setIncludeMDC(true) |
256 | 256 | .setMdcId(Rfc5424Layout.DEFAULT_MDCID) |
257 | 257 | .setMdcPrefix(mdcPrefix) |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-iostreams</artifactId> |
25 | 25 | <packaging>jar</packaging> |
55 | 55 | <dependency> |
56 | 56 | <groupId>org.junit.vintage</groupId> |
57 | 57 | <artifactId>junit-vintage-engine</artifactId> |
58 | <scope>test</scope> | |
58 | 59 | </dependency> |
59 | 60 | <dependency> |
60 | 61 | <groupId>org.junit.jupiter</groupId> |
61 | 62 | <artifactId>junit-jupiter-engine</artifactId> |
63 | <scope>test</scope> | |
62 | 64 | </dependency> |
63 | 65 | <dependency> |
64 | 66 | <groupId>org.hamcrest</groupId> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | |
25 | 25 | <artifactId>log4j-jakarta-smtp</artifactId> |
68 | 68 | <dependency> |
69 | 69 | <groupId>org.junit.vintage</groupId> |
70 | 70 | <artifactId>junit-vintage-engine</artifactId> |
71 | <scope>test</scope> | |
71 | 72 | </dependency> |
72 | 73 | <dependency> |
73 | 74 | <groupId>org.junit.jupiter</groupId> |
74 | 75 | <artifactId>junit-jupiter-engine</artifactId> |
76 | <scope>test</scope> | |
75 | 77 | </dependency> |
76 | 78 | <dependency> |
77 | 79 | <groupId>org.hamcrest</groupId> |
19 | 19 | <parent> |
20 | 20 | <artifactId>log4j</artifactId> |
21 | 21 | <groupId>org.apache.logging.log4j</groupId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <modelVersion>4.0.0</modelVersion> |
25 | 25 | |
60 | 60 | <scope>test</scope> |
61 | 61 | </dependency> |
62 | 62 | <dependency> |
63 | <groupId>org.hamcrest</groupId> | |
64 | <artifactId>hamcrest</artifactId> | |
63 | <groupId>org.hamcrest</groupId> | |
64 | <artifactId>hamcrest</artifactId> | |
65 | 65 | </dependency> |
66 | 66 | <dependency> |
67 | 67 | <groupId>org.junit.jupiter</groupId> |
68 | 68 | <artifactId>junit-jupiter-engine</artifactId> |
69 | <scope>test</scope> | |
69 | 70 | </dependency> |
70 | 71 | <dependency> |
71 | 72 | <groupId>org.mockito</groupId> |
72 | 73 | <artifactId>mockito-junit-jupiter</artifactId> |
73 | </dependency> | |
74 | </dependency> | |
74 | 75 | <dependency> |
75 | 76 | <groupId>org.springframework</groupId> |
76 | 77 | <artifactId>spring-test</artifactId> |
+28
-28
34 | 34 | */ |
35 | 35 | public class Log4jServletContextListener implements ServletContextListener { |
36 | 36 | |
37 | private static final int DEFAULT_STOP_TIMEOUT = 30; | |
37 | private static final int DEFAULT_STOP_TIMEOUT = 30; | |
38 | 38 | private static final TimeUnit DEFAULT_STOP_TIMEOUT_TIMEUNIT = TimeUnit.SECONDS; |
39 | 39 | |
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"; | |
42 | 42 | |
43 | private static final Logger LOGGER = StatusLogger.getLogger(); | |
43 | private static final Logger LOGGER = StatusLogger.getLogger(); | |
44 | 44 | |
45 | 45 | private ServletContext servletContext; |
46 | 46 | private Log4jWebLifeCycle initializer; |
52 | 52 | |
53 | 53 | if ("true".equalsIgnoreCase(servletContext.getInitParameter( |
54 | 54 | 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() + "."); | |
59 | 59 | } |
60 | 60 | |
61 | 61 | this.initializer = WebLoggerContextUtils.getWebLifeCycle(this.servletContext); |
68 | 68 | } |
69 | 69 | |
70 | 70 | @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."); | |
77 | 77 | |
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 | } | |
92 | 92 | } |
+2
-0
70 | 70 | chain.doFilter(request, response); |
71 | 71 | } finally { |
72 | 72 | this.initializer.clearLoggerContext(); |
73 | // Execute once per thread | |
74 | request.removeAttribute(ALREADY_FILTERED_ATTRIBUTE); | |
73 | 75 | } |
74 | 76 | } |
75 | 77 | } |
+5
-5
43 | 43 | @Override |
44 | 44 | public void contextInitialized(final ServletContextEvent event) { |
45 | 45 | LOGGER.debug(Log4jShutdownOnContextDestroyedListener.class.getSimpleName() + |
46 | " ensuring that Log4j started up properly."); | |
46 | " ensuring that Log4j started up properly."); | |
47 | 47 | servletContext = event.getServletContext(); |
48 | 48 | 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."); | |
52 | 52 | } |
53 | 53 | this.initializer = WebLoggerContextUtils.getWebLifeCycle(servletContext); |
54 | 54 | } |
60 | 60 | return; |
61 | 61 | } |
62 | 62 | LOGGER.debug(Log4jShutdownOnContextDestroyedListener.class.getSimpleName() + |
63 | " ensuring that Log4j shuts down properly."); | |
63 | " ensuring that Log4j shuts down properly."); | |
64 | 64 | |
65 | 65 | this.initializer.clearLoggerContext(); // the application is finished |
66 | 66 | // shutting down now |
+24
-24
37 | 37 | @Plugin(name = "Servlet", category = "Core", elementType = "appender", printObject = true) |
38 | 38 | public class ServletAppender extends AbstractAppender { |
39 | 39 | |
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> { | |
42 | 42 | |
43 | 43 | @PluginBuilderAttribute |
44 | 44 | private boolean logThrowables; |
45 | 45 | |
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 | } | |
64 | 64 | |
65 | 65 | /** |
66 | 66 | * Logs with {@link ServletContext#log(String, Throwable)} if true and with {@link ServletContext#log(String)} if false. |
78 | 78 | this.logThrowables = logThrowables; |
79 | 79 | } |
80 | 80 | |
81 | } | |
81 | } | |
82 | 82 | |
83 | 83 | @PluginBuilderFactory |
84 | 84 | public static <B extends Builder<B>> B newBuilder() { |
119 | 119 | public static ServletAppender createAppender(final Layout<? extends Serializable> layout, final Filter filter, |
120 | 120 | final String name, final boolean ignoreExceptions) { |
121 | 121 | // @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 | |
125 | 125 | } |
126 | 126 | |
127 | 127 | } |
+6
-6
33 | 33 | |
34 | 34 | @ExtendWith(MockitoExtension.class) |
35 | 35 | 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) | |
42 | 42 | private ServletContext servletContext; |
43 | 43 | @Mock |
44 | 44 | private Log4jWebLifeCycle initializer; |
+4
-3
71 | 71 | |
72 | 72 | @Test |
73 | 73 | public void testDestroy() { |
74 | assertThrows(IllegalStateException.class, () -> { | |
75 | this.filter.destroy(); | |
76 | }); | |
74 | assertThrows(IllegalStateException.class, () -> { | |
75 | this.filter.destroy(); | |
76 | }); | |
77 | 77 | } |
78 | 78 | |
79 | 79 | @Test |
92 | 92 | then(chain).should().doFilter(same(request), same(response)); |
93 | 93 | then(chain).shouldHaveNoMoreInteractions(); |
94 | 94 | then(initializer).should().clearLoggerContext(); |
95 | then(request).should().removeAttribute(Log4jServletFilter.ALREADY_FILTERED_ATTRIBUTE); | |
95 | 96 | } |
96 | 97 | |
97 | 98 | @Test |
+11
-11
42 | 42 | public void setUp(boolean mockInitializer) { |
43 | 43 | this.listener = new Log4jShutdownOnContextDestroyedListener(); |
44 | 44 | 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); | |
48 | 48 | } |
49 | 49 | } |
50 | ||
50 | ||
51 | 51 | @Test |
52 | 52 | public void testInitAndDestroy() throws Exception { |
53 | setUp(true); | |
53 | setUp(true); | |
54 | 54 | this.listener.contextInitialized(this.event); |
55 | 55 | |
56 | 56 | then(initializer).should(never()).start(); |
64 | 64 | |
65 | 65 | @Test |
66 | 66 | public void testDestroy() throws Exception { |
67 | setUp(true); | |
67 | setUp(true); | |
68 | 68 | this.listener.contextDestroyed(this.event); |
69 | 69 | |
70 | 70 | then(initializer).should(never()).clearLoggerContext(); |
73 | 73 | |
74 | 74 | @Test |
75 | 75 | 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 | }); | |
81 | 81 | } |
82 | 82 | } |
+14
-14
44 | 44 | |
45 | 45 | @ExtendWith(MockitoExtension.class) |
46 | 46 | 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; | |
52 | 52 | @Captor |
53 | 53 | private ArgumentCaptor<Log4jWebLifeCycle> initializerCaptor; |
54 | 54 | @Captor |
72 | 72 | |
73 | 73 | @Test |
74 | 74 | public void testDeinitializeBeforeInitialize() { |
75 | assertThrows(IllegalStateException.class, () -> { | |
76 | this.initializerImpl.stop(); | |
77 | }); | |
75 | assertThrows(IllegalStateException.class, () -> { | |
76 | this.initializerImpl.stop(); | |
77 | }); | |
78 | 78 | } |
79 | 79 | |
80 | 80 | @Test |
213 | 213 | |
214 | 214 | then(servletContext).should().removeAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE)); |
215 | 215 | |
216 | assertThrows(IllegalStateException.class, () -> { | |
217 | this.initializerImpl.start(); | |
218 | }); | |
216 | assertThrows(IllegalStateException.class, () -> { | |
217 | this.initializerImpl.start(); | |
218 | }); | |
219 | 219 | } |
220 | 220 | |
221 | 221 | @Test |
247 | 247 | given(servletContext.getResourcePaths("/WEB-INF/")).willReturn(null); |
248 | 248 | assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null."); |
249 | 249 | |
250 | assertThrows(IllegalStateException.class, () -> { | |
251 | this.initializerImpl.start(); | |
252 | }); | |
250 | assertThrows(IllegalStateException.class, () -> { | |
251 | this.initializerImpl.start(); | |
252 | }); | |
253 | 253 | } |
254 | 254 | |
255 | 255 | @Test |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-jcl</artifactId> |
25 | 25 | <packaging>jar</packaging> |
36 | 36 | <dependency> |
37 | 37 | <groupId>org.junit.vintage</groupId> |
38 | 38 | <artifactId>junit-vintage-engine</artifactId> |
39 | <scope>test</scope> | |
39 | 40 | </dependency> |
40 | 41 | <dependency> |
41 | 42 | <groupId>org.junit.jupiter</groupId> |
42 | 43 | <artifactId>junit-jupiter-engine</artifactId> |
44 | <scope>test</scope> | |
43 | 45 | </dependency> |
44 | 46 | <dependency> |
45 | 47 | <groupId>org.hamcrest</groupId> |
89 | 91 | <configuration> |
90 | 92 | <instructions> |
91 | 93 | <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> | |
92 | 96 | </instructions> |
93 | 97 | </configuration> |
94 | 98 | </plugin> |
10 | 10 | <parent> |
11 | 11 | <groupId>org.apache.logging.log4j</groupId> |
12 | 12 | <artifactId>log4j</artifactId> |
13 | <version>2.18.0</version> | |
13 | <version>2.19.0</version> | |
14 | 14 | </parent> |
15 | 15 | <modelVersion>4.0.0</modelVersion> |
16 | 16 | |
40 | 40 | <dependency> |
41 | 41 | <groupId>org.junit.vintage</groupId> |
42 | 42 | <artifactId>junit-vintage-engine</artifactId> |
43 | <scope>test</scope> | |
43 | 44 | </dependency> |
44 | 45 | <dependency> |
45 | 46 | <groupId>org.junit.jupiter</groupId> |
46 | 47 | <artifactId>junit-jupiter-engine</artifactId> |
48 | <scope>test</scope> | |
47 | 49 | </dependency> |
48 | 50 | <dependency> |
49 | 51 | <groupId>org.apache.logging.log4j</groupId> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-jmx-gui</artifactId> |
25 | 25 | <packaging>jar</packaging> |
10 | 10 | <parent> |
11 | 11 | <groupId>org.apache.logging.log4j</groupId> |
12 | 12 | <artifactId>log4j</artifactId> |
13 | <version>2.18.0</version> | |
13 | <version>2.19.0</version> | |
14 | 14 | </parent> |
15 | 15 | <modelVersion>4.0.0</modelVersion> |
16 | 16 | |
49 | 49 | <dependency> |
50 | 50 | <groupId>org.junit.vintage</groupId> |
51 | 51 | <artifactId>junit-vintage-engine</artifactId> |
52 | <scope>test</scope> | |
52 | 53 | </dependency> |
53 | 54 | <dependency> |
54 | 55 | <groupId>org.junit.jupiter</groupId> |
55 | 56 | <artifactId>junit-jupiter-engine</artifactId> |
57 | <scope>test</scope> | |
56 | 58 | </dependency> |
57 | 59 | <dependency> |
58 | 60 | <groupId>org.apache.logging.log4j</groupId> |
19 | 19 | <parent> |
20 | 20 | <artifactId>log4j</artifactId> |
21 | 21 | <groupId>org.apache.logging.log4j</groupId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <modelVersion>4.0.0</modelVersion> |
25 | 25 | |
57 | 57 | <dependency> |
58 | 58 | <groupId>org.junit.vintage</groupId> |
59 | 59 | <artifactId>junit-vintage-engine</artifactId> |
60 | <scope>test</scope> | |
60 | 61 | </dependency> |
61 | 62 | <dependency> |
62 | 63 | <groupId>org.junit.jupiter</groupId> |
63 | 64 | <artifactId>junit-jupiter-engine</artifactId> |
65 | <scope>test</scope> | |
64 | 66 | </dependency> |
65 | 67 | </dependencies> |
66 | 68 |
19 | 19 | <parent> |
20 | 20 | <artifactId>log4j</artifactId> |
21 | 21 | <groupId>org.apache.logging.log4j</groupId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <modelVersion>4.0.0</modelVersion> |
25 | 25 | |
62 | 62 | <dependency> |
63 | 63 | <groupId>junit</groupId> |
64 | 64 | <artifactId>junit</artifactId> |
65 | <scope>test</scope> | |
65 | 66 | </dependency> |
66 | 67 | <!-- Required for AsyncLogger testing --> |
67 | 68 | <dependency> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-kubernetes</artifactId> |
25 | 25 | <packaging>jar</packaging> |
51 | 51 | <dependency> |
52 | 52 | <groupId>org.junit.vintage</groupId> |
53 | 53 | <artifactId>junit-vintage-engine</artifactId> |
54 | <scope>test</scope> | |
54 | 55 | </dependency> |
55 | 56 | <dependency> |
56 | 57 | <groupId>org.junit.jupiter</groupId> |
57 | 58 | <artifactId>junit-jupiter-engine</artifactId> |
59 | <scope>test</scope> | |
58 | 60 | </dependency> |
59 | 61 | </dependencies> |
60 | 62 | <build> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.apache.logging.log4j</groupId> |
23 | 23 | <artifactId>log4j</artifactId> |
24 | <version>2.18.0</version> | |
24 | <version>2.19.0</version> | |
25 | 25 | </parent> |
26 | 26 | |
27 | 27 | <artifactId>log4j-layout-template-json</artifactId> |
+7
-2
70 | 70 | * first. |
71 | 71 | * <p> |
72 | 72 | * 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 | |
74 | 74 | * <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. | |
75 | 80 | * <p> |
76 | 81 | * <tt>elementTemplate</tt> is an object describing the template to be used |
77 | 82 | * while resolving the {@link StackTraceElement} array. If <tt>stringified</tt> |
137 | 142 | * "stackTrace": { |
138 | 143 | * "stringified": { |
139 | 144 | * "truncation": { |
140 | * "suffix": ">", | |
145 | * "suffix": "... [truncated]", | |
141 | 146 | * "pointMatcherStrings": ["at javax.servlet.http.HttpServlet.service"] |
142 | 147 | * } |
143 | 148 | * } |
+228
-38
15 | 15 | */ |
16 | 16 | package org.apache.logging.log4j.layout.template.json.resolver; |
17 | 17 | |
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.*; | |
21 | 19 | |
22 | 20 | import java.util.List; |
23 | 21 | import java.util.function.Supplier; |
30 | 28 | */ |
31 | 29 | final class StackTraceStringResolver implements StackTraceResolver { |
32 | 30 | |
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; | |
34 | 36 | |
35 | 37 | private final boolean truncationEnabled; |
36 | 38 | |
48 | 50 | final Supplier<TruncatingBufferedPrintWriter> writerSupplier = |
49 | 51 | () -> TruncatingBufferedPrintWriter.ofCapacity( |
50 | 52 | 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); | |
54 | 62 | this.truncationEnabled = |
55 | 63 | !truncationPointMatcherStrings.isEmpty() || |
56 | 64 | !truncationPointMatcherRegexes.isEmpty(); |
65 | 73 | return regexes |
66 | 74 | .stream() |
67 | 75 | .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)) | |
70 | 80 | .collect(Collectors.toList()); |
71 | 81 | } |
72 | 82 | |
74 | 84 | public void resolve( |
75 | 85 | final Throwable throwable, |
76 | 86 | final JsonWriter jsonWriter) { |
77 | final TruncatingBufferedPrintWriter writer = writerRecycler.acquire(); | |
87 | final TruncatingBufferedPrintWriter srcWriter = srcWriterRecycler.acquire(); | |
78 | 88 | 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); | |
82 | 92 | } 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) { | |
88 | 99 | |
89 | 100 | // Short-circuit if truncation is not enabled. |
90 | 101 | 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) { | |
93 | 178 | |
94 | 179 | // Check for string matches. |
95 | 180 | // noinspection ForLoopReplaceableByForEach (avoid iterator allocation) |
96 | 181 | for (int i = 0; i < truncationPointMatcherStrings.size(); i++) { |
97 | 182 | final String matcher = truncationPointMatcherStrings.get(i); |
98 | final int matchIndex = writer.indexOf(matcher); | |
183 | final int matchIndex = findMatchingIndex( | |
184 | matcher, writer, startIndex, endIndex); | |
99 | 185 | 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(); | |
103 | 188 | } |
104 | 189 | } |
105 | 190 | |
106 | 191 | // 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 | } | |
107 | 199 | // noinspection ForLoopReplaceableByForEach (avoid iterator allocation) |
108 | 200 | for (int i = 0; i < groupedTruncationPointMatcherRegexes.size(); i++) { |
109 | 201 | final Pattern pattern = groupedTruncationPointMatcherRegexes.get(i); |
110 | final Matcher matcher = pattern.matcher(writer); | |
202 | final Matcher matcher = pattern.matcher(sequence); | |
111 | 203 | final boolean matched = matcher.matches(); |
112 | 204 | if (matched) { |
113 | 205 | 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 | ||
127 | 317 | } |
128 | 318 | |
129 | 319 | } |
+106
-0
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 | } |
+12
-5
58 | 58 | return writer.truncated(); |
59 | 59 | } |
60 | 60 | |
61 | public int indexOf(final CharSequence seq) { | |
62 | Objects.requireNonNull(seq, "seq"); | |
63 | return writer.indexOf(seq); | |
64 | } | |
65 | ||
66 | 61 | @Override |
67 | 62 | public int length() { |
68 | 63 | return writer.length(); |
71 | 66 | @Override |
72 | 67 | public char charAt(final int index) { |
73 | 68 | 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; | |
74 | 81 | } |
75 | 82 | |
76 | 83 | @Override |
+16
-34
17 | 17 | |
18 | 18 | import java.io.Writer; |
19 | 19 | import java.util.Objects; |
20 | import java.util.stream.IntStream; | |
20 | 21 | |
21 | 22 | final class TruncatingBufferedWriter extends Writer implements CharSequence { |
22 | 23 | |
202 | 203 | |
203 | 204 | } |
204 | 205 | |
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 | ||
237 | 206 | @Override |
238 | 207 | public int length() { |
239 | return position + 1; | |
208 | return position; | |
240 | 209 | } |
241 | 210 | |
242 | 211 | @Override |
246 | 215 | |
247 | 216 | @Override |
248 | 217 | 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"); | |
250 | 232 | } |
251 | 233 | |
252 | 234 | @Override |
+16
-264
33 | 33 | import org.apache.logging.log4j.core.net.Severity; |
34 | 34 | import org.apache.logging.log4j.core.time.MutableInstant; |
35 | 35 | 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.*; | |
42 | 37 | 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.*; | |
50 | 39 | import org.apache.logging.log4j.test.AvailablePortFinder; |
51 | 40 | import org.apache.logging.log4j.util.Strings; |
52 | import org.assertj.core.api.Assertions; | |
53 | 41 | import org.junit.jupiter.api.Test; |
54 | 42 | |
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.*; | |
61 | 44 | import java.math.BigDecimal; |
62 | 45 | import java.net.ServerSocket; |
63 | 46 | import java.net.Socket; |
66 | 49 | import java.time.Instant; |
67 | 50 | import java.time.temporal.ChronoField; |
68 | 51 | 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.*; | |
74 | 53 | import java.util.concurrent.ArrayBlockingQueue; |
75 | 54 | import java.util.concurrent.BlockingQueue; |
76 | 55 | import java.util.concurrent.TimeUnit; |
80 | 59 | |
81 | 60 | import static org.apache.logging.log4j.layout.template.json.TestHelpers.*; |
82 | 61 | import static org.assertj.core.api.Assertions.assertThat; |
62 | import static org.assertj.core.api.Assertions.assertThatThrownBy; | |
83 | 63 | |
84 | 64 | @SuppressWarnings("DoubleBraceInitialization") |
85 | 65 | class JsonTemplateLayoutTest { |
769 | 749 | |
770 | 750 | } |
771 | 751 | |
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() { | |
804 | 754 | |
805 | 755 | // Create the log event. |
806 | 756 | 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; | |
844 | 757 | final Level level = Level.ERROR; |
845 | 758 | final LogEvent logEvent = Log4jLogEvent |
846 | 759 | .newBuilder() |
847 | 760 | .setLoggerName(LOGGER_NAME) |
848 | 761 | .setLevel(level) |
849 | 762 | .setMessage(message) |
850 | .setThrown(exception) | |
851 | 763 | .build(); |
852 | 764 | |
853 | 765 | // Create the event template. |
970 | 882 | // Verify the test case. |
971 | 883 | usingSerializedLogEventAccessor(layout, logEvent, accessor -> |
972 | 884 | testCase.forEach((key, expectedValue) -> |
973 | Assertions | |
974 | .assertThat(accessor.getObject(key)) | |
885 | assertThat(accessor.getObject(key)) | |
975 | 886 | .describedAs("key=%s", key) |
976 | 887 | .isEqualTo(expectedValue))); |
977 | 888 | |
1139 | 1050 | } |
1140 | 1051 | |
1141 | 1052 | @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 | |
1297 | 1053 | void test_inline_stack_trace_element_template() { |
1298 | 1054 | |
1299 | 1055 | // Create the event template. |
1325 | 1081 | |
1326 | 1082 | // Check the serialized log event. |
1327 | 1083 | 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)); | |
1331 | 1087 | |
1332 | 1088 | } |
1333 | 1089 | |
1354 | 1110 | .build(); |
1355 | 1111 | |
1356 | 1112 | // 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]+")); | |
1360 | 1116 | |
1361 | 1117 | } |
1362 | 1118 | |
1421 | 1177 | .newBuilder() |
1422 | 1178 | .setLoggerName(LOGGER_NAME) |
1423 | 1179 | .setMessage(message) |
1424 | .setThrown(NonAsciiUtf8MethodNameContainingException.INSTANCE) | |
1425 | 1180 | .build(); |
1426 | 1181 | |
1427 | 1182 | // Check the serialized event. |
1813 | 1568 | final String expectedSerializedLogEventJson = |
1814 | 1569 | "{}" + JsonTemplateLayoutDefaults.getEventDelimiter(); |
1815 | 1570 | final String actualSerializedLogEventJson = layout.toSerializable(logEvent); |
1816 | Assertions | |
1817 | .assertThat(actualSerializedLogEventJson) | |
1818 | .isEqualTo(expectedSerializedLogEventJson); | |
1571 | assertThat(actualSerializedLogEventJson).isEqualTo(expectedSerializedLogEventJson); | |
1819 | 1572 | |
1820 | 1573 | } |
1821 | 1574 | |
1846 | 1599 | .build(); |
1847 | 1600 | |
1848 | 1601 | // Check the serialized event. |
1849 | Assertions | |
1850 | .assertThatThrownBy(() -> layout.toSerializable(logEvent)) | |
1602 | assertThatThrownBy(() -> layout.toSerializable(logEvent)) | |
1851 | 1603 | .isInstanceOf(StackOverflowError.class); |
1852 | 1604 | |
1853 | 1605 | } |
+657
-0
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 | } |
+121
-0
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 | } |
+61
-2
17 | 17 | |
18 | 18 | import org.assertj.core.api.Assertions; |
19 | 19 | import org.junit.jupiter.api.Test; |
20 | ||
21 | import java.util.function.Consumer; | |
20 | 22 | |
21 | 23 | class TruncatingBufferedWriterTest { |
22 | 24 | |
224 | 226 | verifyTruncation(writer, 'n'); |
225 | 227 | } |
226 | 228 | |
227 | private void verifyTruncation( | |
229 | private static void verifyTruncation( | |
228 | 230 | final TruncatingBufferedWriter writer, |
229 | 231 | final char c) { |
230 | 232 | Assertions.assertThat(writer.buffer()).isEqualTo(new char[]{c}); |
234 | 236 | verifyClose(writer); |
235 | 237 | } |
236 | 238 | |
237 | private void verifyClose(final TruncatingBufferedWriter writer) { | |
239 | private static void verifyClose(final TruncatingBufferedWriter writer) { | |
238 | 240 | writer.close(); |
239 | 241 | Assertions.assertThat(writer.position()).isEqualTo(0); |
240 | 242 | Assertions.assertThat(writer.truncated()).isFalse(); |
241 | 243 | } |
242 | 244 | |
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 | ||
243 | 302 | } |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-liquibase</artifactId> |
25 | 25 | <packaging>jar</packaging> |
65 | 65 | <dependency> |
66 | 66 | <groupId>org.junit.vintage</groupId> |
67 | 67 | <artifactId>junit-vintage-engine</artifactId> |
68 | <scope>test</scope> | |
68 | 69 | </dependency> |
69 | 70 | <dependency> |
70 | 71 | <groupId>org.junit.jupiter</groupId> |
71 | 72 | <artifactId>junit-jupiter-engine</artifactId> |
73 | <scope>test</scope> | |
72 | 74 | </dependency> |
73 | 75 | </dependencies> |
74 | 76 | <build> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <modelVersion>4.0.0</modelVersion> |
25 | 25 | |
55 | 55 | <dependency> |
56 | 56 | <groupId>org.junit.vintage</groupId> |
57 | 57 | <artifactId>junit-vintage-engine</artifactId> |
58 | <scope>test</scope> | |
58 | 59 | </dependency> |
59 | 60 | <dependency> |
60 | 61 | <groupId>org.junit.jupiter</groupId> |
61 | 62 | <artifactId>junit-jupiter-engine</artifactId> |
63 | <scope>test</scope> | |
62 | 64 | </dependency> |
63 | 65 | <dependency> |
64 | 66 | <groupId>org.mockito</groupId> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <modelVersion>4.0.0</modelVersion> |
25 | 25 | |
55 | 55 | <dependency> |
56 | 56 | <groupId>org.junit.vintage</groupId> |
57 | 57 | <artifactId>junit-vintage-engine</artifactId> |
58 | <scope>test</scope> | |
58 | 59 | </dependency> |
59 | 60 | <dependency> |
60 | 61 | <groupId>org.junit.jupiter</groupId> |
61 | 62 | <artifactId>junit-jupiter-engine</artifactId> |
63 | <scope>test</scope> | |
62 | 64 | </dependency> |
63 | 65 | <dependency> |
64 | 66 | <groupId>org.mockito</groupId> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-osgi</artifactId> |
25 | 25 | <packaging>jar</packaging> |
31 | 31 | <projectDir>/osgi</projectDir> |
32 | 32 | <module.name>org.apache.logging.log4j.osgi</module.name> |
33 | 33 | <maven.doap.skip>true</maven.doap.skip> |
34 | <pax.exam.version>4.13.5</pax.exam.version> | |
34 | 35 | </properties> |
35 | 36 | <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> | |
36 | 85 | <!-- 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 --> |
37 | 86 | <dependency> |
38 | 87 | <groupId>org.apache.felix</groupId> |
42 | 91 | <dependency> |
43 | 92 | <groupId>org.osgi</groupId> |
44 | 93 | <artifactId>org.osgi.core</artifactId> |
45 | <scope>test</scope> | |
46 | 94 | </dependency> |
47 | 95 | <dependency> |
48 | 96 | <groupId>org.junit.vintage</groupId> |
49 | 97 | <artifactId>junit-vintage-engine</artifactId> |
98 | <scope>test</scope> | |
50 | 99 | </dependency> |
51 | 100 | <dependency> |
52 | 101 | <groupId>org.junit.jupiter</groupId> |
53 | 102 | <artifactId>junit-jupiter-engine</artifactId> |
103 | <scope>test</scope> | |
54 | 104 | </dependency> |
55 | 105 | <dependency> |
56 | 106 | <groupId>org.eclipse.tycho</groupId> |
58 | 108 | <scope>test</scope> |
59 | 109 | </dependency> |
60 | 110 | <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> | |
69 | 143 | </dependency> |
70 | 144 | </dependencies> |
71 | 145 | <build> |
107 | 181 | </Import-Package> |
108 | 182 | </instructions> |
109 | 183 | </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> | |
110 | 208 | </plugin> |
111 | 209 | </plugins> |
112 | 210 | </build> |
+12
-27
22 | 22 | import java.io.PrintStream; |
23 | 23 | import java.lang.reflect.Field; |
24 | 24 | import java.lang.reflect.Method; |
25 | import java.nio.file.Path; | |
26 | import java.nio.file.Paths; | |
27 | 25 | import java.util.List; |
28 | 26 | import java.util.stream.Collectors; |
29 | 27 | import java.util.stream.Stream; |
30 | 28 | |
31 | import org.apache.logging.log4j.osgi.tests.junit.BundleTestInfo; | |
32 | 29 | import org.apache.logging.log4j.osgi.tests.junit.OsgiRule; |
30 | import org.apache.logging.log4j.util.ServiceLoaderUtil; | |
33 | 31 | import org.junit.Assert; |
34 | 32 | import org.junit.Before; |
35 | 33 | import org.junit.Rule; |
46 | 44 | |
47 | 45 | private BundleContext bundleContext; |
48 | 46 | |
49 | private final BundleTestInfo bundleTestInfo; | |
50 | ||
51 | private Path here; | |
52 | ||
53 | 47 | @Rule |
54 | 48 | 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 | } | |
61 | 49 | |
62 | 50 | /** |
63 | 51 | * Called before each @Test. |
65 | 53 | @Before |
66 | 54 | public void before() throws BundleException { |
67 | 55 | 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); | |
70 | 62 | } |
71 | 63 | |
72 | 64 | 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"); | |
75 | 66 | } |
76 | 67 | |
77 | 68 | |
78 | 69 | 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"); | |
81 | 71 | } |
82 | 72 | |
83 | 73 | 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"); | |
86 | 75 | } |
87 | 76 | |
88 | 77 | 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"); | |
91 | 79 | } |
92 | 80 | |
93 | 81 | 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"); | |
98 | 83 | } |
99 | 84 | |
100 | 85 | 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 | } |
+71
-0
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
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 | } |
19 | 19 | <parent> |
20 | 20 | <artifactId>log4j</artifactId> |
21 | 21 | <groupId>org.apache.logging.log4j</groupId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | |
25 | 25 | <artifactId>log4j-perf</artifactId> |
19 | 19 | <parent> |
20 | 20 | <artifactId>log4j-samples</artifactId> |
21 | 21 | <groupId>org.apache.logging.log4j.samples</groupId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-samples-configuration</artifactId> |
25 | 25 | <packaging>jar</packaging> |
19 | 19 | <parent> |
20 | 20 | <artifactId>log4j-samples</artifactId> |
21 | 21 | <groupId>org.apache.logging.log4j.samples</groupId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-samples-flume-common</artifactId> |
25 | 25 | <packaging>jar</packaging> |
19 | 19 | <parent> |
20 | 20 | <artifactId>log4j-samples</artifactId> |
21 | 21 | <groupId>org.apache.logging.log4j.samples</groupId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-samples-flume-embedded</artifactId> |
25 | 25 | <packaging>war</packaging> |
19 | 19 | <parent> |
20 | 20 | <artifactId>log4j-samples</artifactId> |
21 | 21 | <groupId>org.apache.logging.log4j.samples</groupId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-samples-flume-remote</artifactId> |
25 | 25 | <packaging>war</packaging> |
19 | 19 | <parent> |
20 | 20 | <artifactId>log4j-samples</artifactId> |
21 | 21 | <groupId>org.apache.logging.log4j.samples</groupId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-samples-loggerProperties</artifactId> |
25 | 25 | <packaging>jar</packaging> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <groupId>org.apache.logging.log4j.samples</groupId> |
25 | 25 | <artifactId>log4j-samples</artifactId> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-slf4j-impl</artifactId> |
25 | 25 | <packaging>jar</packaging> |
87 | 87 | <dependency> |
88 | 88 | <groupId>org.junit.vintage</groupId> |
89 | 89 | <artifactId>junit-vintage-engine</artifactId> |
90 | <scope>test</scope> | |
90 | 91 | </dependency> |
91 | 92 | <dependency> |
92 | 93 | <groupId>org.junit.jupiter</groupId> |
93 | 94 | <artifactId>junit-jupiter-engine</artifactId> |
95 | <scope>test</scope> | |
94 | 96 | </dependency> |
95 | 97 | </dependencies> |
96 | 98 | <build> |
29 | 29 | import org.apache.logging.log4j.util.LoaderUtil; |
30 | 30 | import org.slf4j.Marker; |
31 | 31 | import org.slf4j.MarkerFactory; |
32 | import org.slf4j.impl.StaticMarkerBinder; | |
33 | 32 | import org.slf4j.spi.LocationAwareLogger; |
34 | 33 | |
35 | 34 | /** |
46 | 45 | private final boolean eventLogger; |
47 | 46 | private transient ExtendedLogger logger; |
48 | 47 | 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; | |
51 | 52 | this.logger = logger; |
52 | 53 | this.eventLogger = "EventLogger".equals(name); |
53 | 54 | this.name = name; |
85 | 86 | |
86 | 87 | @Override |
87 | 88 | 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); | |
89 | 90 | } |
90 | 91 | |
91 | 92 | @Override |
92 | 93 | 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); | |
94 | 95 | } |
95 | 96 | |
96 | 97 | @Override |
97 | 98 | 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); | |
99 | 100 | } |
100 | 101 | |
101 | 102 | @Override |
102 | 103 | 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); | |
104 | 105 | } |
105 | 106 | |
106 | 107 | @Override |
107 | 108 | 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); | |
109 | 110 | } |
110 | 111 | |
111 | 112 | @Override |
112 | 113 | 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); | |
114 | 115 | } |
115 | 116 | |
116 | 117 | @Override |
145 | 146 | |
146 | 147 | @Override |
147 | 148 | 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); | |
149 | 150 | } |
150 | 151 | |
151 | 152 | @Override |
152 | 153 | 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); | |
154 | 155 | } |
155 | 156 | |
156 | 157 | @Override |
157 | 158 | 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); | |
159 | 160 | } |
160 | 161 | |
161 | 162 | @Override |
162 | 163 | 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); | |
164 | 165 | } |
165 | 166 | |
166 | 167 | @Override |
167 | 168 | 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); | |
169 | 170 | } |
170 | 171 | |
171 | 172 | @Override |
172 | 173 | 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); | |
174 | 175 | } |
175 | 176 | |
176 | 177 | @Override |
205 | 206 | |
206 | 207 | @Override |
207 | 208 | 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); | |
209 | 210 | } |
210 | 211 | |
211 | 212 | @Override |
212 | 213 | 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); | |
214 | 215 | } |
215 | 216 | |
216 | 217 | @Override |
217 | 218 | 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); | |
219 | 220 | } |
220 | 221 | |
221 | 222 | @Override |
222 | 223 | 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); | |
224 | 225 | } |
225 | 226 | |
226 | 227 | @Override |
227 | 228 | 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); | |
229 | 230 | } |
230 | 231 | |
231 | 232 | @Override |
232 | 233 | 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); | |
234 | 235 | } |
235 | 236 | |
236 | 237 | @Override |
265 | 266 | |
266 | 267 | @Override |
267 | 268 | 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); | |
269 | 270 | } |
270 | 271 | |
271 | 272 | @Override |
272 | 273 | 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); | |
274 | 275 | } |
275 | 276 | |
276 | 277 | @Override |
277 | 278 | 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); | |
279 | 280 | } |
280 | 281 | |
281 | 282 | @Override |
282 | 283 | 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); | |
284 | 285 | } |
285 | 286 | |
286 | 287 | @Override |
287 | 288 | 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); | |
289 | 290 | } |
290 | 291 | |
291 | 292 | @Override |
292 | 293 | 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); | |
294 | 295 | } |
295 | 296 | |
296 | 297 | @Override |
325 | 326 | |
326 | 327 | @Override |
327 | 328 | 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); | |
329 | 330 | } |
330 | 331 | |
331 | 332 | @Override |
332 | 333 | 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); | |
334 | 335 | } |
335 | 336 | |
336 | 337 | @Override |
337 | 338 | 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); | |
339 | 340 | } |
340 | 341 | |
341 | 342 | @Override |
342 | 343 | 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); | |
344 | 345 | } |
345 | 346 | |
346 | 347 | @Override |
347 | 348 | 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); | |
349 | 350 | } |
350 | 351 | |
351 | 352 | @Override |
352 | 353 | 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) { | |
358 | 359 | 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); | |
360 | 361 | |
361 | 362 | if (!logger.isEnabled(log4jLevel, log4jMarker, message, params)) { |
362 | 363 | return; |
363 | 364 | } |
364 | 365 | final Message msg; |
366 | final Throwable actualThrowable; | |
365 | 367 | if (CONVERTER != null && eventLogger && marker != null && marker.contains(EVENT_MARKER)) { |
366 | 368 | msg = CONVERTER.convertEvent(message, params, throwable); |
369 | actualThrowable = throwable != null ? throwable : msg.getThrowable(); | |
367 | 370 | } else if (params == null) { |
368 | 371 | msg = new SimpleMessage(message); |
372 | actualThrowable = throwable; | |
369 | 373 | } else { |
370 | 374 | msg = new ParameterizedMessage(message, params, throwable); |
371 | if (throwable != null) { | |
372 | throwable = msg.getThrowable(); | |
373 | } | |
375 | actualThrowable = throwable != null ? throwable : msg.getThrowable(); | |
374 | 376 | } |
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); | |
387 | 378 | } |
388 | 379 | |
389 | 380 | @Override |
399 | 390 | // always perform the default de-serialization first |
400 | 391 | aInputStream.defaultReadObject(); |
401 | 392 | logger = LogManager.getContext().getLogger(name); |
393 | markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory(); | |
402 | 394 | } |
403 | 395 | |
404 | 396 | /** |
33 | 33 | |
34 | 34 | private static final StatusLogger LOGGER = StatusLogger.getLogger(); |
35 | 35 | private static final String SLF4J_PACKAGE = "org.slf4j"; |
36 | private static final String TO_SLF4J_CONTEXT = "org.apache.logging.slf4j.SLF4JLoggerContext"; | |
37 | 36 | private static final Predicate<Class<?>> CALLER_PREDICATE = clazz -> |
38 | 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 | } | |
39 | 45 | |
40 | 46 | @Override |
41 | 47 | protected Logger newLogger(final String name, final LoggerContext context) { |
42 | 48 | 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); | |
44 | 50 | } |
45 | 51 | |
46 | 52 | @Override |
54 | 60 | : getContext(anchor); |
55 | 61 | } |
56 | 62 | |
63 | Log4jMarkerFactory getMarkerFactory() { | |
64 | return markerFactory; | |
65 | } | |
66 | ||
57 | 67 | private LoggerContext validateContext(final LoggerContext context) { |
58 | 68 | if (TO_SLF4J_CONTEXT.equals(context.getClass().getName())) { |
59 | 69 | throw new LoggingException("log4j-slf4j-impl cannot be present with log4j-to-slf4j"); |
51 | 51 | } |
52 | 52 | |
53 | 53 | @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) { | |
56 | 55 | ThreadContext.clearMap(); |
57 | 56 | ThreadContext.putAll(map); |
58 | 57 | } |
23 | 23 | import org.apache.logging.log4j.MarkerManager; |
24 | 24 | import org.slf4j.IMarkerFactory; |
25 | 25 | import org.slf4j.Marker; |
26 | import org.slf4j.impl.StaticMarkerBinder; | |
27 | 26 | |
28 | 27 | /** |
29 | * Log4j/SLF4J {@link org.slf4j.Marker} type bridge. | |
28 | * Log4j/SLF4J {@link Marker} type bridge. | |
30 | 29 | */ |
31 | public class Log4jMarker implements Marker { | |
30 | class Log4jMarker implements Marker { | |
32 | 31 | |
33 | 32 | public static final long serialVersionUID = 1590472L; |
34 | 33 | |
35 | private final IMarkerFactory factory = StaticMarkerBinder.SINGLETON.getMarkerFactory(); | |
34 | private final IMarkerFactory factory; | |
36 | 35 | |
37 | 36 | private final org.apache.logging.log4j.Marker marker; |
38 | 37 | |
40 | 39 | * Constructs a Log4jMarker using an existing Log4j {@link org.apache.logging.log4j.Marker}. |
41 | 40 | * @param marker The Log4j Marker upon which to base this Marker. |
42 | 41 | */ |
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; | |
44 | 44 | this.marker = marker; |
45 | 45 | } |
46 | 46 | |
54 | 54 | } |
55 | 55 | |
56 | 56 | @Override |
57 | public boolean contains(final org.slf4j.Marker marker) { | |
57 | public boolean contains(final Marker marker) { | |
58 | 58 | if (marker == null) { |
59 | 59 | throw new IllegalArgumentException(); |
60 | 60 | } |
55 | 55 | } |
56 | 56 | |
57 | 57 | 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); | |
59 | 59 | final Marker existing = markerMap.putIfAbsent(name, marker); |
60 | 60 | return existing == null ? marker : existing; |
61 | 61 | } |
77 | 77 | return addMarkerIfAbsent(marker.getName(), convertMarker(marker)); |
78 | 78 | } |
79 | 79 | |
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) { | |
81 | 97 | if (original == null) { |
82 | 98 | throw new IllegalArgumentException("Marker must not be null"); |
83 | 99 | } |
16 | 16 | package org.slf4j.impl; |
17 | 17 | |
18 | 18 | import org.apache.logging.slf4j.Log4jLoggerFactory; |
19 | import org.apache.logging.slf4j.Log4jMarkerFactory; | |
19 | 20 | import org.slf4j.ILoggerFactory; |
20 | 21 | import org.slf4j.spi.LoggerFactoryBinder; |
21 | 22 | |
49 | 50 | * Private constructor to prevent instantiation |
50 | 51 | */ |
51 | 52 | private StaticLoggerBinder() { |
52 | loggerFactory = new Log4jLoggerFactory(); | |
53 | loggerFactory = new Log4jLoggerFactory((Log4jMarkerFactory) StaticMarkerBinder.getSingleton().getMarkerFactory()); | |
53 | 54 | } |
54 | 55 | |
55 | 56 | /** |
28 | 28 | */ |
29 | 29 | public static final StaticMDCBinder SINGLETON = new StaticMDCBinder(); |
30 | 30 | |
31 | private final MDCAdapter mdcAdapter = new Log4jMDCAdapter(); | |
32 | ||
31 | 33 | private StaticMDCBinder() { |
32 | 34 | } |
33 | 35 | |
45 | 47 | * @return an MDC adapter |
46 | 48 | */ |
47 | 49 | public MDCAdapter getMDCA() { |
48 | return new Log4jMDCAdapter(); | |
50 | return mdcAdapter; | |
49 | 51 | } |
50 | 52 | |
51 | 53 | /** |
20 | 20 | The Log4j 2 SLF4J Binding allows applications coded to the SLF4J API to use |
21 | 21 | Log4j 2 as the implementation. |
22 | 22 | |
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. | |
24 | 24 | |
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. | |
27 | 27 | |
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. | |
29 | 31 | |
30 | 32 | ## Requirements |
31 | 33 |
+67
-67
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 | } |
18 | 18 | import org.apache.logging.log4j.Marker; |
19 | 19 | import org.apache.logging.log4j.MarkerManager; |
20 | 20 | import org.junit.Assert; |
21 | import org.junit.BeforeClass; | |
21 | 22 | import org.junit.Test; |
22 | 23 | |
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 | } | |
24 | 33 | |
25 | 34 | @Test |
26 | 35 | public void testEquals() { |
27 | 36 | final Marker markerA = MarkerManager.getMarker(Log4jMarkerTest.class.getName() + "-A"); |
28 | 37 | 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); | |
32 | 41 | Assert.assertEquals(marker1, marker2); |
33 | 42 | Assert.assertNotEquals(marker1, null); |
34 | 43 | Assert.assertNotEquals(null, marker1); |
18 | 18 | import org.apache.logging.log4j.core.LifeCycle; |
19 | 19 | import org.apache.logging.log4j.spi.LoggerContext; |
20 | 20 | import org.junit.Test; |
21 | import org.slf4j.impl.StaticLoggerBinder; | |
21 | import org.slf4j.LoggerFactory; | |
22 | 22 | |
23 | 23 | import java.util.Set; |
24 | 24 | |
25 | import static org.junit.Assert.*; | |
25 | import static org.junit.Assert.assertTrue; | |
26 | 26 | |
27 | 27 | /** |
28 | 28 | * Tests cleanup of the LoggerContexts. |
31 | 31 | |
32 | 32 | @Test |
33 | 33 | public void testCleanup() throws Exception { |
34 | Log4jLoggerFactory factory = (Log4jLoggerFactory) StaticLoggerBinder.getSingleton().getLoggerFactory(); | |
34 | Log4jLoggerFactory factory = (Log4jLoggerFactory) LoggerFactory.getILoggerFactory(); | |
35 | 35 | factory.getLogger("test"); |
36 | 36 | Set<LoggerContext> set = factory.getLoggerContexts(); |
37 | 37 | LoggerContext ctx1 = set.toArray(LoggerContext.EMPTY_ARRAY)[0]; |
22 | 22 | import java.util.List; |
23 | 23 | import java.util.Locale; |
24 | 24 | |
25 | import org.apache.logging.log4j.core.LogEvent; | |
25 | 26 | import org.apache.logging.log4j.junit.LoggerContextRule; |
26 | 27 | import org.apache.logging.log4j.test.appender.ListAppender; |
27 | 28 | import org.apache.logging.log4j.util.Strings; |
161 | 162 | verify("EventLogger", "o.a.l.s.LoggerTest Transfer [Audit@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"] Transfer Complete" + Strings.LINE_SEPARATOR); |
162 | 163 | } |
163 | 164 | |
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) { | |
165 | 190 | final ListAppender listApp = ctx.getListAppender(name); |
166 | 191 | 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); | |
167 | 197 | final List<String> events = listApp.getMessages(); |
168 | 198 | assertTrue("Incorrect number of messages. Expected 1 Actual " + events.size(), events.size()== 1); |
169 | 199 | final String actual = events.get(0); |
171 | 201 | listApp.clear(); |
172 | 202 | } |
173 | 203 | |
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 | ||
174 | 213 | @Before |
175 | 214 | @After |
176 | 215 | public void cleanup() { |
177 | 216 | MDC.clear(); |
178 | 217 | ctx.getListAppender("List").clear(); |
218 | ctx.getListAppender("UnformattedList").clear(); | |
179 | 219 | ctx.getListAppender("EventLogger").clear(); |
180 | 220 | } |
181 | 221 | } |
20 | 20 | import org.junit.After; |
21 | 21 | import org.junit.Assert; |
22 | 22 | import org.junit.Before; |
23 | import org.junit.BeforeClass; | |
23 | 24 | import org.junit.Test; |
24 | 25 | |
25 | 26 | import static org.junit.Assert.*; |
31 | 32 | |
32 | 33 | private static final String CHILD_MAKER_NAME = MarkerTest.class.getSimpleName() + "-TEST"; |
33 | 34 | private static final String PARENT_MARKER_NAME = MarkerTest.class.getSimpleName() + "-PARENT"; |
35 | private static Log4jMarkerFactory markerFactory; | |
34 | 36 | |
35 | @Before | |
37 | @BeforeClass | |
38 | public static void startup() { | |
39 | markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory(); | |
40 | ||
41 | } | |
42 | ||
43 | @Before | |
36 | 44 | @After |
37 | 45 | public void clearMarkers() { |
38 | 46 | MarkerManager.clear(); |
64 | 72 | slf4jMarker.add(slf4jParent); |
65 | 73 | final Marker log4jParent = MarkerManager.getMarker(parentMakerName); |
66 | 74 | 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); | |
69 | 77 | final org.slf4j.Marker nullMarker = null; |
70 | 78 | try { |
71 | 79 | log4jSlf4jParent.add(nullMarker); |
125 | 133 | slf4jMarker.add(slf4jParent); |
126 | 134 | final Marker log4jParent = MarkerManager.getMarker(parentMakerName); |
127 | 135 | 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); | |
130 | 138 | final org.slf4j.Marker nullMarker = null; |
131 | 139 | try { |
132 | 140 | Assert.assertFalse(log4jSlf4jParent.contains(nullMarker)); |
151 | 159 | slf4jMarker.add(slf4jParent); |
152 | 160 | final Marker log4jParent = MarkerManager.getMarker(parentMakerName); |
153 | 161 | 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); | |
156 | 164 | final String nullStr = null; |
157 | 165 | Assert.assertFalse(log4jSlf4jParent.contains(nullStr)); |
158 | 166 | Assert.assertFalse(log4jSlf4jMarker.contains(nullStr)); |
167 | 175 | slf4jMarker.add(slf4jParent); |
168 | 176 | final Marker log4jParent = MarkerManager.getMarker(parentMakerName); |
169 | 177 | 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); | |
172 | 180 | final org.slf4j.Marker nullMarker = null; |
173 | 181 | Assert.assertFalse(log4jSlf4jParent.remove(nullMarker)); |
174 | 182 | Assert.assertFalse(log4jSlf4jMarker.remove(nullMarker)); |
15 | 15 | */ |
16 | 16 | package org.apache.logging.slf4j; |
17 | 17 | |
18 | import static org.junit.Assert.fail; | |
19 | ||
18 | 20 | import org.apache.logging.log4j.LoggingException; |
19 | 21 | import org.junit.Test; |
20 | import org.slf4j.Logger; | |
21 | 22 | import org.slf4j.LoggerFactory; |
22 | ||
23 | import static org.junit.Assert.fail; | |
24 | 23 | |
25 | 24 | /** |
26 | 25 | * Tests StackOverflow when slf4j-impl and to-slf4j are both present. |
30 | 29 | @Test |
31 | 30 | public void log() { |
32 | 31 | try { |
33 | final Logger logger = LoggerFactory.getLogger(OverflowTest.class); | |
32 | LoggerFactory.getLogger(OverflowTest.class); | |
34 | 33 | fail("Failed to detect inclusion of log4j-to-slf4j"); |
35 | 34 | } catch (LoggingException ex) { |
36 | 35 | // 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 | } |
19 | 19 | <List name="List"> |
20 | 20 | <PatternLayout pattern="%C{1.} %m MDC%X%n%ex{0}"/> |
21 | 21 | </List> |
22 | <List name="UnformattedList" /> | |
22 | 23 | <SLF4J name="SLF4J"/> |
23 | 24 | </Appenders> |
24 | 25 | |
33 | 34 | |
34 | 35 | <Root level="trace"> |
35 | 36 | <AppenderRef ref="List"/> |
37 | <AppenderRef ref="UnformattedList"/> | |
36 | 38 | </Root> |
37 | 39 | </Loggers> |
38 | 40 |
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 © {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 | /* | |
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 | /* | |
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 | /* | |
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 | /* | |
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 | 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
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
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 | /* | |
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
0 | org.apache.logging.slf4j.SLF4JServiceProvider⏎ |
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 | <!-- | |
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
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
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 | ||
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
-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 | ||
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 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.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 | /* | |
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 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 | /* | |
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 | <?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 | <?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 © {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 | } |
+41
-0
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; |
+1
-0
0 | org.apache.logging.slf4j.SLF4JServiceProvider⏎ |
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> |
+91
-0
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 | } |
+75
-0
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 | } |
+41
-0
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 | }⏎ |
+67
-0
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>⏎ |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-spring-boot</artifactId> |
25 | 25 | <packaging>jar</packaging> |
55 | 55 | <dependency> |
56 | 56 | <groupId>org.junit.vintage</groupId> |
57 | 57 | <artifactId>junit-vintage-engine</artifactId> |
58 | <scope>test</scope> | |
58 | 59 | </dependency> |
59 | 60 | <dependency> |
60 | 61 | <groupId>org.junit.jupiter</groupId> |
61 | 62 | <artifactId>junit-jupiter-engine</artifactId> |
63 | <scope>test</scope> | |
62 | 64 | </dependency> |
63 | 65 | <dependency> |
64 | 66 | <groupId>org.junit.jupiter</groupId> |
65 | 67 | <artifactId>junit-jupiter-api</artifactId> |
68 | <scope>test</scope> | |
66 | 69 | </dependency> |
67 | 70 | <dependency> |
68 | 71 | <groupId>org.apache.logging.log4j</groupId> |
+0
-269
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 | } |
+267
-0
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
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 | } |
+25
-17
20 | 20 | |
21 | 21 | import org.apache.logging.log4j.Logger; |
22 | 22 | import org.apache.logging.log4j.core.LogEvent; |
23 | import org.apache.logging.log4j.core.LoggerContext; | |
24 | import org.apache.logging.log4j.core.config.LoggerContextAware; | |
23 | 25 | import org.apache.logging.log4j.core.config.plugins.Plugin; |
24 | 26 | import org.apache.logging.log4j.core.lookup.StrLookup; |
25 | 27 | import org.apache.logging.log4j.core.util.Integers; |
30 | 32 | * Lookup for Spring properties. |
31 | 33 | */ |
32 | 34 | @Plugin(name = "spring", category = StrLookup.CATEGORY) |
33 | public class SpringLookup extends SpringEnvironmentHolder implements StrLookup { | |
35 | public class SpringLookup implements LoggerContextAware, StrLookup { | |
34 | 36 | |
35 | 37 | private static final Logger LOGGER = StatusLogger.getLogger(); |
36 | 38 | private static final String ACTIVE = "profiles.active"; |
39 | 41 | private static final Pattern ACTIVE_PATTERN = Pattern.compile(ACTIVE + PATTERN); |
40 | 42 | private static final Pattern DEFAULT_PATTERN = Pattern.compile(DEFAULT + PATTERN); |
41 | 43 | |
42 | public SpringLookup() { | |
43 | getEnvironment(); | |
44 | } | |
44 | private volatile Environment environment; | |
45 | 45 | |
46 | 46 | @Override |
47 | 47 | public String lookup(String key) { |
48 | Environment env = getEnvironment(); | |
49 | if (env != null) { | |
48 | if (environment != null) { | |
50 | 49 | String lowerKey = key.toLowerCase(); |
51 | 50 | if (lowerKey.startsWith(ACTIVE)) { |
52 | switch (env.getActiveProfiles().length) { | |
51 | switch (environment.getActiveProfiles().length) { | |
53 | 52 | case 0: { |
54 | 53 | return null; |
55 | 54 | } |
56 | 55 | case 1: { |
57 | return env.getActiveProfiles()[0]; | |
56 | return environment.getActiveProfiles()[0]; | |
58 | 57 | } |
59 | 58 | default: { |
60 | 59 | Matcher matcher = ACTIVE_PATTERN.matcher(key); |
61 | 60 | if (matcher.matches()) { |
62 | 61 | try { |
63 | 62 | 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]; | |
66 | 65 | } |
67 | 66 | LOGGER.warn("Index out of bounds for Spring active profiles: {}", index); |
68 | 67 | return null; |
72 | 71 | } |
73 | 72 | |
74 | 73 | } |
75 | return String.join(",", env.getActiveProfiles()); | |
74 | return String.join(",", environment.getActiveProfiles()); | |
76 | 75 | } |
77 | 76 | } |
78 | 77 | } else if (lowerKey.startsWith(DEFAULT)) { |
79 | switch (env.getDefaultProfiles().length) { | |
78 | switch (environment.getDefaultProfiles().length) { | |
80 | 79 | case 0: { |
81 | 80 | return null; |
82 | 81 | } |
83 | 82 | case 1: { |
84 | return env.getDefaultProfiles()[0]; | |
83 | return environment.getDefaultProfiles()[0]; | |
85 | 84 | } |
86 | 85 | default: { |
87 | 86 | Matcher matcher = DEFAULT_PATTERN.matcher(key); |
88 | 87 | if (matcher.matches()) { |
89 | 88 | try { |
90 | 89 | 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]; | |
93 | 92 | } |
94 | 93 | LOGGER.warn("Index out of bounds for Spring default profiles: {}", index); |
95 | 94 | return null; |
99 | 98 | } |
100 | 99 | |
101 | 100 | } |
102 | return String.join(",", env.getDefaultProfiles()); | |
101 | return String.join(",", environment.getDefaultProfiles()); | |
103 | 102 | } |
104 | 103 | } |
105 | 104 | } |
106 | 105 | |
107 | return env.getProperty(key); | |
106 | return environment.getProperty(key); | |
108 | 107 | |
109 | 108 | } |
110 | 109 | return null; |
114 | 113 | public String lookup(LogEvent event, String key) { |
115 | 114 | return lookup((key)); |
116 | 115 | } |
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 | } | |
117 | 125 | } |
+31
-6
15 | 15 | */ |
16 | 16 | package org.apache.logging.log4j.spring.boot; |
17 | 17 | |
18 | import org.apache.logging.log4j.Logger; | |
19 | import org.apache.logging.log4j.core.LoggerContext; | |
18 | 20 | import org.apache.logging.log4j.core.config.Configuration; |
19 | 21 | import org.apache.logging.log4j.core.config.Node; |
20 | 22 | import org.apache.logging.log4j.core.config.arbiters.Arbiter; |
22 | 24 | import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute; |
23 | 25 | import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory; |
24 | 26 | 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; | |
25 | 29 | import org.springframework.core.env.Environment; |
26 | 30 | import org.springframework.core.env.Profiles; |
27 | 31 | import org.springframework.util.StringUtils; |
31 | 35 | */ |
32 | 36 | @Plugin(name = "SpringProfile", category = Node.CATEGORY, elementType = Arbiter.ELEMENT_TYPE, |
33 | 37 | deferChildren = true, printObject = true) |
34 | public class SpringProfileArbiter extends SpringEnvironmentHolder implements Arbiter { | |
38 | public class SpringProfileArbiter implements Arbiter { | |
35 | 39 | |
36 | 40 | private final String[] profileNames; |
41 | private final Environment environment; | |
37 | 42 | |
38 | private SpringProfileArbiter(final String[] profiles) { | |
43 | private SpringProfileArbiter(final String[] profiles, Environment environment) { | |
39 | 44 | this.profileNames = profiles; |
40 | ||
45 | this.environment = environment; | |
41 | 46 | } |
42 | 47 | |
43 | 48 | @Override |
44 | 49 | public boolean isCondition() { |
45 | Environment environment = getEnvironment(); | |
46 | 50 | if (environment == null) { |
47 | 51 | return false; |
48 | 52 | } |
60 | 64 | |
61 | 65 | public static class Builder implements org.apache.logging.log4j.core.util.Builder<SpringProfileArbiter> { |
62 | 66 | |
67 | private final Logger LOGGER = StatusLogger.getLogger(); | |
63 | 68 | public static final String ATTR_NAME = "name"; |
64 | 69 | |
65 | 70 | @PluginBuilderAttribute(ATTR_NAME) |
66 | 71 | private String name; |
67 | 72 | |
68 | 73 | @PluginConfiguration |
69 | private Configuration configuration;; | |
74 | private Configuration configuration; | |
75 | ||
76 | @PluginLoggerContext | |
77 | private LoggerContext loggerContext; | |
70 | 78 | |
71 | 79 | /** |
72 | 80 | * Sets the Profile Name or Names. |
83 | 91 | return asBuilder(); |
84 | 92 | } |
85 | 93 | |
94 | public Builder setLoggerContext(final LoggerContext loggerContext) { | |
95 | this.loggerContext = loggerContext; | |
96 | return asBuilder(); | |
97 | } | |
98 | ||
86 | 99 | private SpringProfileArbiter.Builder asBuilder() { |
87 | 100 | return this; |
88 | 101 | } |
90 | 103 | public SpringProfileArbiter build() { |
91 | 104 | String[] profileNames = StringUtils.trimArrayElements( |
92 | 105 | 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; | |
94 | 119 | } |
95 | 120 | } |
96 | 121 | } |
+7
-3
21 | 21 | /** |
22 | 22 | * Returns properties from Spring. |
23 | 23 | */ |
24 | public class SpringPropertySource extends SpringEnvironmentHolder implements PropertySource { | |
24 | public class SpringPropertySource implements PropertySource { | |
25 | 25 | |
26 | 26 | private static final int DEFAULT_PRIORITY = -100; |
27 | ||
28 | private final Environment environment; | |
29 | ||
30 | public SpringPropertySource(Environment environment) { | |
31 | this.environment = environment; | |
32 | } | |
27 | 33 | |
28 | 34 | /** |
29 | 35 | * System properties take precendence followed by properties in Log4j properties files. Spring properties |
37 | 43 | |
38 | 44 | @Override |
39 | 45 | public String getProperty(String key) { |
40 | Environment environment = getEnvironment(); | |
41 | 46 | if (environment != null) { |
42 | 47 | return environment.getProperty(key); |
43 | 48 | } |
46 | 51 | |
47 | 52 | @Override |
48 | 53 | public boolean containsProperty(String key) { |
49 | Environment environment = getEnvironment(); | |
50 | 54 | if (environment != null) { |
51 | 55 | return environment.containsProperty(key); |
52 | 56 | } |
+0
-15
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 |
13 | 13 | # See the license for the specific language governing permissions and |
14 | 14 | # limitations under the license. |
15 | 15 | # |
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
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 | } |
+2
-0
53 | 53 | |
54 | 54 | @Override |
55 | 55 | public void run(ApplicationArguments args) throws Exception { |
56 | LoggerContext context = (LoggerContext) LogManager.getContext(false); | |
56 | 57 | SpringLookup lookup = new SpringLookup(); |
58 | lookup.setLoggerContext(context); | |
57 | 59 | LOGGER.info("Started: {}", lookup.lookup("spring.application.name")); |
58 | 60 | } |
59 | 61 | } |
+59
-0
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 | } |
+6
-4
38 | 38 | env.setDefaultProfiles("one", "two"); |
39 | 39 | env.setProperty("app.property", "test"); |
40 | 40 | LoggerContext context = (LoggerContext) LogManager.getContext(false); |
41 | context.putObject(Log4j2CloudConfigLoggingSystem.ENVIRONMENT_KEY, env); | |
41 | context.putObject(Log4j2SpringBootLoggingSystem.ENVIRONMENT_KEY, env); | |
42 | 42 | SpringLookup lookup = new SpringLookup(); |
43 | lookup.setLoggerContext(context); | |
43 | 44 | String result = lookup.lookup("profiles.active"); |
44 | 45 | assertNotNull("No active profiles", result); |
45 | 46 | assertEquals("Incorrect active profile", "test", result); |
65 | 66 | env.setActiveProfiles("test"); |
66 | 67 | env.setProperty("app.property", "test"); |
67 | 68 | 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); | |
71 | 73 | String result = lookup.lookup("spring:profiles.active"); |
72 | 74 | assertNotNull("No active profiles", result); |
73 | 75 | assertEquals("Incorrect active profile", "test", result); |
+1
-1
42 | 42 | public static void before() { |
43 | 43 | loggerContext = (LoggerContext) LogManager.getContext(false); |
44 | 44 | env = new MockEnvironment(); |
45 | loggerContext.putObject(Log4j2CloudConfigLoggingSystem.ENVIRONMENT_KEY, env); | |
45 | loggerContext.putObject(Log4j2SpringBootLoggingSystem.ENVIRONMENT_KEY, env); | |
46 | 46 | } |
47 | 47 | |
48 | 48 |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j-spring-cloud-config</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-spring-cloud-config-client</artifactId> |
25 | 25 | <packaging>jar</packaging> |
35 | 35 | <dependency> |
36 | 36 | <groupId>org.junit.vintage</groupId> |
37 | 37 | <artifactId>junit-vintage-engine</artifactId> |
38 | <scope>test</scope> | |
38 | 39 | </dependency> |
39 | 40 | <dependency> |
40 | 41 | <groupId>org.junit.jupiter</groupId> |
41 | 42 | <artifactId>junit-jupiter-engine</artifactId> |
43 | <scope>test</scope> | |
42 | 44 | </dependency> |
43 | 45 | <dependency> |
44 | 46 | <groupId>org.apache.logging.log4j</groupId> |
+1
-1
20 | 20 | <parent> |
21 | 21 | <groupId>org.apache.logging.log4j.samples</groupId> |
22 | 22 | <artifactId>log4j-spring-cloud-config-samples</artifactId> |
23 | <version>2.18.0</version> | |
23 | <version>2.19.0</version> | |
24 | 24 | </parent> |
25 | 25 | |
26 | 26 | <artifactId>sample-app</artifactId> |
+2
-2
20 | 20 | <groupId>org.apache.logging.log4j.samples</groupId> |
21 | 21 | <artifactId>log4j-spring-cloud-config-sample-server</artifactId> |
22 | 22 | <packaging>jar</packaging> |
23 | <version>2.18.0</version> | |
23 | <version>2.19.0</version> | |
24 | 24 | |
25 | 25 | <name>Apache Log4j Sample Configuration Service</name> |
26 | 26 | <description>Sample Cloud Config Server</description> |
304 | 304 | </profiles> |
305 | 305 | |
306 | 306 | <scm> |
307 | <tag>log4j-2.18.0-rc1</tag> | |
307 | <tag>log4j-2.19.0-rc2</tag> | |
308 | 308 | </scm> |
309 | 309 | </project> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j-spring-cloud-config</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <groupId>org.apache.logging.log4j.samples</groupId> |
25 | 25 | <artifactId>log4j-spring-cloud-config-samples</artifactId> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-spring-cloud-config</artifactId> |
25 | 25 | <packaging>pom</packaging> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-taglib</artifactId> |
25 | 25 | <packaging>jar</packaging> |
66 | 66 | <dependency> |
67 | 67 | <groupId>org.junit.vintage</groupId> |
68 | 68 | <artifactId>junit-vintage-engine</artifactId> |
69 | <scope>test</scope> | |
69 | 70 | </dependency> |
70 | 71 | <dependency> |
71 | 72 | <groupId>org.junit.jupiter</groupId> |
72 | 73 | <artifactId>junit-jupiter-engine</artifactId> |
74 | <scope>test</scope> | |
73 | 75 | </dependency> |
74 | 76 | <dependency> |
75 | 77 | <groupId>org.springframework</groupId> |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-to-jul</artifactId> |
25 | 25 | <packaging>jar</packaging> |
40 | 40 | <artifactId>log4j-api</artifactId> |
41 | 41 | </dependency> |
42 | 42 | <dependency> |
43 | <groupId>org.osgi</groupId> | |
44 | <artifactId>org.osgi.core</artifactId> | |
45 | </dependency> | |
46 | <dependency> | |
43 | 47 | <groupId>com.google.guava</groupId> |
44 | 48 | <artifactId>guava-testlib</artifactId> |
45 | 49 | <scope>test</scope> |
47 | 51 | <dependency> |
48 | 52 | <groupId>org.junit.vintage</groupId> |
49 | 53 | <artifactId>junit-vintage-engine</artifactId> |
54 | <scope>test</scope> | |
50 | 55 | </dependency> |
51 | 56 | <dependency> |
52 | 57 | <groupId>org.junit.jupiter</groupId> |
53 | 58 | <artifactId>junit-jupiter-engine</artifactId> |
59 | <scope>test</scope> | |
54 | 60 | </dependency> |
55 | 61 | <dependency> |
56 | 62 | <groupId>org.assertj</groupId> |
80 | 86 | <artifactId>maven-bundle-plugin</artifactId> |
81 | 87 | <configuration> |
82 | 88 | <instructions> |
89 | <Bundle-Activator>org.apache.logging.log4j.tojul.Activator</Bundle-Activator> | |
83 | 90 | <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> | |
90 | 91 | </instructions> |
91 | 92 | </configuration> |
92 | 93 | </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 | } |
152 | 152 | return current.getLevel(); |
153 | 153 | } |
154 | 154 | // 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; | |
156 | 157 | } |
157 | 158 | |
158 | 159 | 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 | } |
19 | 19 | <parent> |
20 | 20 | <groupId>org.apache.logging.log4j</groupId> |
21 | 21 | <artifactId>log4j</artifactId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <artifactId>log4j-to-slf4j</artifactId> |
25 | 25 | <packaging>jar</packaging> |
42 | 42 | <artifactId>log4j-api</artifactId> |
43 | 43 | </dependency> |
44 | 44 | <dependency> |
45 | <groupId>org.osgi</groupId> | |
46 | <artifactId>org.osgi.core</artifactId> | |
47 | </dependency> | |
48 | <dependency> | |
45 | 49 | <groupId>ch.qos.logback</groupId> |
46 | 50 | <artifactId>logback-core</artifactId> |
47 | 51 | <scope>test</scope> |
60 | 64 | <dependency> |
61 | 65 | <groupId>org.junit.vintage</groupId> |
62 | 66 | <artifactId>junit-vintage-engine</artifactId> |
67 | <scope>test</scope> | |
63 | 68 | </dependency> |
64 | 69 | <dependency> |
65 | 70 | <groupId>org.junit.jupiter</groupId> |
66 | 71 | <artifactId>junit-jupiter-engine</artifactId> |
72 | <scope>test</scope> | |
67 | 73 | </dependency> |
68 | 74 | <dependency> |
69 | 75 | <groupId>org.hamcrest</groupId> |
93 | 99 | <artifactId>maven-bundle-plugin</artifactId> |
94 | 100 | <configuration> |
95 | 101 | <instructions> |
102 | <Bundle-Activator>org.apache.logging.slf4j.Activator</Bundle-Activator> | |
96 | 103 | <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> | |
103 | 104 | </instructions> |
104 | 105 | </configuration> |
105 | 106 | </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 | } |
19 | 19 | <parent> |
20 | 20 | <artifactId>log4j</artifactId> |
21 | 21 | <groupId>org.apache.logging.log4j</groupId> |
22 | <version>2.18.0</version> | |
22 | <version>2.19.0</version> | |
23 | 23 | </parent> |
24 | 24 | <modelVersion>4.0.0</modelVersion> |
25 | 25 | |
58 | 58 | <scope>test</scope> |
59 | 59 | </dependency> |
60 | 60 | <dependency> |
61 | <groupId>org.hamcrest</groupId> | |
62 | <artifactId>hamcrest</artifactId> | |
61 | <groupId>org.hamcrest</groupId> | |
62 | <artifactId>hamcrest</artifactId> | |
63 | <scope>test</scope> | |
63 | 64 | </dependency> |
64 | 65 | <dependency> |
65 | 66 | <groupId>org.junit.jupiter</groupId> |
66 | 67 | <artifactId>junit-jupiter-engine</artifactId> |
68 | <scope>test</scope> | |
67 | 69 | </dependency> |
68 | 70 | <dependency> |
69 | 71 | <groupId>org.mockito</groupId> |
70 | 72 | <artifactId>mockito-junit-jupiter</artifactId> |
71 | </dependency> | |
73 | <scope>test</scope> | |
74 | </dependency> | |
72 | 75 | <dependency> |
73 | 76 | <groupId>org.springframework</groupId> |
74 | 77 | <artifactId>spring-test</artifactId> |
+28
-28
34 | 34 | */ |
35 | 35 | public class Log4jServletContextListener implements ServletContextListener { |
36 | 36 | |
37 | private static final int DEFAULT_STOP_TIMEOUT = 30; | |
37 | private static final int DEFAULT_STOP_TIMEOUT = 30; | |
38 | 38 | private static final TimeUnit DEFAULT_STOP_TIMEOUT_TIMEUNIT = TimeUnit.SECONDS; |
39 | 39 | |
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"; | |
42 | 42 | |
43 | private static final Logger LOGGER = StatusLogger.getLogger(); | |
43 | private static final Logger LOGGER = StatusLogger.getLogger(); | |
44 | 44 | |
45 | 45 | private ServletContext servletContext; |
46 | 46 | private Log4jWebLifeCycle initializer; |
52 | 52 | |
53 | 53 | if ("true".equalsIgnoreCase(servletContext.getInitParameter( |
54 | 54 | 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() + "."); | |
59 | 59 | } |
60 | 60 | |
61 | 61 | this.initializer = WebLoggerContextUtils.getWebLifeCycle(this.servletContext); |
68 | 68 | } |
69 | 69 | |
70 | 70 | @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."); | |
77 | 77 | |
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 | } | |
92 | 92 | } |
70 | 70 | chain.doFilter(request, response); |
71 | 71 | } finally { |
72 | 72 | this.initializer.clearLoggerContext(); |
73 | // Execute once per thread | |
74 | request.removeAttribute(ALREADY_FILTERED_ATTRIBUTE); | |
73 | 75 | } |
74 | 76 | } |
75 | 77 | } |
+5
-5
43 | 43 | @Override |
44 | 44 | public void contextInitialized(final ServletContextEvent event) { |
45 | 45 | LOGGER.debug(Log4jShutdownOnContextDestroyedListener.class.getSimpleName() + |
46 | " ensuring that Log4j started up properly."); | |
46 | " ensuring that Log4j started up properly."); | |
47 | 47 | servletContext = event.getServletContext(); |
48 | 48 | 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."); | |
52 | 52 | } |
53 | 53 | this.initializer = WebLoggerContextUtils.getWebLifeCycle(servletContext); |
54 | 54 | } |
60 | 60 | return; |
61 | 61 | } |
62 | 62 | LOGGER.debug(Log4jShutdownOnContextDestroyedListener.class.getSimpleName() + |
63 | " ensuring that Log4j shuts down properly."); | |
63 | " ensuring that Log4j shuts down properly."); | |
64 | 64 | |
65 | 65 | this.initializer.clearLoggerContext(); // the application is finished |
66 | 66 | // shutting down now |
+24
-24
37 | 37 | @Plugin(name = "Servlet", category = "Core", elementType = "appender", printObject = true) |
38 | 38 | public class ServletAppender extends AbstractAppender { |
39 | 39 | |
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> { | |
42 | 42 | |
43 | 43 | @PluginBuilderAttribute |
44 | 44 | private boolean logThrowables; |
45 | 45 | |
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 | } | |
64 | 64 | |
65 | 65 | /** |
66 | 66 | * Logs with {@link ServletContext#log(String, Throwable)} if true and with {@link ServletContext#log(String)} if false. |
78 | 78 | this.logThrowables = logThrowables; |
79 | 79 | } |
80 | 80 | |
81 | } | |
81 | } | |
82 | 82 | |
83 | 83 | @PluginBuilderFactory |
84 | 84 | public static <B extends Builder<B>> B newBuilder() { |
119 | 119 | public static ServletAppender createAppender(final Layout<? extends Serializable> layout, final Filter filter, |
120 | 120 | final String name, final boolean ignoreExceptions) { |
121 | 121 | // @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 | |
125 | 125 | } |
126 | 126 | |
127 | 127 | } |
+6
-6
33 | 33 | |
34 | 34 | @ExtendWith(MockitoExtension.class) |
35 | 35 | 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) | |
42 | 42 | private ServletContext servletContext; |
43 | 43 | @Mock |
44 | 44 | private Log4jWebLifeCycle initializer; |
71 | 71 | |
72 | 72 | @Test |
73 | 73 | public void testDestroy() { |
74 | assertThrows(IllegalStateException.class, () -> { | |
75 | this.filter.destroy(); | |
76 | }); | |
74 | assertThrows(IllegalStateException.class, () -> { | |
75 | this.filter.destroy(); | |
76 | }); | |
77 | 77 | } |
78 | 78 | |
79 | 79 | @Test |
92 | 92 | then(chain).should().doFilter(same(request), same(response)); |
93 | 93 | then(chain).shouldHaveNoMoreInteractions(); |
94 | 94 | then(initializer).should().clearLoggerContext(); |
95 | then(request).should().removeAttribute(Log4jServletFilter.ALREADY_FILTERED_ATTRIBUTE); | |
95 | 96 | } |
96 | 97 | |
97 | 98 | @Test |
+11
-11
42 | 42 | public void setUp(boolean mockInitializer) { |
43 | 43 | this.listener = new Log4jShutdownOnContextDestroyedListener(); |
44 | 44 | 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); | |
48 | 48 | } |
49 | 49 | } |
50 | ||
50 | ||
51 | 51 | @Test |
52 | 52 | public void testInitAndDestroy() throws Exception { |
53 | setUp(true); | |
53 | setUp(true); | |
54 | 54 | this.listener.contextInitialized(this.event); |
55 | 55 | |
56 | 56 | then(initializer).should(never()).start(); |
64 | 64 | |
65 | 65 | @Test |
66 | 66 | public void testDestroy() throws Exception { |
67 | setUp(true); | |
67 | setUp(true); | |
68 | 68 | this.listener.contextDestroyed(this.event); |
69 | 69 | |
70 | 70 | then(initializer).should(never()).clearLoggerContext(); |
73 | 73 | |
74 | 74 | @Test |
75 | 75 | 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 | }); | |
81 | 81 | } |
82 | 82 | } |
+14
-14
44 | 44 | |
45 | 45 | @ExtendWith(MockitoExtension.class) |
46 | 46 | 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; | |
52 | 52 | @Captor |
53 | 53 | private ArgumentCaptor<Log4jWebLifeCycle> initializerCaptor; |
54 | 54 | @Captor |
72 | 72 | |
73 | 73 | @Test |
74 | 74 | public void testDeinitializeBeforeInitialize() { |
75 | assertThrows(IllegalStateException.class, () -> { | |
76 | this.initializerImpl.stop(); | |
77 | }); | |
75 | assertThrows(IllegalStateException.class, () -> { | |
76 | this.initializerImpl.stop(); | |
77 | }); | |
78 | 78 | } |
79 | 79 | |
80 | 80 | @Test |
213 | 213 | |
214 | 214 | then(servletContext).should().removeAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE)); |
215 | 215 | |
216 | assertThrows(IllegalStateException.class, () -> { | |
217 | this.initializerImpl.start(); | |
218 | }); | |
216 | assertThrows(IllegalStateException.class, () -> { | |
217 | this.initializerImpl.start(); | |
218 | }); | |
219 | 219 | } |
220 | 220 | |
221 | 221 | @Test |
247 | 247 | given(servletContext.getResourcePaths("/WEB-INF/")).willReturn(null); |
248 | 248 | assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null."); |
249 | 249 | |
250 | assertThrows(IllegalStateException.class, () -> { | |
251 | this.initializerImpl.start(); | |
252 | }); | |
250 | assertThrows(IllegalStateException.class, () -> { | |
251 | this.initializerImpl.start(); | |
252 | }); | |
253 | 253 | } |
254 | 254 | |
255 | 255 | @Test |
20 | 20 | <artifactId>log4j</artifactId> |
21 | 21 | <packaging>pom</packaging> |
22 | 22 | <name>Apache Log4j 2</name> |
23 | <version>2.18.0</version> | |
23 | <version>2.19.0</version> | |
24 | 24 | <parent> |
25 | 25 | <groupId>org.apache.logging</groupId> |
26 | 26 | <artifactId>logging-parent</artifactId> |
159 | 159 | <name>Piotr P. Karwasz</name> |
160 | 160 | <email>pkarwasz@apache.org</email> |
161 | 161 | <roles> |
162 | <role>Committer</role> | |
162 | <role>PMC Member</role> | |
163 | 163 | </roles> |
164 | 164 | <timezone>Europe/Warsaw</timezone> |
165 | 165 | </developer> |
223 | 223 | <connection>scm:git:https://gitbox.apache.org/repos/asf/logging-log4j2.git</connection> |
224 | 224 | <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/logging-log4j2.git</developerConnection> |
225 | 225 | <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> | |
227 | 227 | </scm> |
228 | 228 | <properties> |
229 | 229 | <!-- make sure to update these for each release! --> |
230 | 230 | <log4jParentDir>${basedir}</log4jParentDir> |
231 | <Log4jReleaseVersion>2.18.0</Log4jReleaseVersion> | |
231 | <Log4jReleaseVersion>2.19.0</Log4jReleaseVersion> | |
232 | 232 | <Log4jReleaseVersionJava7>2.12.4</Log4jReleaseVersionJava7> |
233 | 233 | <Log4jReleaseVersionJava6>2.3.2</Log4jReleaseVersionJava6> |
234 | 234 | <Log4jReleaseManager>Ralph Goers</Log4jReleaseManager> |
238 | 238 | <slf4jVersion>1.7.36</slf4jVersion> |
239 | 239 | <logbackVersion>1.2.11</logbackVersion> |
240 | 240 | <jackson1Version>1.9.13</jackson1Version> |
241 | <jackson2Version>2.13.3</jackson2Version> | |
241 | <jackson2Version>2.13.4</jackson2Version> | |
242 | 242 | <spring-boot.version>2.6.7</spring-boot.version> |
243 | 243 | <springVersion>5.3.20</springVersion> |
244 | 244 | <kubernetes-client.version>5.12.2</kubernetes-client.version> |
245 | <flumeVersion>1.10.0</flumeVersion> | |
245 | <flumeVersion>1.10.1</flumeVersion> | |
246 | 246 | <disruptorVersion>3.4.4</disruptorVersion> |
247 | 247 | <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> | |
249 | 249 | <mongodb3.version>3.12.11</mongodb3.version> |
250 | 250 | <mongodb4.version>4.5.0</mongodb4.version> |
251 | 251 | <!-- 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> | |
253 | 253 | <groovy.version>3.0.10</groovy.version> |
254 | 254 | <compiler.plugin.version>3.10.1</compiler.plugin.version> |
255 | 255 | <pmd.plugin.version>3.16.0</pmd.plugin.version> |
295 | 295 | <activemq.version>5.17.1</activemq.version> |
296 | 296 | <jctoolsVersion>3.3.0</jctoolsVersion> |
297 | 297 | <junitVersion>4.13.2</junitVersion> |
298 | <junitJupiterVersion>5.8.2</junitJupiterVersion> | |
298 | <junit5Version>5.9.0</junit5Version> | |
299 | 299 | <junitPioneerVersion>1.6.2</junitPioneerVersion> |
300 | 300 | <mockitoVersion>4.4.0</mockitoVersion> |
301 | 301 | <xmlunitVersion>2.9.0</xmlunitVersion> |
302 | 302 | <!-- Java EE 8 artifacts --> |
303 | 303 | <javax.activation.version>1.2.0</javax.activation.version> |
304 | <javax.inject.version>1</javax.inject.version> | |
304 | 305 | <javax.jms.version>2.0.1</javax.jms.version> |
305 | 306 | <javax.jsp.version>2.3.3</javax.jsp.version> |
306 | 307 | <javax.mail.version>1.6.2</javax.mail.version> |
314 | 315 | <module.name /> |
315 | 316 | <!-- Used in `log4j-appserver`, so that it does not override `wiremock`'s deps--> |
316 | 317 | <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> | |
318 | 319 | </properties> |
319 | 320 | <pluginRepositories> |
320 | 321 | <pluginRepository> |
333 | 334 | <dependencyManagement> |
334 | 335 | <dependencies> |
335 | 336 | <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> | |
336 | 344 | <groupId>org.slf4j</groupId> |
337 | 345 | <artifactId>slf4j-api</artifactId> |
338 | 346 | <version>${slf4jVersion}</version> |
458 | 466 | </dependency> |
459 | 467 | <dependency> |
460 | 468 | <groupId>org.apache.logging.log4j</groupId> |
461 | <artifactId>log4j-slf4j18-impl</artifactId> | |
469 | <artifactId>log4j-slf4j2-impl</artifactId> | |
462 | 470 | <version>${project.version}</version> |
463 | 471 | </dependency> |
464 | 472 | <dependency> |
465 | 473 | <groupId>org.apache.logging.log4j</groupId> |
466 | 474 | <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> | |
467 | 485 | <version>${project.version}</version> |
468 | 486 | </dependency> |
469 | 487 | <dependency> |
713 | 731 | <scope>provided</scope> |
714 | 732 | </dependency> |
715 | 733 | <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> | |
716 | 740 | <groupId>javax.jms</groupId> |
717 | 741 | <artifactId>javax.jms-api</artifactId> |
718 | 742 | <version>${javax.jms.version}</version> |
804 | 828 | </dependency> |
805 | 829 | <!-- JUnit 5 engine --> |
806 | 830 | <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> | |
837 | 836 | </dependency> |
838 | 837 | <!-- Environment and system properties support for Jupiter --> |
839 | 838 | <dependency> |
847 | 846 | <groupId>junit</groupId> |
848 | 847 | <artifactId>junit</artifactId> |
849 | 848 | <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> | |
857 | 849 | <scope>test</scope> |
858 | 850 | </dependency> |
859 | 851 | <dependency> |
987 | 979 | <dependency> |
988 | 980 | <groupId>net.javacrumbs.json-unit</groupId> |
989 | 981 | <artifactId>json-unit</artifactId> |
990 | <version>2.32.0</version> | |
982 | <version>2.35.0</version> | |
991 | 983 | <scope>test</scope> |
992 | 984 | </dependency> |
993 | 985 | <dependency> |
1012 | 1004 | <dependency> |
1013 | 1005 | <groupId>co.elastic.logging</groupId> |
1014 | 1006 | <artifactId>log4j2-ecs-layout</artifactId> |
1015 | <version>1.4.0</version> | |
1007 | <version>1.5.0</version> | |
1016 | 1008 | </dependency> |
1017 | 1009 | <dependency> |
1018 | 1010 | <groupId>org.elasticsearch.client</groupId> |
1299 | 1291 | <plugin> |
1300 | 1292 | <groupId>io.fabric8</groupId> |
1301 | 1293 | <artifactId>docker-maven-plugin</artifactId> |
1302 | <version>0.40.1</version> | |
1294 | <version>0.40.2</version> | |
1303 | 1295 | </plugin> |
1304 | 1296 | </plugins> |
1305 | 1297 | </pluginManagement> |
1700 | 1692 | <module>log4j-core-its</module> |
1701 | 1693 | <module>log4j-1.2-api</module> |
1702 | 1694 | <module>log4j-slf4j-impl</module> |
1703 | <module>log4j-slf4j18-impl</module> | |
1695 | <module>log4j-slf4j2-impl</module> | |
1704 | 1696 | <module>log4j-to-slf4j</module> |
1705 | 1697 | <module>log4j-to-jul</module> |
1706 | 1698 | <module>log4j-jcl</module> |
67 | 67 | This release primarily contains bug fixes and minor enhancements. |
68 | 68 | |
69 | 69 | 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. | |
73 | 72 | |
74 | 73 | The Log4j ${relVersion} API, as well as many core components, maintains binary compatibility with previous releases. |
75 | 74 |
28 | 28 | - "update" - Change |
29 | 29 | - "remove" - Removed |
30 | 30 | --> |
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> | |
31 | 96 | <release version="2.18.0" date="2022-06-28" description="GA Release 2.18.0"> |
32 | 97 | <action issue="LOG4J2-3339" dev="rgoers" type="fix"> |
33 | 98 | DirectWriteRolloverStrategy should use the current time when creating files. |
407 | 472 | Add optional additional fields to NoSQLAppender. |
408 | 473 | </action> |
409 | 474 | <!-- UPDATES --> |
410 | <action issue="LOG4J2-3368" dev="vy" type="udpate"> | |
475 | <action issue="LOG4J2-3368" dev="vy" type="update"> | |
411 | 476 | Bump Tomcat from 8.5.20 to 10.0.14 in log4j-appserver along with some dependency clean-up. |
412 | 477 | </action> |
413 | <action dev="ggregory" type="udpate" due-to="Dependabot"> | |
478 | <action dev="ggregory" type="update" due-to="Dependabot"> | |
414 | 479 | Bump mongodb3.version from 3.12.4 to 3.12.10 #605. |
415 | 480 | </action> |
416 | <action dev="ggregory" type="udpate" due-to="Dependabot"> | |
481 | <action dev="ggregory" type="update" due-to="Dependabot"> | |
417 | 482 | Bump awaitility from 4.0.3 to 4.1.1 #663. |
418 | 483 | </action> |
419 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
484 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
420 | 485 | Bump Mockito from 3.11.2 to 4.2.0. |
421 | 486 | </action> |
422 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
487 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
423 | 488 | Bump Jackson from 2.12.4 to 2.13.1. |
424 | 489 | </action> |
425 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
490 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
426 | 491 | Bump org.junit.jupiter:junit-* from 5.7.2 to 5.8.2. |
427 | 492 | </action> |
428 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
493 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
429 | 494 | Bump org.springframework:spring-* from 5.3.13 to 5.3.15. |
430 | 495 | </action> |
431 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
496 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
432 | 497 | Bump de.flapdoodle.embed:de.flapdoodle.embed.mongo from 3.0.0 to 3.4.1. Update tests for binary incompatibilities in APIs. |
433 | 498 | </action> |
434 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
499 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
435 | 500 | Bump org.fusesource.jansi:jansi from 2.3.4 to 2.4.0. |
436 | 501 | </action> |
437 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
502 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
438 | 503 | Bump net.javacrumbs.json-unit:json-unit from 2.27.0 to 2.28.0. |
439 | 504 | </action> |
440 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
505 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
441 | 506 | Bump org.assertj:assertj-core from 3.20.2 to 3.22.0. |
442 | 507 | </action> |
443 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
508 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
444 | 509 | Bump org.xmlunit:xmlunit-* from 2.8.3 to 2.8.4. |
445 | 510 | </action> |
446 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
511 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
447 | 512 | Bump org.codehaus.groovy:groovy-* from 3.0.8 to 3.0.9. |
448 | 513 | </action> |
449 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
514 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
450 | 515 | Bump org.mongodb:bson from 4.2.2 to 4.5.0. |
451 | 516 | </action> |
452 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
517 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
453 | 518 | Bump org.mongodb:mongodb-driver-sync from 4.2.2 to 4.5.0. |
454 | 519 | </action> |
455 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
520 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
456 | 521 | Bump Woodstox 6.2.6 to 6.2.8. |
457 | 522 | </action> |
458 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
523 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
459 | 524 | Bump maven-compiler-plugin from 3.8.1 to 3.9.0. |
460 | 525 | </action> |
461 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
526 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
462 | 527 | Bump org.eclipse.persistence:org.eclipse.persistence.jpa from 2.7.9 to 2.7.10. |
463 | 528 | </action> |
464 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
529 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
465 | 530 | Bump org.junit-pioneer:junit-pioneer from 1.5.0 to 1.6.1. |
466 | 531 | </action> |
467 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
532 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
468 | 533 | Bump org.apache.activemq:activemq-broker from 5.16.3 to 5.16.4. |
469 | 534 | </action> |
470 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
535 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
471 | 536 | Bump org.jacoco:jacoco-maven-plugin from 0.8.6 to 0.8.7. |
472 | 537 | </action> |
473 | <action dev="ggregory" type="udpate" due-to="Gary Gregory"> | |
538 | <action dev="ggregory" type="update" due-to="Gary Gregory"> | |
474 | 539 | Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.3.1 to 3.3.2. |
475 | 540 | </action> |
476 | 541 | </release> |
499 | 564 | Fix MapLookup to lookup MapMessage before DefaultMap |
500 | 565 | </action> |
501 | 566 | <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. | |
503 | 568 | </action> |
504 | 569 | <action dev="ggregory" type="fix"> |
505 | 570 | Fix NPE when input is null in StrSubstitutor.replace(String, Properties). |
551 | 616 | using '%m{lookups}'. |
552 | 617 | </action> |
553 | 618 | <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. | |
555 | 620 | </action> |
556 | 621 | <action issue="LOG4J2-2978" dev="rgoers" type="add" due-to="Michael Seele"> |
557 | 622 | Add support for Jakarta EE 9 (Tomcat 10 / Jetty 11) |
598 | 663 | Allow MapMessage and ThreadContext attributes to be prefixed. |
599 | 664 | </action> |
600 | 665 | <action issue="LOG4J2=3048" dev="rgoers" type="add"> |
601 | Add improved MapMessge support to GelfLayout. | |
666 | Add improved MapMessage support to GelfLayout. | |
602 | 667 | </action> |
603 | 668 | <action issue="LOG4J2-3044" dev="rgoers" type="add"> |
604 | 669 | Add RepeatPatternConverter. |
633 | 698 | Fix Log Event Level vs Logger Config Level table. |
634 | 699 | </action> |
635 | 700 | <action issue="LOG4J2-2540" dev="rgoers"> |
636 | Minor documentation correctsion regarding log levels. | |
701 | Minor documentation corrections regarding log levels. | |
637 | 702 | </action> |
638 | 703 | <action issue="LOG4J2-2541" dev="rgoers" due-to="Gerold Broser"> |
639 | 704 | Minor documentation corrections in the configuration section. |
1068 | 1133 | Move Spring Lookup and Spring PropertySource to its own module. |
1069 | 1134 | </action> |
1070 | 1135 | <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. | |
1072 | 1137 | </action> |
1073 | 1138 | <action issue="LOG4J2-2822" dev="rgoers" type="fix"> |
1074 | 1139 | Javadoc link in ThreadContext description was incorrect. |
1084 | 1149 | size based rollover after a time based rollover had occurred. |
1085 | 1150 | </action> |
1086 | 1151 | <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. | |
1088 | 1153 | </action> |
1089 | 1154 | <action issue="LOG4J2-2859" dev="rgoers" type="fix" due-to="Yanming Zhou"> |
1090 | 1155 | Fixed typos where mergeFactory should be mergeStrategy. |
1259 | 1324 | <action issue="LOG4J2-2717" dev="rgoers" type="fix"> |
1260 | 1325 | Slow initialization on Windows due to accessing network interfaces. |
1261 | 1326 | </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"> | |
1263 | 1328 | Conditionally perform status logging calculations in PluginRegistry. |
1264 | 1329 | </action> |
1265 | 1330 | <action issue="LOG4J2-2756" dev="rgoers" type="fix"> |
1296 | 1361 | PluginProcessor should use Messager instead of System.out. |
1297 | 1362 | </action> |
1298 | 1363 | <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. | |
1300 | 1365 | </action> |
1301 | 1366 | <action issue="LOG4J2-2760" dev="rgoers" type="fix" due-to="Christoph Kaser"> |
1302 | 1367 | Always write header on a new OutputStream. |
1312 | 1377 | NullPointerException when using a custom DirectFileRolloverStrategy without a file name. |
1313 | 1378 | </action> |
1314 | 1379 | <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. | |
1316 | 1381 | </action> |
1317 | 1382 | <action issue="LOG4J2-2770" dev="rgoers" type="fix" due-to="Bill Kuker"> |
1318 | 1383 | Fixed NullPointerException after reconfiguring via JMX. |
1387 | 1452 | Add ThreadContext.putIfNotNull method. |
1388 | 1453 | </action> |
1389 | 1454 | <action issue="LOG4J2-2731" dev="rgoers" type="add"> |
1390 | Add a Level Patttern Selector. | |
1455 | Add a Level Pattern Selector. | |
1391 | 1456 | </action> |
1392 | 1457 | <action issue="LOG4J2-2701" dev="rgoers" type="update"> |
1393 | 1458 | Update Jackson to 2.9.10. |
1483 | 1548 | Restore constructor to ThrowablePatternConverter that was removed in 2.8.2. |
1484 | 1549 | </action> |
1485 | 1550 | <action issue="LOG4J2-2622" dev="rgoers" type="fix"> |
1486 | StructuredDataId was ignoring maxLength atribute. | |
1551 | StructuredDataId was ignoring maxLength attribute. | |
1487 | 1552 | </action> |
1488 | 1553 | <action issue="LOG4J2-2636" dev="rgoers" type="fix"> |
1489 | 1554 | RFC5424Layout was not properly setting default Structured Element id for the MDC |
1553 | 1618 | PatternConverter instanceOf methods with unknown parameter types no longer elide those with known parameters. |
1554 | 1619 | </action> |
1555 | 1620 | <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. | |
1557 | 1622 | </action> |
1558 | 1623 | <action issue="LOG4J2-2612" dev="ggregory" type="fix"> |
1559 | 1624 | NullPointerException at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeInternal(JdbcDatabaseManager.java:803). |
1867 | 1932 | logged throwable and provided varargs array. |
1868 | 1933 | </action> |
1869 | 1934 | <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 | |
1871 | 1936 | </action> |
1872 | 1937 | <action issue="LOG4J2-2373" dev="ckozak" type="fix" due-to="Kevin Meurer"> |
1873 | 1938 | StringBuilders.escapeJson implementation runs in linear time. Escaping large JSON strings |
2103 | 2168 | MapMessage should use deep toString for values. |
2104 | 2169 | </action> |
2105 | 2170 | <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. | |
2107 | 2172 | </action> |
2108 | 2173 | <action issue="LOG4J2-2102" dev="mikes" type="fix" due-to="Carter Douglas Kozak"> |
2109 | 2174 | MapMessage JSON encoding will escape keys and values. |
2348 | 2413 | Consider the StringBuilder's capacity instead of content length when trimming. |
2349 | 2414 | </action> |
2350 | 2415 | <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. | |
2352 | 2417 | </action> |
2353 | 2418 | <action issue="LOG4J2-1994" dev="ggregory" type="fix"> |
2354 | 2419 | TcpSocketServer does not close accepted Sockets. |
2408 | 2473 | JMS Appender does not know how to recover from a broken connection. |
2409 | 2474 | </action> |
2410 | 2475 | <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. | |
2412 | 2477 | </action> |
2413 | 2478 | <action issue="LOG4J2-1956" dev="ggregory" type="update"> |
2414 | 2479 | JMS Appender broker password should be a char[], not a String. |
3305 | 3370 | minSize attribute. |
3306 | 3371 | </action> |
3307 | 3372 | <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. | |
3309 | 3374 | </action> |
3310 | 3375 | <action issue="LOG4J2-1434" dev="rpopma" type="fix" due-to="Luke Butters"> |
3311 | 3376 | Ensure that the thread-local StringBuilders used by Layouts to format log events to text will not |
3389 | 3454 | Added documentation about plugin builders compared to factories. |
3390 | 3455 | </action> |
3391 | 3456 | <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. | |
3393 | 3458 | </action> |
3394 | 3459 | </release> |
3395 | 3460 | <release version="2.6" date="2016-05-25" description="GA Release 2.6"> |
4110 | 4175 | Avoid creating temporary array object in org.apache.logging.slf4j.Log4jMarker.iterator(). |
4111 | 4176 | </action> |
4112 | 4177 | <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. | |
4114 | 4179 | </action> |
4115 | 4180 | <action issue="LOG4J2-403" dev="ggregory" type="update" due-to="Poorna Subhash P, Jeremy Lautman"> |
4116 | 4181 | MongoDB appender, username and password should be optional. |
4361 | 4426 | Documentation: add sections on the JUL Adapter, IO Streams and NoSQL Appenders to the Maven and Ivy page. |
4362 | 4427 | </action> |
4363 | 4428 | <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. | |
4365 | 4430 | </action> |
4366 | 4431 | <action issue="LOG4J2-855" dev="rpopma" type="fix"> |
4367 | 4432 | Documentation: fix broken links on Appenders manual page. |
4386 | 4451 | Documentation: added section on XInclude to user manual Configuration page. |
4387 | 4452 | </action> |
4388 | 4453 | <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. | |
4390 | 4455 | </action> |
4391 | 4456 | <action issue="LOG4J2-844" dev="rpopma" type="update"> |
4392 | 4457 | Update JMH to 1.1 from 0.7.2. |
4734 | 4799 | Create an appender to route log events to the ServletContext log. |
4735 | 4800 | </action> |
4736 | 4801 | <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. | |
4738 | 4803 | </action> |
4739 | 4804 | <action issue="LOG4J2-563" dev="rgoers" type="fix" due-to="Michael Friedmann"> |
4740 | 4805 | FlumeAvroManager now always uses a client type of default_failover. |
5212 | 5277 | [Pattern Layout] Customize level names to lower-case. |
5213 | 5278 | </action> |
5214 | 5279 | <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. | |
5216 | 5281 | </action> |
5217 | 5282 | <action dev="nickwilliams" type="update"> |
5218 | 5283 | Cleaned up tests and cleared up documentation for the JPA appender following the resolution of EclipseLink |
5556 | 5621 | Improved error reporting when misconfigured. |
5557 | 5622 | </action> |
5558 | 5623 | <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. | |
5560 | 5625 | </action> |
5561 | 5626 | <action dev="rpopma" type="update"> |
5562 | 5627 | Renamed AsynchAppender to AsyncAppender. Plugin name became Async (was Asynch). |
5853 | 5918 | Created combined jar to combine API and Core contents for users who only want the Log4j implementation. |
5854 | 5919 | </action> |
5855 | 5920 | <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 | |
5857 | 5922 | bug in Oracle's xmlparserv2 jar. |
5858 | 5923 | </action> |
5859 | 5924 | <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>⏎ |