├── .asf.yaml ├── .editorconfig ├── .gitattributes ├── .github ├── dependabot.yaml ├── generate-email.sh └── workflows │ ├── build.yaml │ ├── codeql-analysis.yaml │ ├── deploy-site.yaml │ └── merge-dependabot.yaml ├── .gitignore ├── .java-version ├── .mvn ├── jvm.config └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── LICENSE.txt ├── NOTICE.txt ├── README.adoc ├── antora-playbook.yaml ├── log4j-api-kotlin-benchmark ├── README.adoc ├── pom.xml └── src │ └── main │ ├── kotlin │ └── org │ │ └── apache │ │ └── logging │ │ └── log4j │ │ └── kotlin │ │ └── benchmark │ │ └── LoggingBenchmark.kt │ └── resources │ └── log4j2.xml ├── log4j-api-kotlin-sample ├── pom.xml └── src │ └── main │ ├── kotlin │ └── org │ │ └── apache │ │ └── logging │ │ └── log4j │ │ └── kotlin │ │ └── sample │ │ ├── LoggingApp.kt │ │ ├── LoggingAppExtensionProperty.kt │ │ └── LoggingAppMixin.kt │ └── resources │ └── log4j2.xml ├── log4j-api-kotlin ├── pom.xml └── src │ ├── main │ └── kotlin │ │ └── org │ │ └── apache │ │ └── logging │ │ └── log4j │ │ └── kotlin │ │ ├── ContextMap.kt │ │ ├── ContextStack.kt │ │ ├── CoroutineThreadContext.kt │ │ ├── KotlinLogger.kt │ │ ├── Logging.kt │ │ ├── LoggingFactory.kt │ │ ├── Suppliers.kt │ │ └── package-info.java │ └── test │ └── kotlin │ └── org.apache.logging.log4j.kotlin │ ├── LoggerCompanionTest.kt │ ├── LoggerContextNameTest.kt │ ├── LoggerMixinCompanionExtendsTest.kt │ ├── LoggerMixinExtendsTest.kt │ ├── LoggerReceiversTest.kt │ ├── LoggerTest.kt │ ├── NamedLoggerTest.kt │ ├── ThreadContextTest.kt │ └── support │ └── LoggerTests.kt ├── mvnw ├── mvnw.cmd ├── package.json ├── pom.xml └── src ├── changelog ├── .1.x.x │ ├── .release-notes.adoc.ftl │ ├── update_apache_logging_parent.xml │ ├── update_apache_logging_parent_github_workflows_codeql_analysis_reusable_yaml_rel_11_3_0.xml │ ├── update_apache_logging_parent_github_workflows_deploy_site_reusable_yaml_rel_11_3_0.xml │ ├── update_org_apache_logging_log4j_log4j_bom.xml │ ├── update_org_apache_logging_logging_parent.xml │ ├── update_org_codehaus_mojo_exec_maven_plugin.xml │ ├── update_org_jetbrains_kotlin_kotlin_stdlib.xml │ └── update_org_junit_junit_bom.xml ├── .changelog.adoc.ftl ├── .index.adoc.ftl ├── 1.0.0 │ ├── .release-notes.adoc.ftl │ ├── .release.xml │ ├── LOG4J2-1705_Create_Kotlin_API.xml │ └── LOG4J2-2432_Make_namedLogger_more_discoverable.xml ├── 1.1.0 │ ├── .release-notes.adoc.ftl │ ├── .release.xml │ ├── LOG4J2-2433_Support_MDCs_with_coroutines.xml │ ├── LOG4J2-2518_Support_suspend_functions.xml │ └── LOG4J2-2843_Update_Kotlin_baseline_to_1.3.72.xml ├── 1.2.0 │ ├── .release-notes.adoc.ftl │ ├── .release.xml │ └── LOG4J2-3218_Update_Log4j_baseline.xml ├── 1.3.0 │ ├── .release-notes.adoc.ftl │ ├── .release.xml │ ├── 28-Update_Log4j_baseline.xml │ ├── 29-Add_extension_property_for_logger.xml │ ├── 30-Add_facade_APIs_for_ThreadContext.xml │ ├── 32-Catching_Throwing.xml │ ├── 37-facelift.xml │ ├── JPMS.xml │ ├── OSGi-Bundle-SymbolicName.xml │ ├── dokka.xml │ ├── junit5.xml │ ├── kotlin-baseline.xml │ └── skip-deploy.xml ├── 1.4.0 │ ├── .release-notes.adoc.ftl │ ├── .release.xml │ ├── 54-thread-context.xml │ ├── add-sbom.xml │ ├── update-parent.xml │ ├── update_org_apache_logging_log4j_log4j_bom.xml │ ├── update_org_apache_logging_logging_parent.xml │ ├── update_org_codehaus_mojo_build_helper_maven_plugin.xml │ ├── update_org_codehaus_mojo_exec_maven_plugin.xml │ └── update_org_junit_junit_bom.xml └── 1.5.0 │ ├── .release-notes.adoc.ftl │ ├── .release.xml │ ├── add-coroutine-context-convenience-functions.xml │ ├── antora.xml │ └── update_org_apache_logging_log4j_log4j_bom.xml └── site └── antora ├── antora.tmpl.yml ├── antora.yml └── modules └── ROOT ├── nav.adoc └── pages ├── development.adoc ├── index.adoc └── release-notes.adoc /.asf.yaml: -------------------------------------------------------------------------------- 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 | # `.asf.yaml` is a branch-specific YAML configuration file for Git repositories to control features such as notifications, GitHub settings, etc. 19 | # See its documentation for details: https://cwiki.apache.org/confluence/display/INFRA/Git+-+.asf.yaml+features 20 | 21 | # Bare minimum `notifications` to 22 | # 23 | # 1. Forward GitHub _activity_ to `notifications@` 24 | # 2. Forward commits to `commits@` 25 | # 3. Forward `dependabot` PRs to `robots@` 26 | # 27 | # Note that `notifications` are merged with the defaults accessible from: https://gitbox.apache.org/schemes.cgi?logging-log4j-kotlin 28 | notifications: 29 | commits: commits@logging.apache.org 30 | issues: notifications@logging.apache.org 31 | pullrequests: notifications@logging.apache.org 32 | pullrequests_bot_dependabot: robots@logging.apache.org 33 | 34 | github: 35 | 36 | description: A Kotlin-friendly interface to log against the Log4j API 37 | homepage: https://logging.apache.org/log4j/kotlin 38 | labels: 39 | - apache 40 | - api 41 | - jvm 42 | - kotlin 43 | - library 44 | - log4j 45 | - log4j2 46 | - logging 47 | - logger 48 | - coroutines 49 | - concurrency 50 | 51 | del_branch_on_merge: true 52 | 53 | # Enforce squashing while merging PRs. 54 | # Otherwise, the git log gets polluted severely. 55 | enabled_merge_buttons: 56 | squash: true 57 | merge: false 58 | rebase: false 59 | 60 | features: 61 | issues: true 62 | 63 | protected_branches: 64 | main: 65 | required_signatures: true 66 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 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 | # https://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 | # Configuration here must match the one for Spotless in `pom.xml`! 17 | 18 | root = true 19 | 20 | [*] 21 | indent_size = 4 22 | ij_continuation_indent_size = 8 23 | indent_style = space 24 | trim_trailing_whitespace = true 25 | 26 | [*.kt] 27 | indent_size = 2 28 | ij_continuation_indent_size = 4 29 | 30 | # `ij_any_use_relative_indents = true` is deliberately left out since it messes up the indentation in ternary operator usages 31 | 32 | # Split some things over multiple lines to keep lines short 33 | ij_any_call_parameters_wrap = on_every_item 34 | ij_any_method_parameters_wrap = on_every_item 35 | ij_any_method_call_chain_wrap = on_every_item 36 | 37 | # Don't align with the first line to avoid single-line changes having an impact in the rest of the code 38 | ij_any_align_multiline_parameters_in_calls = false 39 | ij_any_align_multiline_parameters = false 40 | ij_any_align_multiline_chained_methods = false 41 | 42 | # Only use `import *` when importing 5 or more 43 | ij_java_names_count_to_use_import_on_demand = 5 44 | ij_java_class_count_to_use_import_on_demand = 5 45 | 46 | # Order imports 47 | # `*` denotes any packages except explicitly specified ones 48 | # `|` denotes a blank line 49 | # `$` denotes the prefix for static packages 50 | # `**` means including subpackages 51 | ij_java_imports_layout = java.**, |, javax.**, |, org.apache.logging.**, |, *, |, $java.**, |, $javax.**, |, $org.apache.logging.**, |, $* 52 | 53 | # Force curly braces 54 | ij_any_for_brace_force = always 55 | ij_any_if_brace_force = always 56 | ij_any_do_while_brace_force = always 57 | ij_any_while_brace_force = always 58 | 59 | # Don't align parameters and exceptions in javadoc based on the longest names to avoid single-line changes having an impact in the rest of the code 60 | ij_java_doc_align_param_comments = false 61 | ij_java_doc_align_exception_comments = false 62 | 63 | [*.{xml,xsd,properties,yml,yaml,json}] 64 | indent_size = 2 65 | 66 | [*.{md,adoc}] 67 | indent_size = 2 68 | ij_any_wrap_long_lines = false 69 | # The `no` value doesn't work in IntelliJ IDEA so a big number does the trick as well in most cases: 70 | max_line_length = 9999 71 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 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 | # https://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 | # Checked by Spotless (LF line endings) 17 | *.java text eol=lf 18 | *.xml text eol=lf 19 | *.yaml text eol=lf 20 | *.yml text eol=lf 21 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 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 | version: 2 19 | 20 | # Fix the Maven Central to the ASF repository to work around: https://github.com/dependabot/dependabot-core/issues/8329 21 | registries: 22 | maven-central: 23 | type: maven-repository 24 | url: https://repo.maven.apache.org/maven2 25 | 26 | updates: 27 | 28 | - package-ecosystem: maven 29 | directory: "/" 30 | schedule: 31 | interval: daily 32 | open-pull-requests-limit: 10 33 | registries: 34 | - maven-central 35 | ignore: 36 | # Keep Kotlin baseline 37 | - dependency-name: "org.jetbrains.kotlin:*" 38 | update-types: ["version-update:semver-major", "version-update:semver-minor"] 39 | # Keep Kotlin extensions baseline 40 | - dependency-name: "org.jetbrains.kotlinx:*" 41 | update-types: ["version-update:semver-major", "version-update:semver-minor"] 42 | # Keep Mockito baseline (5+ requires Java 11) 43 | - dependency-name: "org.mockito.kotlin:*" 44 | update-types: ["version-update:semver-major"] 45 | - dependency-name: "org.mockito:*" 46 | update-types: ["version-update:semver-major"] 47 | 48 | - package-ecosystem: github-actions 49 | directory: "/" 50 | schedule: 51 | interval: weekly 52 | 53 | - package-ecosystem: npm 54 | directory: "/" 55 | schedule: 56 | interval: daily 57 | -------------------------------------------------------------------------------- /.github/generate-email.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Licensed to the Apache Software Foundation (ASF) under one or more 4 | # contributor license agreements. See the NOTICE file distributed with 5 | # this work for additional information regarding copyright ownership. 6 | # The ASF licenses this file to you under the Apache License, Version 2.0 7 | # (the "License"); you may not use this file except in compliance with 8 | # the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | # Enable strict mode 20 | set -euo pipefail 21 | IFS=$'\n\t' 22 | 23 | SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd) 24 | 25 | stderr() { 26 | echo "$*" 1>&2 27 | } 28 | 29 | fail_for_invalid_args() { 30 | stderr "Invalid arguments!" 31 | stderr "Expected arguments: " 32 | exit 1 33 | } 34 | 35 | # Check arguments 36 | [ $# -ne 3 ] && fail_for_invalid_args 37 | 38 | # Constants 39 | PROJECT_NAME="Apache Log4j Kotlin API" 40 | PROJECT_ID="log4j-kotlin" 41 | PROJECT_SITE="https://logging.apache.org/log4j/kotlin" 42 | PROJECT_STAGING_SITE="${PROJECT_SITE/apache.org/staged.apache.org}" 43 | PROJECT_REPO="https://github.com/apache/logging-log4j-kotlin" 44 | PROJECT_VERSION="$2" 45 | COMMIT_ID="$3" 46 | PROJECT_DIST_URL="https://dist.apache.org/repos/dist/dev/logging/$PROJECT_ID/$PROJECT_VERSION" 47 | 48 | # Check release notes file 49 | RELEASE_NOTES_FILE="$SCRIPT_DIR/../target/generated-site/antora/modules/ROOT/pages/_release-notes/$PROJECT_VERSION.adoc" 50 | [ -f "$RELEASE_NOTES_FILE" ] || { 51 | stderr "Couldn't find release notes file: $RELEASE_NOTES_FILE" 52 | exit 1 53 | } 54 | 55 | dump_release_notes() { 56 | awk "f{print} /^Release date::/{f=1}" "$RELEASE_NOTES_FILE" \ 57 | | sed -r -e 's|'$PROJECT_REPO'/(issues|pull)/[0-9]+\[([0-9]+)\]|#\2|g 58 | s|https://github.com/([^/]+)/([^/]+)/(pull|issues)/([0-9]+)\[(\1/\2#\4)\]|\5|g' 59 | } 60 | 61 | case $1 in 62 | 63 | vote) 64 | cat < 75 | Signing key: 0x077e8893a6dcc33dd4a4d5b256e73ba9a0b592d0 76 | Review kit: https://s.apache.org/logging-parent-release-review-kit 77 | 78 | Please download, test, and cast your votes on this mailing list. 79 | 80 | [ ] +1, release the artifacts 81 | [ ] -1, don't release, because... 82 | 83 | This vote is open for 72 hours and will pass unless getting a 84 | net negative vote count. All votes are welcome and we encourage 85 | everyone to test the release, but only the Logging Services PMC 86 | votes are officially counted. At least 3 +1 votes and more 87 | positive than negative votes are required. 88 | 89 | == Release Notes 90 | EOF 91 | dump_release_notes 92 | ;; 93 | 94 | announce) 95 | cat <> "$GITHUB_OUTPUT" 81 | 82 | deploy-site-rel: 83 | needs: export-version 84 | uses: apache/logging-parent/.github/workflows/deploy-site-reusable.yaml@rel/12.0.0 85 | # Secrets for committing the generated site 86 | secrets: 87 | GPG_SECRET_KEY: ${{ secrets.LOGGING_GPG_SECRET_KEY }} 88 | # Write permissions for committing the generated site 89 | permissions: 90 | contents: write 91 | with: 92 | asf-yaml-content: | 93 | staging: 94 | profile: ~ 95 | whoami: ${{ github.ref_name }}-site-stg-out 96 | subdir: content/log4j/kotlin-${{ needs.export-version.outputs.version }} 97 | install-required: true 98 | target-branch: ${{ github.ref_name }}-site-stg-out 99 | -------------------------------------------------------------------------------- /.github/workflows/merge-dependabot.yaml: -------------------------------------------------------------------------------- 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 | name: merge-dependabot 19 | 20 | on: 21 | pull_request_target: 22 | paths-ignore: 23 | - "**.adoc" 24 | - "**.md" 25 | - "**.txt" 26 | 27 | permissions: read-all 28 | 29 | jobs: 30 | 31 | build: 32 | if: github.repository == 'apache/logging-log4j-kotlin' && github.event_name == 'pull_request_target' && github.actor == 'dependabot[bot]' 33 | uses: apache/logging-parent/.github/workflows/build-reusable.yaml@rel/11.3.0 34 | 35 | merge-dependabot: 36 | needs: build 37 | uses: apache/logging-parent/.github/workflows/merge-dependabot-reusable.yaml@rel/11.3.0 38 | permissions: 39 | contents: write # to push changelog commits 40 | pull-requests: write # to close the PR 41 | secrets: 42 | GPG_SECRET_KEY: ${{ secrets.LOGGING_GPG_SECRET_KEY }} # to sign commits 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 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 | # Maven 17 | target/ 18 | .flattened-pom.xml 19 | /.mvn/wrapper/maven-wrapper.jar 20 | # IDEA 21 | .idea/ 22 | *.iml 23 | *.iws 24 | # Eclipse 25 | .project 26 | .classpath 27 | .settings/ 28 | # Node 29 | node 30 | node_modules 31 | package-lock.json 32 | -------------------------------------------------------------------------------- /.java-version: -------------------------------------------------------------------------------- 1 | 17 2 | -------------------------------------------------------------------------------- /.mvn/jvm.config: -------------------------------------------------------------------------------- 1 | -Djava.awt.headless=true 2 | --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED 3 | --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED 4 | --add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED 5 | --add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED 6 | --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED 7 | --add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED 8 | --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED 9 | --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED 10 | --add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED 11 | --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED 12 | --add-opens java.base/sun.nio.ch=ALL-UNNAMED 13 | --add-opens java.base/java.io=ALL-UNNAMED 14 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/logging-log4j-kotlin/95c7ef296588189509a3a44486f8ebbfbd51e29b/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.4/apache-maven-3.9.4-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar 19 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Apache Log4j 2 | Copyright 2021-2023 Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 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 | https://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 | https://github.com/apache/logging-log4j-kotlin/actions[image:https://github.com/apache/logging-log4j-kotlin/actions/workflows/build.yaml/badge.svg[Actions Status]] 19 | https://search.maven.org/search?q=g:org.apache.logging.log4j%20a:log4j-api-kotlin-parent[image:https://img.shields.io/maven-central/v/org.apache.logging.log4j/log4j-api-kotlin-parent.svg[Maven Central]] 20 | https://www.apache.org/licenses/LICENSE-2.0.txt[image:https://img.shields.io/github/license/apache/logging-log4j-kotlin.svg[License]] 21 | 22 | Log4j Kotlin API provides a Kotlin-friendly interface to log against the https://logging.apache.org/log4j[Log4j] API. 23 | See https://logging.apache.org/log4j/kotlin[the project website] for more information. 24 | -------------------------------------------------------------------------------- /antora-playbook.yaml: -------------------------------------------------------------------------------- 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 | site: 19 | title: Apache Log4j Kotlin 20 | url: "https://logging.apache.org/log4j/kotlin" 21 | start_page: "ROOT::index.adoc" 22 | 23 | content: 24 | sources: 25 | - url: . 26 | branches: HEAD 27 | start_paths: 28 | - target/generated-site/antora 29 | edit_url: 30 | 31 | runtime: 32 | log: 33 | # Fail on warnings 34 | failure_level: warn 35 | 36 | asciidoc: 37 | extensions: 38 | - "@asciidoctor/tabs" 39 | 40 | ui: 41 | 42 | bundle: 43 | url: "https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable" 44 | snapshot: true 45 | 46 | # Template files: https://github.com/asciidoctor/asciidoctor-docs-ui/blob/main/src 47 | # Template variables: https://docs.antora.org/antora-ui-default/templates 48 | supplemental_files: 49 | 50 | # Add `@asciidoctor/tabs` extension styles 51 | - path: css/vendor/tabs.css 52 | contents: ./node_modules/@asciidoctor/tabs/dist/css/tabs.css 53 | 54 | # Add `@asciidoctor/tabs` extension scripts 55 | - path: js/vendor/tabs.js 56 | contents: ./node_modules/@asciidoctor/tabs/dist/js/tabs.js 57 | 58 | - path: partials/footer-scripts.hbs 59 | contents: | 60 | 61 | 62 | 63 | 64 | {{#if env.SITE_SEARCH_PROVIDER}} 65 | {{> search-scripts}} 66 | {{/if}} 67 | 68 | - path: partials/head-styles.hbs 69 | contents: | 70 | 71 | 72 | 73 | 74 | 103 | 104 | - path: partials/header-content.hbs 105 | contents: | 106 |
107 | 117 |
118 | 119 | - path: partials/footer-content.hbs 120 | contents: | 121 |
122 |

123 | Copyright © 1999-{{{year}}} The Apache Software Foundation. 124 | Licensed under the Apache Software License, Version 2.0. 125 | Please read our privacy policy. 126 |

127 |

128 | Apache, Log4j, and the Apache feather logo are trademarks or registered trademarks of The Apache Software Foundation. 129 | Oracle and Java are registered trademarks of Oracle and/or its affiliates. 130 | Other names may be trademarks of their respective owners. 131 |

132 |
133 | 134 | # Disable component version selector 135 | - path: partials/nav-explore.hbs 136 | contents: "" 137 | 138 | # Fix the `Edit this page` link 139 | - path: partials/edit-this-page.hbs 140 | contents: | 141 | 142 | -------------------------------------------------------------------------------- /log4j-api-kotlin-benchmark/README.adoc: -------------------------------------------------------------------------------- 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 | https://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 | This module contains JMH benchmarks for the Log4j Kotlin API. 19 | You can compile and run benchmarks as follows: 20 | 21 | [source,bash] 22 | ---- 23 | ./mvnw package 24 | java -jar log4j-api-kotlin-benchmark/target/benchmarks.jar 25 | ---- 26 | -------------------------------------------------------------------------------- /log4j-api-kotlin-benchmark/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 4.0.0 21 | 22 | 23 | org.apache.logging.log4j 24 | log4j-api-kotlin-parent 25 | ${revision} 26 | ../pom.xml 27 | 28 | 29 | log4j-api-kotlin-benchmark 30 | 31 | Apache Log4j Kotlin API benchmarks 32 | 33 | 34 | true 35 | true 36 | true 37 | true 38 | true 39 | benchmarks 40 | 41 | 42 | 43 | 44 | 45 | org.jetbrains.kotlin 46 | kotlin-stdlib 47 | 48 | 49 | 50 | org.jetbrains.kotlin 51 | kotlin-reflect 52 | ${kotlin.version} 53 | 54 | 55 | 56 | org.jetbrains.kotlinx 57 | kotlinx-coroutines-jdk8 58 | ${kotlinx.coroutines.version} 59 | 60 | 61 | 62 | org.apache.logging.log4j 63 | log4j-api-kotlin 64 | 65 | 66 | 67 | org.apache.logging.log4j 68 | log4j-core 69 | runtime 70 | 71 | 72 | 73 | org.openjdk.jmh 74 | jmh-core 75 | ${jmh.version} 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 91 | 92 | 93 | 94 | org.jetbrains.kotlin 95 | kotlin-maven-plugin 96 | 97 | 98 | compile 99 | 100 | compile 101 | 102 | process-sources 103 | 104 | 105 | ${project.basedir}/src/main/kotlin 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | org.codehaus.mojo 115 | exec-maven-plugin 116 | 117 | 118 | org.openjdk.jmh 119 | jmh-generator-bytecode 120 | ${jmh.version} 121 | 122 | 123 | 124 | 125 | generate-JMH-sources 126 | 127 | java 128 | 129 | process-resources 130 | 131 | true 132 | org.openjdk.jmh.generators.bytecode.JmhBytecodeGenerator 133 | 134 | 135 | ${project.build.directory}/classes 136 | 137 | ${project.build.directory}/generated-sources/jmh 138 | 139 | ${project.build.directory}/classes 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | org.codehaus.mojo 149 | build-helper-maven-plugin 150 | 151 | 152 | add-JMH-sources 153 | 154 | add-source 155 | 156 | process-resources 157 | 158 | 159 | ${project.build.directory}/generated-sources/jmh 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | org.apache.maven.plugins 169 | maven-compiler-plugin 170 | 171 | 172 | 173 | 174 | org.apache.maven.plugins 175 | maven-shade-plugin 176 | 177 | 178 | 179 | shade 180 | 181 | package 182 | 183 | false 184 | ${uberjar.name} 185 | 186 | 187 | org.openjdk.jmh.Main 188 | 189 | 190 | true 191 | 192 | 193 | 194 | 195 | 196 | 200 | *:* 201 | 202 | META-INF/*.SF 203 | META-INF/*.DSA 204 | META-INF/*.RSA 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | src/main/kotlin 216 | 217 | 218 | 219 | 220 | -------------------------------------------------------------------------------- /log4j-api-kotlin-benchmark/src/main/kotlin/org/apache/logging/log4j/kotlin/benchmark/LoggingBenchmark.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin.benchmark 18 | 19 | import org.apache.logging.log4j.LogManager 20 | import org.apache.logging.log4j.Logger 21 | import org.apache.logging.log4j.kotlin.Logging 22 | import org.apache.logging.log4j.kotlin.contextName 23 | import org.apache.logging.log4j.kotlin.logger 24 | import org.apache.logging.log4j.util.Supplier 25 | import org.openjdk.jmh.annotations.Benchmark 26 | import org.openjdk.jmh.annotations.BenchmarkMode 27 | import org.openjdk.jmh.annotations.Fork 28 | import org.openjdk.jmh.annotations.Measurement 29 | import org.openjdk.jmh.annotations.Mode 30 | import org.openjdk.jmh.annotations.OutputTimeUnit 31 | import org.openjdk.jmh.annotations.Warmup 32 | import java.util.concurrent.TimeUnit 33 | 34 | val LOGGER1 = logger("Bar") 35 | val LOGGER2 = logger(contextName {}) 36 | 37 | @BenchmarkMode(Mode.AverageTime) 38 | @OutputTimeUnit(TimeUnit.NANOSECONDS) 39 | @Fork(value = 2, jvmArgs = ["-Xms2G", "-Xmx2G"]) 40 | @Warmup(iterations = 3, time = 5) 41 | @Measurement(iterations = 5, time = 1) 42 | open class LoggingBenchmark { 43 | companion object: Logging { 44 | @JvmStatic 45 | val LOGGER3 = logger() 46 | val LOGGER4: Logger = LogManager.getLogger() 47 | val LOGGER5 = logger 48 | } 49 | 50 | @Benchmark 51 | fun topLevelNamedLoggerFunctional() { 52 | LOGGER1.info { "Test" } 53 | } 54 | 55 | @Benchmark 56 | fun topLevelNamedLoggerDirect() { 57 | LOGGER1.info("Test") 58 | } 59 | 60 | @Benchmark 61 | fun topLevelLoggerWithContextLookupFunctional() { 62 | LOGGER2.info {"Test" } 63 | } 64 | 65 | @Benchmark 66 | fun topLevelLoggerWithContextLookupDirect() { 67 | LOGGER2.info("Test") 68 | } 69 | 70 | @Benchmark 71 | fun companionObjectKotlinLoggerFunctional() { 72 | LOGGER3.info { "Test" } 73 | } 74 | 75 | @Benchmark 76 | fun companionObjectKotlinLoggerDirect() { 77 | LOGGER3.info("Test") 78 | } 79 | 80 | @Benchmark 81 | fun companionObjectLog4jLoggerFunctional() { 82 | LOGGER4.info(Supplier { "Test" }) 83 | } 84 | 85 | @Benchmark 86 | fun companionObjectLog4jLoggerDirect() { 87 | LOGGER4.info("Test") 88 | } 89 | 90 | @Benchmark 91 | fun companionObjectLookupInterfaceFunctional() { 92 | logger.info {"Test" } 93 | } 94 | 95 | @Benchmark 96 | fun companionObjectLookupInterfaceDirect() { 97 | logger.info("Test") 98 | } 99 | 100 | @Benchmark 101 | fun companionObjectExtensionPropertyFunctional() { 102 | LOGGER5.info { "Test" } 103 | } 104 | 105 | @Benchmark 106 | fun companionObjectExtensionPropertyDirect() { 107 | LOGGER5.info("Test") 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /log4j-api-kotlin-benchmark/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /log4j-api-kotlin-sample/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 4.0.0 21 | 22 | 23 | org.apache.logging.log4j 24 | log4j-api-kotlin-parent 25 | ${revision} 26 | ../pom.xml 27 | 28 | 29 | log4j-api-kotlin-sample 30 | 31 | Apache Log4j Kotlin API samples 32 | Sample usage of the Log4j Kotlin API 33 | 34 | 35 | true 36 | true 37 | true 38 | true 39 | 40 | 41 | 42 | 43 | 44 | org.jetbrains.kotlin 45 | kotlin-stdlib 46 | 47 | 48 | 49 | org.jetbrains.kotlin 50 | kotlin-reflect 51 | 52 | 53 | 54 | org.jetbrains.kotlinx 55 | kotlinx-coroutines-jdk8 56 | 57 | 58 | 59 | org.apache.logging.log4j 60 | log4j-api-kotlin 61 | 62 | 63 | 64 | org.apache.logging.log4j 65 | log4j-core 66 | runtime 67 | 68 | 69 | 70 | com.github.spotbugs 71 | spotbugs-annotations 72 | provided 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | org.codehaus.mojo 83 | exec-maven-plugin 84 | 85 | org.apache.logging.log4j.kotlin.sample.LoggingApp 86 | 87 | 88 | 89 | 90 | 91 | src/main/kotlin 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /log4j-api-kotlin-sample/src/main/kotlin/org/apache/logging/log4j/kotlin/sample/LoggingApp.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin.sample 18 | 19 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings 20 | import org.apache.logging.log4j.kotlin.logger 21 | import java.util.Random 22 | 23 | @SuppressFBWarnings("PREDICTABLE_RANDOM", "DMI_RANDOM_USED_ONLY_ONCE") 24 | object LoggingApp { 25 | val log = logger() 26 | 27 | @JvmStatic 28 | fun main(args: Array) { 29 | val s1 = "foo" 30 | val s2 = "bar" 31 | 32 | log.info { "Hello, world: $s1 $s2" } 33 | 34 | log.trace("Regular trace") 35 | 36 | log.runInTrace { 37 | log.info("Inside trace extension!") 38 | } 39 | 40 | log.runInTrace(log.traceEntry({ "param1" }, { "param2" })) { 41 | log.info("Inside trace extension with params suppliers!") 42 | } 43 | 44 | fun getKey(): Int = log.runInTrace { 45 | Random().nextInt(10) 46 | } 47 | 48 | @SuppressFBWarnings("NP_ALWAYS_NULL") 49 | fun getKeyError(): Int = log.runInTrace { 50 | throw Exception("Oops!") 51 | } 52 | 53 | log.info { "Key was ${getKey()}" } 54 | try { 55 | log.info { "Key was ${getKeyError()}" } 56 | } catch(e: Exception) { 57 | log.info { "Key threw ${e.message}" } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /log4j-api-kotlin-sample/src/main/kotlin/org/apache/logging/log4j/kotlin/sample/LoggingAppExtensionProperty.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin.sample 18 | 19 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings 20 | import org.apache.logging.log4j.kotlin.ContextMap 21 | import org.apache.logging.log4j.kotlin.logger 22 | import java.util.Random 23 | 24 | @SuppressFBWarnings("PREDICTABLE_RANDOM", "DMI_RANDOM_USED_ONLY_ONCE") 25 | object LoggingAppExtensionProperty { 26 | @JvmStatic 27 | fun main(args: Array) { 28 | val s1 = "foo" 29 | val s2 = "bar" 30 | 31 | ContextMap["key"] = "value" 32 | 33 | logger.info { "Hello, world: $s1 $s2" } 34 | 35 | ContextMap -= "key" 36 | 37 | logger.trace("Regular trace") 38 | 39 | logger.runInTrace { 40 | logger.info("Inside trace extension!") 41 | } 42 | 43 | logger.runInTrace(logger.traceEntry({ "param1" }, { "param2" })) { 44 | logger.info("Inside trace extension with params suppliers!") 45 | } 46 | 47 | fun getKey(): Int = logger.runInTrace { 48 | Random().nextInt(10) 49 | } 50 | 51 | @SuppressFBWarnings("NP_ALWAYS_NULL") 52 | fun getKeyError(): Int = logger.runInTrace { 53 | throw Exception("Oops!") 54 | } 55 | 56 | ContextMap += "foo" to "bar" 57 | ContextMap += "a" to "b" 58 | logger.info { "Key was ${getKey()}" } 59 | try { 60 | logger.info { "Key was ${getKeyError()}" } 61 | } catch(e: Exception) { 62 | ContextMap.clear() 63 | logger.info { "Key threw ${e.message}" } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /log4j-api-kotlin-sample/src/main/kotlin/org/apache/logging/log4j/kotlin/sample/LoggingAppMixin.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin.sample 18 | 19 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings 20 | import org.apache.logging.log4j.kotlin.Logging 21 | import java.util.Random 22 | 23 | @SuppressFBWarnings("PREDICTABLE_RANDOM", "DMI_RANDOM_USED_ONLY_ONCE") 24 | object LoggingAppMixin: Logging { 25 | @JvmStatic 26 | fun main(args: Array) { 27 | val s1 = "foo" 28 | val s2 = "bar" 29 | 30 | logger.info { "Hello, world: $s1 $s2" } 31 | 32 | logger.trace("Regular trace") 33 | 34 | logger.runInTrace { 35 | logger.info("Inside trace extension!") 36 | } 37 | 38 | logger.runInTrace(logger.traceEntry({ "param1" }, { "param2" })) { 39 | logger.info("Inside trace extension with params suppliers!") 40 | } 41 | 42 | fun getKey(): Int = logger.runInTrace { 43 | Random().nextInt(10) 44 | } 45 | 46 | @SuppressFBWarnings("NP_ALWAYS_NULL") 47 | fun getKeyError(): Int = logger.runInTrace { 48 | throw Exception("Oops!") 49 | } 50 | 51 | logger.info { "Key was ${getKey()}" } 52 | try { 53 | logger.info { "Key was ${getKeyError()}" } 54 | } catch(e: Exception) { 55 | logger.info { "Key threw ${e.message}" } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /log4j-api-kotlin-sample/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | 22 | %d %5p %c{1} %X %F:%L - %m%n 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /log4j-api-kotlin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 4.0.0 21 | 22 | 23 | org.apache.logging.log4j 24 | log4j-api-kotlin-parent 25 | ${revision} 26 | ../pom.xml 27 | 28 | 29 | log4j-api-kotlin 30 | 31 | Apache Log4j Kotlin API 32 | Kotlin wrapper for Log4j API 33 | 34 | 35 | 38 | 39 | 40 | kotlin.reflect.*;resolution:=optional, 41 | kotlinx.coroutines.*;resolution:=optional 42 | 43 | 44 | 45 | kotlin.stdlib;substitute="kotlin-stdlib", 46 | kotlin.reflect;substitute="kotlin-reflect", 47 | 48 | kotlinx.coroutines.core;substitute="kotlinx-coroutines-core-jvm";transitive=false, 49 | 50 | kotlin-stdlib-common;ignore=true 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.apache.logging.log4j 58 | log4j-api 59 | 60 | 61 | 62 | org.jetbrains.kotlin 63 | kotlin-stdlib 64 | provided 65 | 66 | 67 | 68 | org.jetbrains.kotlin 69 | kotlin-reflect 70 | provided 71 | 72 | 73 | 74 | org.jetbrains.kotlinx 75 | kotlinx-coroutines-jdk8 76 | ${kotlinx.coroutines.version} 77 | provided 78 | 79 | 80 | 81 | com.github.spotbugs 82 | spotbugs-annotations 83 | provided 84 | 85 | 86 | 87 | org.osgi 88 | osgi.annotation 89 | provided 90 | 91 | 92 | 93 | org.apache.logging.log4j 94 | log4j-api-test 95 | test 96 | 97 | 98 | junit 99 | junit 100 | 101 | 102 | 103 | 104 | 105 | org.apache.logging.log4j 106 | log4j-core 107 | test 108 | 109 | 110 | 111 | org.apache.logging.log4j 112 | log4j-core-test 113 | test 114 | 115 | 116 | junit 117 | junit 118 | 119 | 120 | 121 | 122 | 123 | org.jetbrains.kotlin 124 | kotlin-test-junit5 125 | test 126 | 127 | 128 | 129 | org.junit.jupiter 130 | junit-jupiter 131 | test 132 | 133 | 134 | 135 | org.mockito.kotlin 136 | mockito-kotlin 137 | test 138 | 139 | 140 | 141 | 142 | 143 | src/main/kotlin 144 | src/test/kotlin 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/ContextMap.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin 18 | 19 | import org.apache.logging.log4j.ThreadContext 20 | 21 | /** 22 | * Provides map-based storage for contextual data used in logging. This is provided as a facade around 23 | * [ThreadContext] map operations. 24 | * 25 | * @since 1.3.0 26 | */ 27 | object ContextMap { 28 | 29 | /** 30 | * Checks if the provided key is defined in the current context map. If the context map is disabled, 31 | * this will always return `false`. 32 | * 33 | * Example usage: 34 | * 35 | * ``` 36 | * if ("requestId" !in ContextMap) { 37 | * ContextMap["requestId"] = UUID.randomUUID().toString() 38 | * } 39 | * ``` 40 | * 41 | * @see ThreadContext.containsKey 42 | */ 43 | operator fun contains(key: String): Boolean = ThreadContext.containsKey(key) 44 | 45 | /** 46 | * Gets the value corresponding to the provided key from the current context map. If the context map 47 | * is disabled, this will always return `null`. 48 | * 49 | * Example usage: 50 | * 51 | * ``` 52 | * val value = ContextMap["key"] 53 | * ``` 54 | * 55 | * @see ThreadContext.get 56 | */ 57 | operator fun get(key: String): String? = ThreadContext.get(key) 58 | 59 | /** 60 | * Puts a value in the current context map for the given key. If the value is null, this is effectively 61 | * the same as removing the key. If the context map is disabled, this does nothing. 62 | * 63 | * Example usage: 64 | * 65 | * ``` 66 | * ContextMap["key"] = "value" 67 | * ``` 68 | * 69 | * @see ThreadContext.put 70 | */ 71 | operator fun set(key: String, value: String?) = ThreadContext.put(key, value) 72 | 73 | /** 74 | * Puts a key/value pair into the current context map. If the context map is disabled, this does nothing. 75 | * 76 | * Example usage: 77 | * 78 | * ``` 79 | * ContextMap += "key" to "value" 80 | * ``` 81 | * 82 | * @see ThreadContext.put 83 | */ 84 | operator fun plusAssign(pair: Pair) = ThreadContext.put(pair.first, pair.second) 85 | 86 | /** 87 | * Puts all the entries from the provided map into the current context map. If the context map is disabled, 88 | * this does nothing. 89 | * 90 | * Example usage: 91 | * 92 | * ``` 93 | * ContextMap += mapOf("key" to "value", "otherKey" to "anotherValue") 94 | * ``` 95 | * 96 | * @see ThreadContext.putAll 97 | */ 98 | operator fun plusAssign(map: Map) = ThreadContext.putAll(map) 99 | 100 | /** 101 | * Removes the provided key from the current context map. If the context map is disabled, this does nothing. 102 | * 103 | * Example usage: 104 | * 105 | * ``` 106 | * ContextMap -= "key" 107 | * ``` 108 | * 109 | * @see ThreadContext.remove 110 | */ 111 | operator fun minusAssign(key: String) = ThreadContext.remove(key) 112 | 113 | /** 114 | * Removes the provided keys from the current context map. If the context map is disabled, this does nothing. 115 | * 116 | * Example usage: 117 | * 118 | * ``` 119 | * ContextMap -= listOf("key1", "key2", "key3") 120 | * ``` 121 | * 122 | * @see ThreadContext.removeAll 123 | */ 124 | operator fun minusAssign(keys: Iterable) = ThreadContext.removeAll(keys) 125 | 126 | /** 127 | * Indicates if the current context map is empty. If the context map is disabled, this always returns `true`. 128 | * 129 | * @see ThreadContext.isEmpty 130 | */ 131 | val empty: Boolean 132 | get() = ThreadContext.isEmpty() 133 | 134 | /** 135 | * Provides an immutable view of the current context map. If the context map is disabled, this is always an 136 | * empty map. 137 | * 138 | * @see ThreadContext.getImmutableContext 139 | */ 140 | val view: Map 141 | get() = ThreadContext.getImmutableContext() 142 | 143 | /** 144 | * Provides a mutable copy of the current context map. If the context map is disabled, this is always a new 145 | * mutable map. 146 | * 147 | * @see ThreadContext.getContext 148 | */ 149 | fun copy(): MutableMap = ThreadContext.getContext() 150 | 151 | /** 152 | * Clears the current context map of all data. If the context map is disabled, this does nothing. 153 | * 154 | * @see ThreadContext.clearMap 155 | */ 156 | fun clear() = ThreadContext.clearMap() 157 | 158 | } 159 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/ContextStack.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin 18 | 19 | import org.apache.logging.log4j.ThreadContext 20 | import org.apache.logging.log4j.ThreadContext.ContextStack as ThreadContextStack 21 | 22 | /** 23 | * Provides stack-based storage for contextual data used in logging. This is provided as a facade around 24 | * [ThreadContext] stack operations. 25 | * 26 | * @since 1.3.0 27 | */ 28 | object ContextStack { 29 | 30 | /** 31 | * Returns the depth of the current context stack. If the context stack is disabled, this always returns `0`. 32 | * 33 | * @see ThreadContext.getDepth 34 | */ 35 | val depth: Int 36 | get() = ThreadContext.getDepth() 37 | 38 | /** 39 | * Indicates whether the current context stack is empty. If the context stack is disabled, this always returns `true`. 40 | */ 41 | val empty: Boolean 42 | get() = depth == 0 43 | 44 | /** 45 | * Returns an immutable view of the current context stack. If the context stack is disabled, this always returns 46 | * an empty stack. 47 | * 48 | * @see ThreadContext.getImmutableStack 49 | */ 50 | val view: ThreadContextStack 51 | get() = ThreadContext.getImmutableStack() 52 | 53 | /** 54 | * Returns a mutable copy of the current context stack. If the context stack is disabled, this always returns a new 55 | * stack. 56 | * 57 | * @see ThreadContext.cloneStack 58 | */ 59 | fun copy(): ThreadContextStack = ThreadContext.cloneStack() 60 | 61 | /** 62 | * Clears the current context stack of all its messages. If the context stack is disabled, this does nothing. 63 | * 64 | * @see ThreadContext.clearStack 65 | */ 66 | fun clear() = ThreadContext.clearStack() 67 | 68 | /** 69 | * Overwrites the current context stack using the provided collection of messages. If the context stack is disabled, 70 | * this does nothing. 71 | * 72 | * @see ThreadContext.setStack 73 | */ 74 | fun set(stack: Collection) = ThreadContext.setStack(stack) 75 | 76 | /** 77 | * Removes and returns the top-most message in the current context stack. If the context stack is empty or disabled, 78 | * this will always return an empty string. 79 | * 80 | * @see ThreadContext.pop 81 | */ 82 | fun pop(): String = ThreadContext.pop() 83 | 84 | /** 85 | * Returns without removing the top-most message in the current context stack. If the context stack is empty or 86 | * disabled, this will always return an empty string. 87 | * 88 | * @see ThreadContext.peek 89 | */ 90 | fun peek(): String = ThreadContext.peek() 91 | 92 | /** 93 | * Adds the provided message to the top of the current context stack. If the context stack is disabled, this does 94 | * nothing. 95 | * 96 | * @see ThreadContext.push 97 | */ 98 | fun push(message: String) = ThreadContext.push(message) 99 | 100 | /** 101 | * Adds a formatted message to the top of the current context stack using the provided parameterized message and 102 | * arguments. 103 | * 104 | * @see ThreadContext.push 105 | */ 106 | fun push(message: String, vararg args: Any?) = ThreadContext.push(message, args) 107 | 108 | /** 109 | * Trims the current context stack to at most the given depth. 110 | * 111 | * @see ThreadContext.trim 112 | */ 113 | fun trim(depth: Int) = ThreadContext.trim(depth) 114 | 115 | } 116 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/CoroutineThreadContext.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin 18 | 19 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings 20 | import kotlinx.coroutines.CoroutineScope 21 | import kotlinx.coroutines.ThreadContextElement 22 | import kotlinx.coroutines.withContext 23 | import org.apache.logging.log4j.ThreadContext 24 | import kotlin.coroutines.AbstractCoroutineContextElement 25 | import kotlin.coroutines.CoroutineContext 26 | 27 | /** 28 | * Snapshot of the current [ContextMap] and [ContextStack]. 29 | * 30 | * @param map immutable view of the current context map 31 | * @param stack immutable view of the current context stack 32 | * @see ContextMap.view 33 | * @see ContextStack.view 34 | */ 35 | @SuppressFBWarnings("EI_EXPOSE_REP", "EI_EXPOSE_REP2") 36 | data class ThreadContextData( 37 | val map: Map? = ContextMap.view, 38 | val stack: Collection? = ContextStack.view 39 | ) { 40 | operator fun plus(data: ThreadContextData) = ThreadContextData( 41 | map = this.map.orEmpty() + data.map.orEmpty(), 42 | stack = this.stack.orEmpty() + data.stack.orEmpty(), 43 | ) 44 | } 45 | 46 | /** 47 | * Log4j2 [ThreadContext] element for [CoroutineContext]. 48 | * 49 | * This is based on the SLF4J MDCContext maintained by Jetbrains: 50 | * https://github.com/Kotlin/kotlinx.coroutines/blob/master/integration/kotlinx-coroutines-slf4j/src/MDCContext.kt 51 | * 52 | * Example: 53 | * 54 | * ``` 55 | * ContextMap["kotlin"] = "rocks" // Put a value into the Thread context 56 | * 57 | * launch(CoroutineThreadContext()) { 58 | * logger.info { "..." } // The Thread context contains the mapping here 59 | * } 60 | * ``` 61 | * 62 | * Note, that you cannot update Thread context from inside of the coroutine simply 63 | * using [ThreadContext.put] or [ContextMap.set]. These updates are going to be lost on the next suspension and 64 | * reinstalled to the Thread context that was captured or explicitly specified in 65 | * [contextData] when this object was created on the next resumption. 66 | * Use `withContext(CoroutineThreadContext()) { ... }` to capture updated map of Thread keys and values 67 | * for the specified block of code. 68 | * 69 | * See [loggingContext] and [additionalLoggingContext] for convenience functions that make working with a 70 | * [CoroutineThreadContext] simpler. 71 | * 72 | * @param contextData the value of [Thread] context map and context stack. 73 | * Default value is the copy of the current thread's context map that is acquired via 74 | * [ContextMap.view] and [ContextStack.view]. 75 | */ 76 | class CoroutineThreadContext( 77 | /** 78 | * The value of [Thread] context map. 79 | */ 80 | val contextData: ThreadContextData = ThreadContextData() 81 | ) : ThreadContextElement, AbstractCoroutineContextElement(Key) { 82 | /** 83 | * Key of [ThreadContext] in [CoroutineContext]. 84 | */ 85 | companion object Key : CoroutineContext.Key 86 | 87 | /** @suppress */ 88 | @SuppressFBWarnings("EI_EXPOSE_REP") 89 | override fun updateThreadContext(context: CoroutineContext): ThreadContextData { 90 | val oldState = ThreadContextData(ContextMap.view, ContextStack.view) 91 | setCurrent(contextData) 92 | return oldState 93 | } 94 | 95 | /** @suppress */ 96 | @SuppressFBWarnings("EI_EXPOSE_REP") 97 | override fun restoreThreadContext(context: CoroutineContext, oldState: ThreadContextData) { 98 | setCurrent(oldState) 99 | } 100 | 101 | private fun setCurrent(contextData: ThreadContextData) { 102 | ContextMap.clear() 103 | ContextStack.clear() 104 | contextData.map?.let { ContextMap += it } 105 | contextData.stack?.let { ContextStack.set(it) } 106 | } 107 | } 108 | 109 | /** 110 | * Convenience function to obtain a [CoroutineThreadContext] with the given map and stack, which default 111 | * to no context. Any existing logging context in scope is ignored. 112 | * 113 | * Example: 114 | * 115 | * ``` 116 | * launch(loggingContext(mapOf("kotlin" to "rocks"))) { 117 | * logger.info { "..." } // The Thread context contains the mapping here 118 | * } 119 | * ``` 120 | */ 121 | fun loggingContext( 122 | map: Map? = null, 123 | stack: Collection? = null, 124 | ): CoroutineThreadContext = CoroutineThreadContext(ThreadContextData(map = map, stack = stack)) 125 | 126 | /** 127 | * Convenience function to obtain a [CoroutineThreadContext] that inherits the current context (if any), plus adds 128 | * the context from the given map and stack, which default to nothing. 129 | * 130 | * Example: 131 | * 132 | * ``` 133 | * launch(additionalLoggingContext(mapOf("kotlin" to "rocks"))) { 134 | * logger.info { "..." } // The Thread context contains the mapping plus whatever context was in scope at launch 135 | * } 136 | * ``` 137 | */ 138 | fun additionalLoggingContext( 139 | map: Map? = null, 140 | stack: Collection? = null, 141 | ): CoroutineThreadContext = CoroutineThreadContext(ThreadContextData() + ThreadContextData(map = map, stack = stack)) 142 | 143 | /** 144 | * Run the given block with the provided logging context, which default to no context. Any existing logging context 145 | * in scope is ignored. 146 | * 147 | * Example: 148 | * 149 | * ``` 150 | * withLoggingContext(mapOf("kotlin" to "rocks")) { 151 | * logger.info { "..." } // The Thread context contains the mapping 152 | * } 153 | * ``` 154 | */ 155 | suspend fun withLoggingContext( 156 | map: Map? = null, 157 | stack: Collection? = null, 158 | block: suspend CoroutineScope.() -> R, 159 | ): R = withContext(loggingContext(map, stack), block) 160 | 161 | /** 162 | * Run the given block with the provided additional logging context. The given context is added to any existing 163 | * logging context in scope. 164 | * 165 | * Example: 166 | * 167 | * ``` 168 | * withAdditionalLoggingContext(mapOf("kotlin" to "rocks")) { 169 | * logger.info { "..." } // The Thread context contains the mapping plus whatever context was in the scope previously 170 | * } 171 | * ``` 172 | */ 173 | suspend fun withAdditionalLoggingContext( 174 | map: Map? = null, 175 | stack: Collection? = null, 176 | block: suspend CoroutineScope.() -> R, 177 | ): R = withContext(additionalLoggingContext(map, stack), block) 178 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/Logging.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin 18 | 19 | /** 20 | * An interface-based "mixin" to easily add a log val to a class, named by the enclosing class. This allows 21 | * code like this: 22 | * 23 | * ``` 24 | * import org.apache.logging.log4j.kotlin.Logging 25 | * 26 | * class MyClass: Logging { 27 | * // use `logger` as necessary 28 | * } 29 | * 30 | * ``` 31 | * 32 | * Or declaring the interface on a companion object works just as well: 33 | * 34 | * ``` 35 | * import org.apache.logging.log4j.kotlin.logger 36 | * 37 | * class MyClass { 38 | * companion object: Logging 39 | * 40 | * // use `logger` as necessary 41 | * } 42 | * 43 | * ``` 44 | * 45 | * Note that this is significantly slower than creating a logger explicitly, as it requires a lookup of the 46 | * logger on each call via the property getter, since we cannot store any state in an interface. We attempt to 47 | * minimize the overhead of this by caching the loggers, but according to microbenchmarks, it is still about 48 | * 3.5 times slower than creating a logger once and using it (about 4.2 nanoseconds per call instead of 1.2 49 | * nanoseconds). 50 | */ 51 | interface Logging { 52 | /** 53 | * Provides a logger automatically named after the class that extends this mixin interface. 54 | */ 55 | val logger 56 | get() = cachedLoggerOf(this.javaClass) 57 | } 58 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/LoggingFactory.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin 18 | 19 | import org.apache.logging.log4j.LogManager 20 | import org.apache.logging.log4j.spi.ExtendedLogger 21 | import java.util.Collections 22 | import kotlin.reflect.full.companionObject 23 | 24 | /** 25 | * Logger instantiation by function. Use: `val log = logger()`. The logger will be named according to the 26 | * receiver of the function, which can be a class or object. An alternative for explicitly named loggers is 27 | * the [logger(String)] function. 28 | */ 29 | @Suppress("unused") 30 | inline fun T.logger() = loggerOf(T::class.java) 31 | 32 | /** 33 | * Provides a logger named after the receiver object's class. 34 | * 35 | * @since 1.3.0 36 | */ 37 | inline val T.logger: KotlinLogger 38 | get() = cachedLoggerOf(T::class.java) 39 | 40 | 41 | /** 42 | * Named logger instantiation by function. Use: `val log = logger('MyLoggerName')`. Generally one should 43 | * prefer the `logger` function to create automatically named loggers, but this is useful outside of objects, 44 | * such as in top-level functions. 45 | */ 46 | fun logger(name: String): KotlinLogger = KotlinLogger(LogManager.getContext(false).getLogger(name)) 47 | 48 | /** 49 | * Returns normalized context name. 50 | * * Execution within a class/object will return the full qualified class/object name, 51 | * in case of nested classes/objects the most outer class/object is used. 52 | * * Execution outside of any class/object will return the full qualified file name without `.kt suffix. 53 | * 54 | * Usage: `val LOG = logger(contextName {})` 55 | * @param context should always be `{}` 56 | * @return normalized context name 57 | */ 58 | fun contextName(context: () -> Unit): String = with(context::class.java.name) { 59 | when { 60 | contains("Kt$") -> substringBefore("Kt$") 61 | contains("$") -> substringBefore("$") 62 | else -> this 63 | } 64 | } 65 | 66 | /** 67 | * @see [logger] 68 | */ 69 | @Deprecated("Replaced with logger(name)", replaceWith = ReplaceWith("logger"), level = DeprecationLevel.WARNING) 70 | fun namedLogger(name: String): KotlinLogger = KotlinLogger(LogManager.getContext(false).getLogger(name)) 71 | 72 | fun loggerDelegateOf(ofClass: Class<*>): ExtendedLogger { 73 | return LogManager.getContext(ofClass.classLoader, false).getLogger(unwrapCompanionClass(ofClass).name) 74 | } 75 | 76 | fun loggerOf(ofClass: Class<*>): KotlinLogger { 77 | return KotlinLogger(loggerDelegateOf(ofClass)) 78 | } 79 | 80 | fun cachedLoggerOf(ofClass: Class<*>): KotlinLogger { 81 | return loggerCache.getOrPut(ofClass) { loggerOf(ofClass) } 82 | } 83 | 84 | // unwrap companion class to enclosing class given a Java Class 85 | private fun unwrapCompanionClass(ofClass: Class): Class<*> { 86 | return if (ofClass.enclosingClass?.kotlin?.companionObject?.java == ofClass) { 87 | ofClass.enclosingClass 88 | } else { 89 | ofClass 90 | } 91 | } 92 | 93 | private val loggerCache = Collections.synchronizedMap(SimpleLoggerLruCache(100)) 94 | 95 | /** 96 | * A very simple cache for loggers, to be used with [cachedLoggerOf]. 97 | */ 98 | private class SimpleLoggerLruCache(private val maxEntries: Int): LinkedHashMap, KotlinLogger>(maxEntries, 1f) { 99 | override fun removeEldestEntry(eldest: MutableMap.MutableEntry, KotlinLogger>): Boolean { 100 | return size > maxEntries 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/Suppliers.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin 18 | 19 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings 20 | import org.apache.logging.log4j.util.Supplier 21 | 22 | fun (() -> T).asLog4jSupplier(): Supplier = Supplier { invoke() } 23 | 24 | @SuppressFBWarnings("BC_BAD_CAST_TO_ABSTRACT_COLLECTION") 25 | fun (Array T>).asLog4jSuppliers(): Array> = map { it.asLog4jSupplier() }.toTypedArray() 26 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/package-info.java: -------------------------------------------------------------------------------- 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 | @Export 18 | package org.apache.logging.log4j.kotlin; 19 | 20 | import org.osgi.annotation.bundle.Export; 21 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerCompanionTest.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin 18 | 19 | import org.apache.logging.log4j.Level 20 | import org.apache.logging.log4j.kotlin.support.withListAppender 21 | import org.junit.jupiter.api.Test 22 | import kotlin.test.assertEquals 23 | 24 | class LoggerCompanionTest { 25 | companion object { 26 | val log = logger() 27 | } 28 | 29 | // note: using LoggerContextRule here to init the config does nothing as the initialization happens in the companion 30 | // log4j will fall back to the default config 31 | 32 | @Test 33 | fun `Logging from a function instantiation via companion logs the correct class name`() { 34 | val msg = "This is an error log." 35 | val msgs = withListAppender { _, _ -> 36 | log.error(msg) 37 | } 38 | 39 | assertEquals(1, msgs.size.toLong()) 40 | 41 | msgs.first().also { 42 | assertEquals(Level.ERROR, it.level) 43 | assertEquals(msg, it.message.format) 44 | assertEquals(LoggerCompanionTest::class.qualifiedName, it.loggerName) 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerContextNameTest.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin 18 | 19 | import org.junit.jupiter.api.Test 20 | import kotlin.test.assertEquals 21 | 22 | private val CONTEXT_NAME = contextName {} 23 | 24 | private class FooClass { 25 | val contextName = contextName {} 26 | 27 | companion object { 28 | val CONTEXT_NAME = contextName {} 29 | } 30 | } 31 | 32 | class LoggerContextNameTest { 33 | 34 | @Test 35 | fun `contextName on top level return full qualified file name`() { 36 | assertEquals("org.apache.logging.log4j.kotlin.LoggerContextNameTest", CONTEXT_NAME) 37 | } 38 | 39 | @Test 40 | fun `contextName within class return full qualified class name`() { 41 | assertEquals(FooClass::class.java.name, FooClass().contextName) 42 | } 43 | 44 | @Test 45 | fun `contextName within companion object return full qualified class name of enclosing class`() { 46 | assertEquals(FooClass::class.java.name, FooClass.CONTEXT_NAME) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerMixinCompanionExtendsTest.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin 18 | 19 | import org.apache.logging.log4j.Level 20 | import org.apache.logging.log4j.kotlin.support.withListAppender 21 | import org.junit.jupiter.api.Test 22 | import kotlin.test.assertEquals 23 | 24 | class LoggerMixinCompanionExtendsTest { 25 | 26 | companion object : Logging 27 | 28 | // note: using LoggerContextRule here to init the config does nothing as the initialization happens in the companion 29 | // log4j will fall back to the default config 30 | 31 | @Test 32 | fun `Logging from an interface mix-in via companion logs the correct class name`() { 33 | val msg = "This is an error log." 34 | val msgs = withListAppender { _, _ -> 35 | logger.error(msg) 36 | } 37 | 38 | assertEquals(1, msgs.size.toLong()) 39 | 40 | msgs.first().also { 41 | assertEquals(Level.ERROR, it.level) 42 | assertEquals(msg, it.message.format) 43 | assertEquals(LoggerMixinCompanionExtendsTest::class.qualifiedName, it.loggerName) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerMixinExtendsTest.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin 18 | 19 | import org.apache.logging.log4j.Level.ERROR 20 | import org.apache.logging.log4j.kotlin.support.withListAppender 21 | import org.junit.jupiter.api.Test 22 | import kotlin.test.assertEquals 23 | 24 | class LoggerMixinExtendsTest : Logging { 25 | 26 | @Test 27 | fun `Logging using an interface mix-in logs the correct class name`() { 28 | val msg = "This is an error log." 29 | val msgs = withListAppender { _, _ -> 30 | logger.error(msg) 31 | } 32 | 33 | assertEquals(1, msgs.size.toLong()) 34 | 35 | msgs.first().also { 36 | assertEquals(ERROR, it.level) 37 | assertEquals(msg, it.message.format) 38 | assertEquals(LoggerMixinExtendsTest::class.qualifiedName, it.loggerName) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerReceiversTest.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin 18 | 19 | import org.apache.logging.log4j.Level 20 | import org.apache.logging.log4j.kotlin.support.withListAppender 21 | import org.junit.jupiter.api.Test 22 | import kotlin.test.assertEquals 23 | 24 | class LoggerReceiversTest { 25 | 26 | @Test 27 | fun `Logging from a function instantiation via class receiver logs the correct class name`() { 28 | runTest(LoggerTest.logger()) 29 | } 30 | 31 | @Test 32 | fun `Logging from a function instantiation via object receiver logs the correct class name`() { 33 | runTest(LoggerTest().logger()) 34 | } 35 | 36 | private fun runTest(log: KotlinLogger) { 37 | val msg = "This is an error log." 38 | val msgs = withListAppender { _, _ -> 39 | log.error(msg) 40 | } 41 | 42 | assertEquals(1, msgs.size.toLong()) 43 | 44 | msgs.first().also { 45 | assertEquals(Level.ERROR, it.level) 46 | assertEquals(msg, it.message.format) 47 | assertEquals(LoggerTest::class.qualifiedName, it.loggerName) 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerTest.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin 18 | 19 | import org.apache.logging.log4j.Level 20 | import org.apache.logging.log4j.MarkerManager 21 | import org.apache.logging.log4j.message.DefaultFlowMessageFactory 22 | import org.apache.logging.log4j.message.EntryMessage 23 | import org.apache.logging.log4j.message.MessageFactory2 24 | import org.apache.logging.log4j.message.ParameterizedMessage 25 | import org.apache.logging.log4j.message.ParameterizedMessageFactory 26 | import org.apache.logging.log4j.spi.ExtendedLogger 27 | import org.junit.jupiter.api.Test 28 | import org.mockito.ArgumentMatchers.anyString 29 | import org.mockito.kotlin.KStubbing 30 | import org.mockito.kotlin.any 31 | import org.mockito.kotlin.argThat 32 | import org.mockito.kotlin.doReturn 33 | import org.mockito.kotlin.eq 34 | import org.mockito.kotlin.isNull 35 | import org.mockito.kotlin.mock 36 | import org.mockito.kotlin.times 37 | import org.mockito.kotlin.verify 38 | import org.mockito.kotlin.whenever 39 | import kotlin.test.assertEquals 40 | import kotlin.test.assertFailsWith 41 | 42 | data class Custom(val i: Int) 43 | 44 | interface Manager { 45 | fun fetchValue(): Int 46 | } 47 | 48 | typealias LoggerStubbingFn = KStubbing.() -> Unit 49 | 50 | class LoggerTest { 51 | companion object { 52 | val msg = ParameterizedMessage("msg {}", 17) 53 | val entryMsg = DefaultFlowMessageFactory().newEntryMessage(msg) 54 | val cseqMsg: CharSequence = StringBuilder().append("cseq msg") 55 | val objectMsg = Custom(17) 56 | val cause = RuntimeException("cause") 57 | val marker = MarkerManager.getMarker("marker") 58 | val result = "foo" 59 | val managerValue: Int = 4711 60 | } 61 | 62 | class Fixture(stubbing: LoggerStubbingFn? = null) { 63 | val mockLogger = mock { 64 | on { getMessageFactory() } doReturn ParameterizedMessageFactory() 65 | if(stubbing != null) stubbing() 66 | } 67 | 68 | val manager = mock { 69 | on { fetchValue() } doReturn managerValue 70 | } 71 | } 72 | 73 | fun withFixture(stubbing: LoggerStubbingFn?, level: Level, returning: Boolean, block: Fixture.(KotlinLogger) -> Unit): Fixture { 74 | val f = Fixture(stubbing) 75 | whenever(f.mockLogger.isEnabled(level)).thenReturn(returning) 76 | val logger = KotlinLogger(f.mockLogger) 77 | block(f, logger) 78 | return f 79 | } 80 | 81 | fun withLevelFixture(level: Level, returning: Boolean, block: Fixture.(KotlinLogger) -> Unit): Fixture { 82 | return withFixture({ 83 | on { isEnabled(level) } doReturn returning 84 | }, level, returning, block) 85 | } 86 | 87 | @Test 88 | fun `Logging works!`() { 89 | val f = withLevelFixture(Level.ERROR, true) { 90 | it.error(result) 91 | } 92 | verify(f.mockLogger).logIfEnabled(anyString(), eq(Level.ERROR), isNull(), eq(result), isNull()) 93 | } 94 | 95 | @Test 96 | fun `Level fatal enabled with String message`() { 97 | val f = withLevelFixture(Level.FATAL, true) { 98 | it.fatal("string msg with value: ${manager.fetchValue()}") 99 | } 100 | verify(f.mockLogger).logIfEnabled(anyString(), eq(Level.FATAL), isNull(), eq("string msg with value: $managerValue"), isNull()) 101 | verify(f.manager).fetchValue() 102 | } 103 | 104 | 105 | @Test 106 | fun `Level fatal disabled with String message`() { 107 | val f = withLevelFixture(Level.FATAL, false) { 108 | it.fatal("string msg with value: ${manager.fetchValue()}") 109 | } 110 | 111 | verify(f.mockLogger).logIfEnabled(anyString(), eq(Level.FATAL), isNull(), eq("string msg with value: $managerValue"), isNull()) 112 | // one might expect times(0), but we just delegate so times(1), we don't have any extra macro-based logic like the Scala api 113 | // use the lambda approach to not evaluate the message if the level is not enabled 114 | verify(f.manager, times(1)).fetchValue() 115 | } 116 | 117 | @Test 118 | fun `Lambda functions are evaluated if the level is high enough`() { 119 | var count = 0 120 | fun lamdaFun(): String { 121 | count++ 122 | return result 123 | } 124 | val log = logger() 125 | log.error { lamdaFun() } 126 | assertEquals(1, count) 127 | } 128 | 129 | @Test 130 | fun `Lambda functions are not evaluated if the level is low enough`() { 131 | var count = 0 132 | fun lamdaFun(): String { 133 | count++ 134 | return result 135 | } 136 | val log = logger() 137 | log.debug { lamdaFun() } 138 | assertEquals(0, count) 139 | } 140 | 141 | @Test 142 | fun `CharSequence messages are logged`() { 143 | val f = withLevelFixture(Level.INFO, true) { 144 | it.info(cseqMsg) 145 | } 146 | verify(f.mockLogger).logIfEnabled(anyString(), eq(Level.INFO), isNull(), eq(cseqMsg), isNull()) 147 | } 148 | 149 | @Test 150 | fun `Object messages are logged`() { 151 | val f = withLevelFixture(Level.INFO, true) { 152 | it.info(objectMsg) 153 | } 154 | verify(f.mockLogger).logIfEnabled(anyString(), eq(Level.INFO), isNull(), eq(objectMsg), isNull()) 155 | } 156 | 157 | @Test 158 | fun `Markers are logged`() { 159 | val f = withLevelFixture(Level.INFO, true) { 160 | it.info(marker, result) 161 | } 162 | verify(f.mockLogger).logIfEnabled(anyString(), eq(Level.INFO), eq(marker), eq(result), isNull()) 163 | } 164 | 165 | @Test 166 | fun `Run in trace with no result`() { 167 | var count = 0 168 | val f = withLevelFixture(Level.INFO, true) { 169 | it.runInTrace(entryMsg) { 170 | ++count 171 | Unit 172 | } 173 | } 174 | assertEquals(1, count) 175 | verify(f.mockLogger).traceExit(eq(entryMsg)) 176 | } 177 | 178 | @Test 179 | fun `Run in trace with result`() { 180 | var count = 0 181 | var returnedCount = 0 182 | val f = withLevelFixture(Level.INFO, true) { 183 | returnedCount = it.runInTrace(entryMsg) { 184 | ++count 185 | } 186 | } 187 | assertEquals(1, count) 188 | assertEquals(1, returnedCount) 189 | verify(f.mockLogger).traceEntry(eq(entryMsg)) 190 | verify(f.mockLogger).traceExit(eq(entryMsg), eq(1)) 191 | } 192 | 193 | @Test 194 | fun `Run in trace with Exception`() { 195 | var count = 0 196 | val f = withLevelFixture(Level.INFO, true) { 197 | assertFailsWith { 198 | it.runInTrace(entryMsg) { 199 | ++count 200 | throw cause 201 | } 202 | } 203 | } 204 | assertEquals(1, count) 205 | verify(f.mockLogger, times(1)).traceEntry(any()) 206 | verify(f.mockLogger, times(0)).traceExit(any()) 207 | verify(f.mockLogger).catching(argThat { message == "cause" }) 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/NamedLoggerTest.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin 18 | 19 | import org.apache.logging.log4j.Level 20 | import org.apache.logging.log4j.kotlin.support.withListAppender 21 | import org.junit.jupiter.api.Test 22 | import kotlin.test.assertEquals 23 | 24 | const val loggerName = "Foo" 25 | 26 | class NamedLoggerTest { 27 | 28 | val log = logger(loggerName) 29 | 30 | @Test 31 | fun `Logging from an explicitly named logger logs with the correct name`() { 32 | val msg = "This is an error log." 33 | val msgs = withListAppender { _, _ -> 34 | log.error(msg) 35 | } 36 | 37 | assertEquals(1, msgs.size.toLong()) 38 | 39 | msgs.first().also { 40 | assertEquals(Level.ERROR, it.level) 41 | assertEquals(msg, it.message.format) 42 | assertEquals(loggerName, it.loggerName) 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/support/LoggerTests.kt: -------------------------------------------------------------------------------- 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 | package org.apache.logging.log4j.kotlin.support 18 | 19 | import org.apache.logging.log4j.LogManager 20 | import org.apache.logging.log4j.core.LogEvent 21 | import org.apache.logging.log4j.core.Logger 22 | import org.apache.logging.log4j.core.test.appender.ListAppender 23 | 24 | fun rootLogger() = LogManager.getRootLogger() as Logger 25 | 26 | fun withListAppender(block: (rootLogger: Logger, appender: ListAppender) -> Unit): List { 27 | val appender = ListAppender("List").apply { start() } 28 | val root = rootLogger().apply { addAppender(appender) } 29 | 30 | try { 31 | block(root, appender) 32 | return appender.events 33 | } finally { 34 | appender.stop() 35 | root.removeAppender(appender) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Apache Maven Wrapper startup batch script, version 3.2.0 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | # e.g. to debug Maven itself, use 32 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | # ---------------------------------------------------------------------------- 35 | 36 | if [ -z "$MAVEN_SKIP_RC" ] ; then 37 | 38 | if [ -f /usr/local/etc/mavenrc ] ; then 39 | . /usr/local/etc/mavenrc 40 | fi 41 | 42 | if [ -f /etc/mavenrc ] ; then 43 | . /etc/mavenrc 44 | fi 45 | 46 | if [ -f "$HOME/.mavenrc" ] ; then 47 | . "$HOME/.mavenrc" 48 | fi 49 | 50 | fi 51 | 52 | # OS specific support. $var _must_ be set to either true or false. 53 | cygwin=false; 54 | darwin=false; 55 | mingw=false 56 | case "$(uname)" in 57 | CYGWIN*) cygwin=true ;; 58 | MINGW*) mingw=true;; 59 | Darwin*) darwin=true 60 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 61 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 62 | if [ -z "$JAVA_HOME" ]; then 63 | if [ -x "/usr/libexec/java_home" ]; then 64 | JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME 65 | else 66 | JAVA_HOME="/Library/Java/Home"; export JAVA_HOME 67 | fi 68 | fi 69 | ;; 70 | esac 71 | 72 | if [ -z "$JAVA_HOME" ] ; then 73 | if [ -r /etc/gentoo-release ] ; then 74 | JAVA_HOME=$(java-config --jre-home) 75 | fi 76 | fi 77 | 78 | # For Cygwin, ensure paths are in UNIX format before anything is touched 79 | if $cygwin ; then 80 | [ -n "$JAVA_HOME" ] && 81 | JAVA_HOME=$(cygpath --unix "$JAVA_HOME") 82 | [ -n "$CLASSPATH" ] && 83 | CLASSPATH=$(cygpath --path --unix "$CLASSPATH") 84 | fi 85 | 86 | # For Mingw, ensure paths are in UNIX format before anything is touched 87 | if $mingw ; then 88 | [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && 89 | JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" 90 | fi 91 | 92 | if [ -z "$JAVA_HOME" ]; then 93 | javaExecutable="$(which javac)" 94 | if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then 95 | # readlink(1) is not available as standard on Solaris 10. 96 | readLink=$(which readlink) 97 | if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then 98 | if $darwin ; then 99 | javaHome="$(dirname "\"$javaExecutable\"")" 100 | javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" 101 | else 102 | javaExecutable="$(readlink -f "\"$javaExecutable\"")" 103 | fi 104 | javaHome="$(dirname "\"$javaExecutable\"")" 105 | javaHome=$(expr "$javaHome" : '\(.*\)/bin') 106 | JAVA_HOME="$javaHome" 107 | export JAVA_HOME 108 | fi 109 | fi 110 | fi 111 | 112 | if [ -z "$JAVACMD" ] ; then 113 | if [ -n "$JAVA_HOME" ] ; then 114 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 115 | # IBM's JDK on AIX uses strange locations for the executables 116 | JAVACMD="$JAVA_HOME/jre/sh/java" 117 | else 118 | JAVACMD="$JAVA_HOME/bin/java" 119 | fi 120 | else 121 | JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" 122 | fi 123 | fi 124 | 125 | if [ ! -x "$JAVACMD" ] ; then 126 | echo "Error: JAVA_HOME is not defined correctly." >&2 127 | echo " We cannot execute $JAVACMD" >&2 128 | exit 1 129 | fi 130 | 131 | if [ -z "$JAVA_HOME" ] ; then 132 | echo "Warning: JAVA_HOME environment variable is not set." 133 | fi 134 | 135 | # traverses directory structure from process work directory to filesystem root 136 | # first directory with .mvn subdirectory is considered project base directory 137 | find_maven_basedir() { 138 | if [ -z "$1" ] 139 | then 140 | echo "Path not specified to find_maven_basedir" 141 | return 1 142 | fi 143 | 144 | basedir="$1" 145 | wdir="$1" 146 | while [ "$wdir" != '/' ] ; do 147 | if [ -d "$wdir"/.mvn ] ; then 148 | basedir=$wdir 149 | break 150 | fi 151 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 152 | if [ -d "${wdir}" ]; then 153 | wdir=$(cd "$wdir/.." || exit 1; pwd) 154 | fi 155 | # end of workaround 156 | done 157 | printf '%s' "$(cd "$basedir" || exit 1; pwd)" 158 | } 159 | 160 | # concatenates all lines of a file 161 | concat_lines() { 162 | if [ -f "$1" ]; then 163 | # Remove \r in case we run on Windows within Git Bash 164 | # and check out the repository with auto CRLF management 165 | # enabled. Otherwise, we may read lines that are delimited with 166 | # \r\n and produce $'-Xarg\r' rather than -Xarg due to word 167 | # splitting rules. 168 | tr -s '\r\n' ' ' < "$1" 169 | fi 170 | } 171 | 172 | log() { 173 | if [ "$MVNW_VERBOSE" = true ]; then 174 | printf '%s\n' "$1" 175 | fi 176 | } 177 | 178 | BASE_DIR=$(find_maven_basedir "$(dirname "$0")") 179 | if [ -z "$BASE_DIR" ]; then 180 | exit 1; 181 | fi 182 | 183 | MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR 184 | log "$MAVEN_PROJECTBASEDIR" 185 | 186 | ########################################################################################## 187 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 188 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 189 | ########################################################################################## 190 | wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" 191 | if [ -r "$wrapperJarPath" ]; then 192 | log "Found $wrapperJarPath" 193 | else 194 | log "Couldn't find $wrapperJarPath, downloading it ..." 195 | 196 | if [ -n "$MVNW_REPOURL" ]; then 197 | wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" 198 | else 199 | wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" 200 | fi 201 | while IFS="=" read -r key value; do 202 | # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) 203 | safeValue=$(echo "$value" | tr -d '\r') 204 | case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; 205 | esac 206 | done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" 207 | log "Downloading from: $wrapperUrl" 208 | 209 | if $cygwin; then 210 | wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") 211 | fi 212 | 213 | if command -v wget > /dev/null; then 214 | log "Found wget ... using wget" 215 | [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" 216 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 217 | wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 218 | else 219 | wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 220 | fi 221 | elif command -v curl > /dev/null; then 222 | log "Found curl ... using curl" 223 | [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" 224 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 225 | curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" 226 | else 227 | curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" 228 | fi 229 | else 230 | log "Falling back to using Java to download" 231 | javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" 232 | javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" 233 | # For Cygwin, switch paths to Windows format before running javac 234 | if $cygwin; then 235 | javaSource=$(cygpath --path --windows "$javaSource") 236 | javaClass=$(cygpath --path --windows "$javaClass") 237 | fi 238 | if [ -e "$javaSource" ]; then 239 | if [ ! -e "$javaClass" ]; then 240 | log " - Compiling MavenWrapperDownloader.java ..." 241 | ("$JAVA_HOME/bin/javac" "$javaSource") 242 | fi 243 | if [ -e "$javaClass" ]; then 244 | log " - Running MavenWrapperDownloader.java ..." 245 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" 246 | fi 247 | fi 248 | fi 249 | fi 250 | ########################################################################################## 251 | # End of extension 252 | ########################################################################################## 253 | 254 | # If specified, validate the SHA-256 sum of the Maven wrapper jar file 255 | wrapperSha256Sum="" 256 | while IFS="=" read -r key value; do 257 | case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; 258 | esac 259 | done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" 260 | if [ -n "$wrapperSha256Sum" ]; then 261 | wrapperSha256Result=false 262 | if command -v sha256sum > /dev/null; then 263 | if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then 264 | wrapperSha256Result=true 265 | fi 266 | elif command -v shasum > /dev/null; then 267 | if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then 268 | wrapperSha256Result=true 269 | fi 270 | else 271 | echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." 272 | echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." 273 | exit 1 274 | fi 275 | if [ $wrapperSha256Result = false ]; then 276 | echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 277 | echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 278 | echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 279 | exit 1 280 | fi 281 | fi 282 | 283 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 284 | 285 | # For Cygwin, switch paths to Windows format before running java 286 | if $cygwin; then 287 | [ -n "$JAVA_HOME" ] && 288 | JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") 289 | [ -n "$CLASSPATH" ] && 290 | CLASSPATH=$(cygpath --path --windows "$CLASSPATH") 291 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 292 | MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") 293 | fi 294 | 295 | # Provide a "standardized" way to retrieve the CLI args that will 296 | # work with both Windows and non-Windows executions. 297 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" 298 | export MAVEN_CMD_LINE_ARGS 299 | 300 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 301 | LINE_SEPARATOR=" 302 | " 303 | 304 | # shellcheck disable=SC2086 # safe args 305 | exec "$JAVACMD" \ 306 | $MAVEN_OPTS \ 307 | $MAVEN_DEBUG_OPTS \ 308 | "-Dline.separator=$LINE_SEPARATOR" \ 309 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 310 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 311 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 312 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Apache Maven Wrapper startup batch script, version 3.2.0 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 28 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 29 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 30 | @REM e.g. to debug Maven itself, use 31 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 32 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 33 | @REM ---------------------------------------------------------------------------- 34 | 35 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 36 | @echo off 37 | @REM set title of command window 38 | title %0 39 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 40 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 41 | 42 | @REM set %HOME% to equivalent of $HOME 43 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 44 | 45 | @REM Execute a user defined script before this one 46 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 47 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 48 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 49 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 50 | :skipRcPre 51 | 52 | @setlocal 53 | 54 | set ERROR_CODE=0 55 | 56 | @REM To isolate internal variables from possible post scripts, we use another setlocal 57 | @setlocal 58 | 59 | @REM ==== START VALIDATION ==== 60 | if not "%JAVA_HOME%" == "" goto OkJHome 61 | 62 | echo. 63 | echo Error: JAVA_HOME not found in your environment. >&2 64 | echo Please set the JAVA_HOME variable in your environment to match the >&2 65 | echo location of your Java installation. >&2 66 | echo. 67 | goto error 68 | 69 | :OkJHome 70 | if exist "%JAVA_HOME%\bin\java.exe" goto init 71 | 72 | echo. 73 | echo Error: JAVA_HOME is set to an invalid directory. >&2 74 | echo JAVA_HOME = "%JAVA_HOME%" >&2 75 | echo Please set the JAVA_HOME variable in your environment to match the >&2 76 | echo location of your Java installation. >&2 77 | echo. 78 | goto error 79 | 80 | @REM ==== END VALIDATION ==== 81 | 82 | :init 83 | 84 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 85 | @REM Fallback to current working directory if not found. 86 | 87 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 88 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 89 | 90 | set EXEC_DIR=%CD% 91 | set WDIR=%EXEC_DIR% 92 | :findBaseDir 93 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 94 | cd .. 95 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 96 | set WDIR=%CD% 97 | goto findBaseDir 98 | 99 | :baseDirFound 100 | set MAVEN_PROJECTBASEDIR=%WDIR% 101 | cd "%EXEC_DIR%" 102 | goto endDetectBaseDir 103 | 104 | :baseDirNotFound 105 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 106 | cd "%EXEC_DIR%" 107 | 108 | :endDetectBaseDir 109 | 110 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 111 | 112 | @setlocal EnableExtensions EnableDelayedExpansion 113 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 114 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 115 | 116 | :endReadAdditionalConfig 117 | 118 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" 123 | 124 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 125 | IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | if "%MVNW_VERBOSE%" == "true" ( 132 | echo Found %WRAPPER_JAR% 133 | ) 134 | ) else ( 135 | if not "%MVNW_REPOURL%" == "" ( 136 | SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" 137 | ) 138 | if "%MVNW_VERBOSE%" == "true" ( 139 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 140 | echo Downloading from: %WRAPPER_URL% 141 | ) 142 | 143 | powershell -Command "&{"^ 144 | "$webclient = new-object System.Net.WebClient;"^ 145 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 146 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 147 | "}"^ 148 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ 149 | "}" 150 | if "%MVNW_VERBOSE%" == "true" ( 151 | echo Finished downloading %WRAPPER_JAR% 152 | ) 153 | ) 154 | @REM End of extension 155 | 156 | @REM If specified, validate the SHA-256 sum of the Maven wrapper jar file 157 | SET WRAPPER_SHA_256_SUM="" 158 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 159 | IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B 160 | ) 161 | IF NOT %WRAPPER_SHA_256_SUM%=="" ( 162 | powershell -Command "&{"^ 163 | "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ 164 | "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ 165 | " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ 166 | " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ 167 | " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ 168 | " exit 1;"^ 169 | "}"^ 170 | "}" 171 | if ERRORLEVEL 1 goto error 172 | ) 173 | 174 | @REM Provide a "standardized" way to retrieve the CLI args that will 175 | @REM work with both Windows and non-Windows executions. 176 | set MAVEN_CMD_LINE_ARGS=%* 177 | @REM Do not remove the blank lines 178 | (set \n=^^^ 179 | 180 | ^ 181 | 182 | ) 183 | 184 | %MAVEN_JAVA_EXE% ^ 185 | %JVM_CONFIG_MAVEN_PROPS% ^ 186 | %MAVEN_OPTS% ^ 187 | %MAVEN_DEBUG_OPTS% ^ 188 | -Dline.separator=%\n% ^ 189 | -classpath %WRAPPER_JAR% ^ 190 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 191 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 192 | if ERRORLEVEL 1 goto error 193 | goto end 194 | 195 | :error 196 | set ERROR_CODE=1 197 | 198 | :end 199 | @endlocal & set ERROR_CODE=%ERROR_CODE% 200 | 201 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 202 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 203 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 204 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 205 | :skipRcPost 206 | 207 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 208 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 209 | 210 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 211 | 212 | cmd /C exit /B %ERROR_CODE% 213 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@antora/cli": "^3.2.0-alpha.4", 4 | "@antora/site-generator-default": "^3.2.0-alpha.4", 5 | "@asciidoctor/tabs": "^1.0.0-beta.6" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 4.0.0 21 | 22 | 23 | org.apache.logging 24 | logging-parent 25 | 11.3.0 26 | 27 | 28 | 29 | org.apache.logging.log4j 30 | log4j-api-kotlin-parent 31 | ${revision} 32 | pom 33 | 34 | Apache Log4j Kotlin API Parent 35 | Apache Log4j Kotlin API parent project 36 | 37 | https://logging.apache.org/log4j/kotlin/ 38 | 39 | 40 | 41 | 42 | ggregory 43 | Gary Gregory 44 | ggregory@apache.org 45 | https://www.garygregory.com 46 | The Apache Software Foundation 47 | https://www.apache.org/ 48 | 49 | PMC Member 50 | 51 | America/New_York 52 | 53 | 54 | 55 | mattsicker 56 | Matt Sicker 57 | mattsicker@apache.org 58 | Apple 59 | 60 | PMC Member 61 | 62 | America/Chicago 63 | 64 | 65 | 66 | rgoers 67 | Ralph Goers 68 | rgoers@apache.org 69 | Nextiva 70 | 71 | PMC Member 72 | 73 | America/Phoenix 74 | 75 | 76 | 77 | rgupta 78 | Raman Gupta 79 | rgupta@apache.org 80 | 81 | Committer 82 | 83 | Asia/Kolkata 84 | 85 | 86 | 87 | vy 88 | Volkan Yazıcı 89 | vy@apache.org 90 | 91 | PMC Chair 92 | 93 | Europe/Amsterdam 94 | 95 | 96 | 97 | 98 | 99 | log4j-api-kotlin 100 | log4j-api-kotlin-sample 101 | log4j-api-kotlin-benchmark 102 | 103 | 104 | 105 | scm:git:git@github.com:apache/logging-log4j-kotlin.git 106 | scm:git:git@github.com:apache/logging-log4j-kotlin.git 107 | HEAD 108 | https://github.com/apache/logging-log4j-kotlin 109 | 110 | 111 | 112 | GitHub Issues 113 | https://github.com/apache/logging-log4j-kotlin/issues 114 | 115 | 116 | 117 | GitHub Actions 118 | https://github.com/apache/logging-log4j-kotlin/actions 119 | 120 | 121 | 122 | https://logging.apache.org/download.html 123 | 124 | 125 | 126 | 127 | 128 | 1.6.0-SNAPSHOT 129 | 130 | 137 | 2024-08-03T16:55:56Z 138 | 139 | 140 | true 141 | true 142 | 143 | 144 | 1.37 145 | 5.12.0 146 | 2.24.3 147 | 2.0.21 148 | 1.6.4 149 | 4.1.0 150 | 151 | 152 | 3.6.0 153 | 3.4.1 154 | 3.6.0 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | org.apache.logging.log4j 163 | log4j-api-kotlin 164 | ${project.version} 165 | 166 | 167 | 168 | org.apache.logging.log4j 169 | log4j-bom 170 | ${log4j.version} 171 | pom 172 | import 173 | 174 | 175 | 176 | org.junit 177 | junit-bom 178 | ${junit.version} 179 | pom 180 | import 181 | 182 | 183 | 184 | org.jetbrains.kotlin 185 | kotlin-stdlib 186 | ${kotlin.version} 187 | 188 | 189 | 190 | org.jetbrains.kotlin 191 | kotlin-test-junit5 192 | ${kotlin.version} 193 | 194 | 195 | 196 | org.jetbrains.kotlin 197 | kotlin-reflect 198 | ${kotlin.version} 199 | 200 | 201 | 202 | org.jetbrains.kotlinx 203 | kotlinx-coroutines-jdk8 204 | ${kotlinx.coroutines.version} 205 | 206 | 207 | org.jetbrains.kotlin 208 | kotlin-stdlib 209 | 210 | 211 | org.jetbrains.kotlin 212 | kotlin-stdlib-common 213 | 214 | 215 | 216 | 217 | 218 | org.junit.jupiter 219 | junit-jupiter 220 | ${junit.version} 221 | 222 | 223 | 224 | org.mockito.kotlin 225 | mockito-kotlin 226 | ${mockito-kotlin.version} 227 | 228 | 229 | 230 | org.openjdk.jmh 231 | jmh-core 232 | ${jmh.version} 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | org.apache.maven.plugins 244 | maven-surefire-plugin 245 | ${surefire.version} 246 | 247 | 248 | 249 | org.jetbrains.kotlin 250 | kotlin-maven-plugin 251 | ${kotlin.version} 252 | 253 | 254 | 255 | org.apache.maven.plugins 256 | maven-shade-plugin 257 | ${maven-shade-plugin.version} 258 | 259 | 260 | 261 | org.codehaus.mojo 262 | build-helper-maven-plugin 263 | ${build-helper-maven-plugin.version} 264 | 265 | 266 | 267 | org.codehaus.mojo 268 | exec-maven-plugin 269 | ${exec-maven-plugin.version} 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | org.jetbrains.kotlin 278 | kotlin-maven-plugin 279 | 280 | 281 | compile 282 | 283 | compile 284 | 285 | compile 286 | 287 | 288 | test-compile 289 | 290 | test-compile 291 | 292 | test-compile 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | -------------------------------------------------------------------------------- /src/changelog/.1.x.x/.release-notes.adoc.ftl: -------------------------------------------------------------------------------- 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 | //// 19 | ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████ ██ 20 | ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ ██ 21 | ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ 22 | ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 23 | ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████ ██ 24 | 25 | IF THIS FILE DOESN'T HAVE A `.ftl` SUFFIX, IT IS AUTO-GENERATED, DO NOT EDIT IT! 26 | 27 | Version-specific release notes (`7.8.0.adoc`, etc.) are generated from `src/changelog/*/.release-notes.adoc.ftl`. 28 | Auto-generation happens during `generate-sources` phase of Maven. 29 | Hence, you must always 30 | 31 | 1. Find and edit the associated `.release-notes.adoc.ftl` 32 | 2. Run `./mvnw generate-sources` 33 | 3. Commit both `.release-notes.adoc.ftl` and the generated `7.8.0.adoc` 34 | //// 35 | 36 | [#release-notes-${release.version?replace("[^a-zA-Z0-9]", "-", "r")}] 37 | == ${release.version} 38 | 39 | <#if release.date?has_content>Release date:: ${release.date} 40 | 41 | List of changes for the upcoming release. 42 | 43 | <#include "../.changelog.adoc.ftl"> 44 | -------------------------------------------------------------------------------- /src/changelog/.1.x.x/update_apache_logging_parent.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `apache/logging-parent` to version `` 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/.1.x.x/update_apache_logging_parent_github_workflows_codeql_analysis_reusable_yaml_rel_11_3_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `apache/logging-parent/.github/workflows/codeql-analysis-reusable.yaml@rel/11.3.0` to version `12.0.0` 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/.1.x.x/update_apache_logging_parent_github_workflows_deploy_site_reusable_yaml_rel_11_3_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `apache/logging-parent/.github/workflows/deploy-site-reusable.yaml@rel/11.3.0` to version `12.0.0` 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/.1.x.x/update_org_apache_logging_log4j_log4j_bom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `org.apache.logging.log4j:log4j-bom` to version `2.24.3` 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/.1.x.x/update_org_apache_logging_logging_parent.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `org.apache.logging:logging-parent` to version `11.3.0` 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/.1.x.x/update_org_codehaus_mojo_exec_maven_plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `org.codehaus.mojo:exec-maven-plugin` to version `3.4.1` 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/.1.x.x/update_org_jetbrains_kotlin_kotlin_stdlib.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `org.jetbrains.kotlin:kotlin-stdlib` to version `2.0.21` 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/.1.x.x/update_org_junit_junit_bom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `org.junit:junit-bom` to version `5.12.0` 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/.changelog.adoc.ftl: -------------------------------------------------------------------------------- 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 | <#if entriesByType?size gt 0> 18 | <#list entriesByType as entryType, entries> 19 | 20 | [#release-notes-${release.version?replace("[^a-zA-Z0-9]", "-", "r")}-${entryType?lower_case}] 21 | === ${entryType?capitalize} 22 | 23 | <#list entries as entry> 24 | * ${entry.description.text?replace("\\s+", " ", "r")}<#if entry.issues?has_content> (<#list entry.issues as issue>${issue.link}[${issue.id}]<#if issue?has_next>, ) 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/changelog/.index.adoc.ftl: -------------------------------------------------------------------------------- 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 | //// 19 | ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████ ██ 20 | ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ ██ 21 | ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ 22 | ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 23 | ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████ ██ 24 | 25 | IF THIS FILE IS CALLED `index.adoc`, IT IS AUTO-GENERATED, DO NOT EDIT IT! 26 | 27 | Release notes `index.adoc` is generated from `src/changelog/.index.adoc.ftl`. 28 | Auto-generation happens during `generate-sources` phase of Maven. 29 | Hence, you must always 30 | 31 | 1. Edit `.index.adoc.ftl` 32 | 2. Run `./mvnw generate-sources` 33 | 3. Commit both `.index.adoc.ftl` and the generated `.index.adoc` 34 | //// 35 | 36 | // Release notes index does not look nice with a deep sectioning, override it: 37 | :page-toclevels: 1 38 | 39 | [#release-notes] 40 | = Release notes 41 | <#list releases as release><#if release.changelogEntryCount gt 0> 42 | 43 | include::_release-notes/${release.version}.adoc[] 44 | 45 | -------------------------------------------------------------------------------- /src/changelog/1.0.0/.release-notes.adoc.ftl: -------------------------------------------------------------------------------- 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 | //// 19 | ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████ ██ 20 | ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ ██ 21 | ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ 22 | ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 23 | ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████ ██ 24 | 25 | IF THIS FILE DOESN'T HAVE A `.ftl` SUFFIX, IT IS AUTO-GENERATED, DO NOT EDIT IT! 26 | 27 | Version-specific release notes (`7.8.0.adoc`, etc.) are generated from `src/changelog/*/.release-notes.adoc.ftl`. 28 | Auto-generation happens during `generate-sources` phase of Maven. 29 | Hence, you must always 30 | 31 | 1. Find and edit the associated `.release-notes.adoc.ftl` 32 | 2. Run `./mvnw generate-sources` 33 | 3. Commit both `.release-notes.adoc.ftl` and the generated `7.8.0.adoc` 34 | //// 35 | 36 | [#release-notes-${release.version?replace("[^a-zA-Z0-9]", "-", "r")}] 37 | == ${release.version} 38 | 39 | <#if release.date?has_content>Release date:: ${release.date} 40 | 41 | This is the first major release of the project. 42 | 43 | <#include "../.changelog.adoc.ftl"> 44 | -------------------------------------------------------------------------------- /src/changelog/1.0.0/.release.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /src/changelog/1.0.0/LOG4J2-1705_Create_Kotlin_API.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Create Kotlin wrapper API for Log4j 7 | 8 | -------------------------------------------------------------------------------- /src/changelog/1.0.0/LOG4J2-2432_Make_namedLogger_more_discoverable.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Make `namedLogger` more discoverable 7 | 8 | -------------------------------------------------------------------------------- /src/changelog/1.1.0/.release-notes.adoc.ftl: -------------------------------------------------------------------------------- 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 | //// 19 | ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████ ██ 20 | ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ ██ 21 | ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ 22 | ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 23 | ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████ ██ 24 | 25 | IF THIS FILE DOESN'T HAVE A `.ftl` SUFFIX, IT IS AUTO-GENERATED, DO NOT EDIT IT! 26 | 27 | Version-specific release notes (`7.8.0.adoc`, etc.) are generated from `src/changelog/*/.release-notes.adoc.ftl`. 28 | Auto-generation happens during `generate-sources` phase of Maven. 29 | Hence, you must always 30 | 31 | 1. Find and edit the associated `.release-notes.adoc.ftl` 32 | 2. Run `./mvnw generate-sources` 33 | 3. Commit both `.release-notes.adoc.ftl` and the generated `7.8.0.adoc` 34 | //// 35 | 36 | [#release-notes-${release.version?replace("[^a-zA-Z0-9]", "-", "r")}] 37 | == ${release.version} 38 | 39 | <#if release.date?has_content>Release date:: ${release.date} 40 | 41 | This is the 2nd minor release of the project. 42 | 43 | <#include "../.changelog.adoc.ftl"> 44 | -------------------------------------------------------------------------------- /src/changelog/1.1.0/.release.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /src/changelog/1.1.0/LOG4J2-2433_Support_MDCs_with_coroutines.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Support MDCs with Kotlin coroutines 7 | 8 | -------------------------------------------------------------------------------- /src/changelog/1.1.0/LOG4J2-2518_Support_suspend_functions.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Support suspend functions in supplier lambdas 7 | 8 | -------------------------------------------------------------------------------- /src/changelog/1.1.0/LOG4J2-2843_Update_Kotlin_baseline_to_1.3.72.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Update Kotlin baseline version to 1.3.72 7 | 8 | -------------------------------------------------------------------------------- /src/changelog/1.2.0/.release-notes.adoc.ftl: -------------------------------------------------------------------------------- 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 | //// 19 | ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████ ██ 20 | ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ ██ 21 | ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ 22 | ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 23 | ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████ ██ 24 | 25 | IF THIS FILE DOESN'T HAVE A `.ftl` SUFFIX, IT IS AUTO-GENERATED, DO NOT EDIT IT! 26 | 27 | Version-specific release notes (`7.8.0.adoc`, etc.) are generated from `src/changelog/*/.release-notes.adoc.ftl`. 28 | Auto-generation happens during `generate-sources` phase of Maven. 29 | Hence, you must always 30 | 31 | 1. Find and edit the associated `.release-notes.adoc.ftl` 32 | 2. Run `./mvnw generate-sources` 33 | 3. Commit both `.release-notes.adoc.ftl` and the generated `7.8.0.adoc` 34 | //// 35 | 36 | [#release-notes-${release.version?replace("[^a-zA-Z0-9]", "-", "r")}] 37 | == ${release.version} 38 | 39 | <#if release.date?has_content>Release date:: ${release.date} 40 | 41 | This is the 3rd minor release of the project. 42 | 43 | <#include "../.changelog.adoc.ftl"> 44 | -------------------------------------------------------------------------------- /src/changelog/1.2.0/.release.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /src/changelog/1.2.0/LOG4J2-3218_Update_Log4j_baseline.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Update Kotlin baseline version to `1.3.72` 7 | 8 | -------------------------------------------------------------------------------- /src/changelog/1.3.0/.release-notes.adoc.ftl: -------------------------------------------------------------------------------- 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 | //// 19 | ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████ ██ 20 | ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ ██ 21 | ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ 22 | ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 23 | ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████ ██ 24 | 25 | IF THIS FILE DOESN'T HAVE A `.ftl` SUFFIX, IT IS AUTO-GENERATED, DO NOT EDIT IT! 26 | 27 | Version-specific release notes (`7.8.0.adoc`, etc.) are generated from `src/changelog/*/.release-notes.adoc.ftl`. 28 | Auto-generation happens during `generate-sources` phase of Maven. 29 | Hence, you must always 30 | 31 | 1. Find and edit the associated `.release-notes.adoc.ftl` 32 | 2. Run `./mvnw generate-sources` 33 | 3. Commit both `.release-notes.adoc.ftl` and the generated `7.8.0.adoc` 34 | //// 35 | 36 | [#release-notes-${release.version?replace("[^a-zA-Z0-9]", "-", "r")}] 37 | == ${release.version} 38 | 39 | <#if release.date?has_content>Release date:: ${release.date} 40 | 41 | This minor release bumps the Kotlin baseline to 1.6.21 and contains various small improvements. 42 | 43 | <#include "../.changelog.adoc.ftl"> 44 | -------------------------------------------------------------------------------- /src/changelog/1.3.0/.release.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /src/changelog/1.3.0/28-Update_Log4j_baseline.xml: -------------------------------------------------------------------------------- 1 | 5 | Updated Log4j dependency to `2.20.0` 6 | 7 | -------------------------------------------------------------------------------- /src/changelog/1.3.0/29-Add_extension_property_for_logger.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Added an extension property for storing a cached logger 7 | 8 | -------------------------------------------------------------------------------- /src/changelog/1.3.0/30-Add_facade_APIs_for_ThreadContext.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Added facade APIs for manipulating the context map and stack 7 | 8 | -------------------------------------------------------------------------------- /src/changelog/1.3.0/32-Catching_Throwing.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Added missing `catching` and `throwing` API methods in `KotlinLogger` 7 | 8 | -------------------------------------------------------------------------------- /src/changelog/1.3.0/37-facelift.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Bumped `logging-parent` version to `10.1.1` and overhauled the entire project infrastructure to take advantage of its goodies 7 | 8 | -------------------------------------------------------------------------------- /src/changelog/1.3.0/JPMS.xml: -------------------------------------------------------------------------------- 1 | 5 | Added JPMS support and used `org.apache.logging.log4j.api.kotlin` for the module name (identical to OSGi `Bundle-SymbolicName`) of the `log4j-api-kotlin` artifact 6 | 7 | -------------------------------------------------------------------------------- /src/changelog/1.3.0/OSGi-Bundle-SymbolicName.xml: -------------------------------------------------------------------------------- 1 | 5 | Renamed OSGi `Bundle-SymbolicName` from `org.apache.logging.log4j.kotlin` to `org.apache.logging.log4j.api.kotlin` 6 | 7 | -------------------------------------------------------------------------------- /src/changelog/1.3.0/dokka.xml: -------------------------------------------------------------------------------- 1 | 5 | Stopped exporting KDoc to HTML 6 | 7 | -------------------------------------------------------------------------------- /src/changelog/1.3.0/junit5.xml: -------------------------------------------------------------------------------- 1 | 5 | Migrated tests to JUnit 5 6 | 7 | -------------------------------------------------------------------------------- /src/changelog/1.3.0/kotlin-baseline.xml: -------------------------------------------------------------------------------- 1 | 5 | Bumped Kotlin and Kotlin Extensions baseline to `1.6.21` and `1.6.4` respectively 6 | 7 | -------------------------------------------------------------------------------- /src/changelog/1.3.0/skip-deploy.xml: -------------------------------------------------------------------------------- 1 | 5 | Skipped deploying `log4j-api-kotlin-benchmark` and `log4j-api-kotlin-sample` modules 6 | 7 | -------------------------------------------------------------------------------- /src/changelog/1.4.0/.release-notes.adoc.ftl: -------------------------------------------------------------------------------- 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 | //// 19 | ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████ ██ 20 | ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ ██ 21 | ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ 22 | ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 23 | ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████ ██ 24 | 25 | IF THIS FILE DOESN'T HAVE A `.ftl` SUFFIX, IT IS AUTO-GENERATED, DO NOT EDIT IT! 26 | 27 | Version-specific release notes (`7.8.0.adoc`, etc.) are generated from `src/changelog/*/.release-notes.adoc.ftl`. 28 | Auto-generation happens during `generate-sources` phase of Maven. 29 | Hence, you must always 30 | 31 | 1. Find and edit the associated `.release-notes.adoc.ftl` 32 | 2. Run `./mvnw generate-sources` 33 | 3. Commit both `.release-notes.adoc.ftl` and the generated `7.8.0.adoc` 34 | //// 35 | 36 | [#release-notes-${release.version?replace("[^a-zA-Z0-9]", "-", "r")}] 37 | == ${release.version} 38 | 39 | <#if release.date?has_content>Release date:: ${release.date} 40 | 41 | This minor release fixes incorrect coroutine context map and stack. 42 | 43 | <#include "../.changelog.adoc.ftl"> 44 | -------------------------------------------------------------------------------- /src/changelog/1.4.0/.release.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /src/changelog/1.4.0/54-thread-context.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | Coroutine context is not cleared properly, only appended to 7 | 8 | -------------------------------------------------------------------------------- /src/changelog/1.4.0/add-sbom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | Started generating CycloneDX SBOM with the recent update of `logging-parent` to version `10.2.0` 7 | 8 | -------------------------------------------------------------------------------- /src/changelog/1.4.0/update-parent.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | Update `org.apache.logging:logging-parent` to version `10.2.0` 7 | 8 | -------------------------------------------------------------------------------- /src/changelog/1.4.0/update_org_apache_logging_log4j_log4j_bom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `org.apache.logging.log4j:log4j-bom` to version `2.22.0` 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/1.4.0/update_org_apache_logging_logging_parent.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `org.apache.logging:logging-parent` to version `10.5.0` 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/1.4.0/update_org_codehaus_mojo_build_helper_maven_plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `org.codehaus.mojo:build-helper-maven-plugin` to version `3.5.0` 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/1.4.0/update_org_codehaus_mojo_exec_maven_plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `org.codehaus.mojo:exec-maven-plugin` to version `3.1.1` 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/1.4.0/update_org_junit_junit_bom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `org.junit:junit-bom` to version `5.10.1` 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/1.5.0/.release-notes.adoc.ftl: -------------------------------------------------------------------------------- 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 | //// 19 | ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████ ██ 20 | ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ ██ 21 | ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ 22 | ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 23 | ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████ ██ 24 | 25 | IF THIS FILE DOESN'T HAVE A `.ftl` SUFFIX, IT IS AUTO-GENERATED, DO NOT EDIT IT! 26 | 27 | Version-specific release notes (`7.8.0.adoc`, etc.) are generated from `src/changelog/*/.release-notes.adoc.ftl`. 28 | Auto-generation happens during `generate-sources` phase of Maven. 29 | Hence, you must always 30 | 31 | 1. Find and edit the associated `.release-notes.adoc.ftl` 32 | 2. Run `./mvnw generate-sources` 33 | 3. Commit both `.release-notes.adoc.ftl` and the generated `7.8.0.adoc` 34 | //// 35 | 36 | [#release-notes-${release.version?replace("[^a-zA-Z0-9]", "-", "r")}] 37 | == ${release.version} 38 | 39 | <#if release.date?has_content>Release date:: ${release.date} 40 | 41 | This release contains improvements to Kotlin coroutine integration. 42 | 43 | <#include "../.changelog.adoc.ftl"> 44 | -------------------------------------------------------------------------------- /src/changelog/1.5.0/.release.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 22 | -------------------------------------------------------------------------------- /src/changelog/1.5.0/add-coroutine-context-convenience-functions.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Add convenience functions for managing logging context in coroutines 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/1.5.0/antora.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Migrate website to Antora 8 | 9 | -------------------------------------------------------------------------------- /src/changelog/1.5.0/update_org_apache_logging_log4j_log4j_bom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Update `org.apache.logging.log4j:log4j-bom` to version `2.23.1` 8 | 9 | -------------------------------------------------------------------------------- /src/site/antora/antora.tmpl.yml: -------------------------------------------------------------------------------- 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 | # 19 | # ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████ ██ 20 | # ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ ██ 21 | # ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ 22 | # ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 23 | # ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████ ██ 24 | # 25 | # THIS FILE IS USED AS A TEMPLATE TO AUTO-GENERATE `antora.yml`! 26 | # 27 | # The actual `antora.yml` that is used in `target/generated-site/antora` is auto-generated from `.antora.yml`. 28 | # Auto-generation happens during `pre-site` phase of Maven. 29 | # Hence, you must always 30 | # 31 | # 1. Edit `.antora.yml` 32 | # 2. Edit `antora.yml` to match the fields in `.antora.yml` and fill Maven property placeholders with dummy values 33 | # 34 | 35 | name: ROOT 36 | title: Home 37 | version: ~ 38 | start_page: index.adoc 39 | asciidoc: 40 | attributes: 41 | project-github-url: "${scm.url}" 42 | project-version: "${project.version}" 43 | project-name: "Log4j Kotlin API" 44 | project-id: "log4j-kotlin" 45 | java-target-version: "${maven.compiler.target}" 46 | java-compiler-version: "${minimalJavaBuildVersion}" 47 | kotlin-version: "${kotlin.version}" 48 | logging-services-url: "https://logging.apache.org" 49 | nav: 50 | - modules/ROOT/nav.adoc 51 | -------------------------------------------------------------------------------- /src/site/antora/antora.yml: -------------------------------------------------------------------------------- 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 | # 19 | # ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████ ██ 20 | # ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██ ██ 21 | # ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ 22 | # ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 23 | # ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████ ██ 24 | # 25 | # THIS FILE IS A STUB! 26 | # 27 | # The actual `antora.yml` that is used in `target/generated-site/antora` is auto-generated from `antora.tmpl.yml`. 28 | # Auto-generation happens during `pre-site` phase of Maven. 29 | # Hence, you must always 30 | # 31 | # 1. Edit `antora.tmpl.yml` 32 | # 2. Edit `antora.yml` to match the fields in `antora.tmpl.yml` and fill Maven property placeholders with dummy values 33 | # 34 | 35 | name: ROOT 36 | title: Home 37 | version: ~ 38 | start_page: index.adoc 39 | asciidoc: 40 | attributes: 41 | project-github-url: "https://github.com/apache/logging-log4j-kotlin" 42 | project-version: "1.5.0-SNAPSHOT" 43 | project-name: "Log4j Kotlin API" 44 | project-id: "log4j-kotlin" 45 | java-target-version: "8" 46 | java-compiler-version: "[17,18)" 47 | kotlin-version: "1.6.21" 48 | logging-services-url: "https://logging.apache.org" 49 | nav: 50 | - modules/ROOT/nav.adoc 51 | -------------------------------------------------------------------------------- /src/site/antora/modules/ROOT/nav.adoc: -------------------------------------------------------------------------------- 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 | * xref:development.adoc[] 19 | * xref:release-notes.adoc[] 20 | * {logging-services-url}/download.html[Download] 21 | * {logging-services-url}/support.html[Support] 22 | * {logging-services-url}/security.html[Security] 23 | -------------------------------------------------------------------------------- /src/site/antora/modules/ROOT/pages/development.adoc: -------------------------------------------------------------------------------- 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 | = Development 19 | 20 | {project-name} uses {project-github-url}[GitHub] for source code management. 21 | 22 | The project requires a Java compiler matching the `{java-compiler-version}` range and targets Java `{java-target-version}` and Kotlin `{kotlin-version}`. 23 | 24 | You can build and verify sources using: 25 | 26 | [source,bash] 27 | ---- 28 | ./mvnw verify 29 | ---- 30 | 31 | You can build and view the website as follows: 32 | 33 | [source,bash] 34 | ---- 35 | ./mvnw -N site 36 | ---- 37 | 38 | You can view the generated website with a browser by pointing it to `target/site` directory. 39 | 40 | [#release-instructions] 41 | == Release instructions 42 | 43 | {project-name} employs the CI/CD foundation provided by the {logging-services-url}/logging-parent[`logging-parent`]. 44 | You can simply use its release instructions. 45 | -------------------------------------------------------------------------------- /src/site/antora/modules/ROOT/pages/index.adoc: -------------------------------------------------------------------------------- 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-url: {logging-services-url}/log4j/2.x 19 | :log4j-api-url: {log4j-url}/manual/api-separation.html 20 | 21 | = Log4j Kotlin API 22 | 23 | {project-name} provides a Kotlin-friendly interface to log against {log4j-api-url}[the Log4j API]. 24 | The minimum requirements are Java `{java-target-version}` and Kotlin `{kotlin-version}`. 25 | 26 | [IMPORTANT] 27 | ==== 28 | This is just a logging API. 29 | Your application still needs to have a logging backend (e.g., {log4j-url}[Log4j]) configured. 30 | ==== 31 | 32 | [#dependencies] 33 | == Dependencies 34 | 35 | You need to have the `org.apache.logging.log4j:log4j-api-kotlin` dependency in your classpath: 36 | 37 | [source,xml,subs="+attributes"] 38 | ---- 39 | 40 | org.apache.logging.log4j 41 | log4j-api-kotlin 42 | {project-version} 43 | 44 | ---- 45 | 46 | Java module name and OSGi `Bundle-SymbolicName` are set to `org.apache.logging.log4j.api.kotlin`. 47 | 48 | [#create-loggers] 49 | == Creating loggers 50 | 51 | A `Logger` is the primary interface that users interact with Log4j Kotlin. 52 | You can create ``Logger``s particularly in two ways: 53 | 54 | * <> (*Recommended!*) 55 | * <> 56 | 57 | [#class-loggers] 58 | === [[usage]] Creating class loggers 59 | 60 | For most applications, we recommend you to create *a single logger instance per class definition* – not <>! 61 | This not only avoids creating an extra logger field for each instance, its access pattern transparently communicates the implementation: the `Logger` is statically bound to the class definition. 62 | You can create class loggers in one of following ways: 63 | 64 | [#create-companion-logger] 65 | ==== Creating a logger in the companion object 66 | 67 | This is the traditional approach to create class loggers. 68 | It also happens to be the most efficient one, since the logger lookup is performed once and its result is stored in the companion object shared by all instances of the class. 69 | 70 | [source,kotlin] 71 | ---- 72 | import org.apache.logging.log4j.kotlin.logger 73 | 74 | class DbTableService { 75 | 76 | companion object { 77 | 78 | private val LOGGER = logger() // <1> 79 | 80 | } 81 | 82 | fun truncateTable(tableName: String) { 83 | LOGGER.warn { "truncating table `${tableName}`" } 84 | db.truncate(tableName) 85 | } 86 | 87 | } 88 | ---- 89 | <1> Create a `Logger` associated with the static class definition that all instances of the class share 90 | 91 | [#extend-companion] 92 | ==== Extending companion object from `Logging` 93 | 94 | `Logging` interface contains a `logger` getter that you can use by extending the companion object from the `Logging` class: 95 | 96 | [source,kotlin] 97 | ---- 98 | import org.apache.logging.log4j.kotlin.Logging 99 | 100 | class DbTableService { 101 | 102 | companion object: Logging // <1> 103 | 104 | fun truncateTable(tableName: String) { 105 | logger.warn { "truncating table `${tableName}`" } 106 | db.truncate(tableName) 107 | } 108 | 109 | } 110 | ---- 111 | <1> Extending the companion object from `Logging` effectively creates a single `Logger` instance 112 | . Assigned to the `logger` field 113 | . Associated with the static class definition that all instances of the class share 114 | 115 | [NOTE] 116 | ==== 117 | This getter-based approach incurs an extra overhead (compared to <>) due to the logger lookup involved at runtime. 118 | ==== 119 | 120 | [#instance-loggers] 121 | === Creating instance loggers 122 | 123 | Even though we recommend you to <>, there might be occasions (most notably while {logging-services-url}/log4j/2.x/manual/webapp.html#log-separation[sharing classes in Jakarta EE environments]) necessitating loggers associated with each instance. 124 | You can achieve this as follows: 125 | 126 | [#create-instance-logger] 127 | ==== Creating a logger in the class 128 | 129 | This is the traditional approach to create instance loggers. 130 | It also happens to be the most efficient one, since the logger lookup is performed once and its result is stored in the instance field. 131 | 132 | [source,kotlin] 133 | ---- 134 | import org.apache.logging.log4j.kotlin.logger 135 | 136 | class DbTableService { 137 | 138 | private val logger = logger() // <1> 139 | 140 | fun truncateTable(tableName: String) { 141 | logger.warn { "truncating table `${tableName}`" } 142 | db.truncate(tableName) 143 | } 144 | 145 | } 146 | ---- 147 | <1> Create a `Logger` associated with the class instance 148 | 149 | [#extend-instance] 150 | ==== Extending the class from `Logging` 151 | 152 | `Logging` interface contains a `logger` getter that you can use by extending the class from `Logging`: 153 | 154 | [source,kotlin] 155 | ---- 156 | import org.apache.logging.log4j.kotlin.Logging 157 | 158 | class DbTableService: Logging { // <1> 159 | 160 | fun truncateTable(tableName: String) { 161 | logger.warn { "truncating table `${tableName}`" } 162 | db.truncate(tableName) 163 | } 164 | 165 | } 166 | ---- 167 | <1> Extending the class from `Logging` effectively creates a single `Logger` instance 168 | . Assigned to the `logger` field 169 | . Exclusively associated with the class instance (i.e., not shared among instances!) 170 | 171 | [NOTE] 172 | ==== 173 | This getter-based approach incurs an extra overhead (compared to <>) due to the logger lookup involved at runtime. 174 | ==== 175 | 176 | [#logger-extension] 177 | ==== Using `logger` extension property 178 | 179 | You can use the `logger` extension property to dynamically inject a logger at the spot: 180 | 181 | [source,kotlin] 182 | ---- 183 | import org.apache.logging.log4j.kotlin.logger 184 | 185 | class DbTableService { 186 | 187 | fun truncateTable(tableName: String) { 188 | logger.warn { "truncating table `${tableName}`" } // <1> 189 | db.truncate(tableName) 190 | } 191 | 192 | } 193 | ---- 194 | <1> `logger` will look up the associated `Logger` instance for the encapsulating class 195 | 196 | [NOTE] 197 | ==== 198 | This getter-based approach incurs an extra overhead (compared to <>) due to the logger lookup involved at runtime. 199 | ==== 200 | 201 | [#thread-context] 202 | == Thread context 203 | 204 | The `ThreadContext` API has two facade objects provided: `ContextMap` and `ContextStack`. 205 | 206 | [source,kotlin] 207 | ---- 208 | import org.apache.logging.log4j.kotlin.ContextMap 209 | import org.apache.logging.log4j.kotlin.ContextStack 210 | 211 | ContextMap["key"] = "value" 212 | assert(ContextMap["key"] == "value") 213 | assert("key" in ContextMap) 214 | 215 | ContextMap += "anotherKey" to "anotherValue" 216 | ContextMap -= "key" 217 | 218 | ContextStack.push("message") 219 | assert(!ContextStack.empty) 220 | assert(ContextStack.depth == 1) 221 | val message = ContextStack.peek() 222 | assert(message == ContextStack.pop()) 223 | assert(ContextStack.empty) 224 | ---- 225 | 226 | A `CoroutineThreadContext` context element is provided to integrate logging context with coroutines. 227 | 228 | We provide convenience functions `loggingContext` and `additionalLoggingContext` to create instances of `CoroutineThreadContext` with the appropriate context data. 229 | The result of these functions can be passed directly to coroutine builders to set the context for the coroutine. 230 | 231 | To set the context, ignoring any context currently in scope: 232 | 233 | [source,kotlin] 234 | ---- 235 | launch(loggingContext(mapOf("myKey" to "myValue"), listOf("test"))) { 236 | assertEquals("myValue", ContextMap["myKey"]) 237 | assertEquals("test", ContextStack.peek()) 238 | } 239 | ---- 240 | 241 | Or to preserve the existing context and add additional logging context: 242 | 243 | [source,kotlin] 244 | ---- 245 | launch(additionalLoggingContext(mapOf("myKey" to "myValue"), listOf("test"))) { 246 | assertEquals("myValue", ContextMap["myKey"]) 247 | assertEquals("test", ContextStack.peek()) 248 | } 249 | ---- 250 | 251 | Alternatively, to change the context without launching a new coroutine, the `withLoggingContext` and `withAdditionalLoggingContext` functions are provided: 252 | 253 | [source,kotlin] 254 | ---- 255 | withAdditionalLoggingContext(mapOf("myKey" to "myValue"), listOf("test")) { 256 | assertEquals("myValue", ContextMap["myKey"]) 257 | assertEquals("test", ContextStack.peek()) 258 | } 259 | ---- 260 | 261 | These functions are shorthand for `withContext(loggingContext(...))` or `withContext(additionalLoggingContext(...))`. 262 | 263 | [#params] 264 | == Parameter substitution 265 | 266 | Unlike Java, Kotlin provides native functionality for https://kotlinlang.org/docs/reference/basic-syntax.html#using-string-templates[string templates]. 267 | However, using a string template still incurs the message construction cost if the logger level is not enabled. 268 | To avoid this, prefer passing a lambda which won't be evaluated until necessary: 269 | 270 | [source,kotlin] 271 | ---- 272 | logger.debug { "Logging in user ${user.name} with birthday ${user.calcBirthday()}" } 273 | ---- 274 | 275 | [#logger-names] 276 | == Logger names 277 | 278 | Most logging implementations use a hierarchical scheme for matching logger names with logging configuration. 279 | 280 | In this scheme the logger name hierarchy is represented by `.` (dot) characters in the logger name, in a fashion very similar to the hierarchy used for Java/Kotlin package names. 281 | The `Logger` property added by the `Logging` interface follows this convention: the interface ensures the `Logger` is automatically named according to the class it is being used in. 282 | 283 | The value returned when calling the `logger()` extension method depends on the receiver of the extension. 284 | When called within an object, the receiver is `this` and therefore the logger will again be named according to the class it is being used in. 285 | However, a logger named via another class can be obtained as well: 286 | 287 | [source,kotlin] 288 | ---- 289 | import org.apache.logging.log4j.kotlin 290 | 291 | class MyClass: BaseClass { 292 | 293 | val logger = SomeOtherClass.logger() 294 | 295 | // ... 296 | 297 | } 298 | ---- 299 | 300 | [#explicitly-named-loggers] 301 | === Explicitly Named Loggers 302 | 303 | An explicitly-named logger may be obtained via the `logger` function that takes a `name` parameter: 304 | 305 | [source,kotlin] 306 | ---- 307 | import org.apache.logging.log4j.kotlin 308 | 309 | class MyClass: BaseClass { 310 | 311 | val logger = logger("MyCustomLoggerName") 312 | 313 | // ... 314 | 315 | } 316 | ---- 317 | 318 | This is also needed in scopes that do not have a `this` object, such as top-level functions. 319 | -------------------------------------------------------------------------------- /src/site/antora/modules/ROOT/pages/release-notes.adoc: -------------------------------------------------------------------------------- 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 | = Release notes 19 | 20 | This file is a stub. 21 | Its content will be auto-generated during build. 22 | --------------------------------------------------------------------------------