From cb8d5b40b97905a7aa5e92ebf8342245af598b17 Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Tue, 3 Oct 2023 12:13:45 +0300 Subject: [PATCH 01/19] Bump version --> `2.0.0-SNAPSHOT.226` --- license-report.md | 64 +++++++++++++++++++++++----------------------- pom.xml | 2 +- version.gradle.kts | 2 +- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/license-report.md b/license-report.md index 13ca43fd..be7a9f08 100644 --- a/license-report.md +++ b/license-report.md @@ -1,6 +1,6 @@ -# Dependencies of `io.spine:spine-fixtures:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-fixtures:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.github.ajalt. **Name** : colormath. **Version** : 1.2.0. @@ -592,12 +592,12 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:32 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:12 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-flogger-api:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-flogger-api:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -1350,12 +1350,12 @@ This report was generated on **Mon Oct 02 18:22:32 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:33 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:14 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-flogger-platform-generator:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-flogger-platform-generator:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -2113,12 +2113,12 @@ This report was generated on **Mon Oct 02 18:22:33 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:34 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:15 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-jvm-log4j2-backend-our-context:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-jvm-log4j2-backend-our-context:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -2883,12 +2883,12 @@ This report was generated on **Mon Oct 02 18:22:34 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:35 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:15 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-jvm-our-backend-grpc-context:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-jvm-our-backend-grpc-context:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -3649,12 +3649,12 @@ This report was generated on **Mon Oct 02 18:22:35 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:35 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:16 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-jvm-our-backend-our-context:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-jvm-our-backend-our-context:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -4411,12 +4411,12 @@ This report was generated on **Mon Oct 02 18:22:35 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:36 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:17 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-jvm-slf4j-jdk14-backend-our-context:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-jvm-slf4j-jdk14-backend-our-context:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -5185,12 +5185,12 @@ This report was generated on **Mon Oct 02 18:22:36 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:37 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:18 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-jvm-slf4j-reload4j-backend-our-context:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-jvm-slf4j-reload4j-backend-our-context:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -5963,12 +5963,12 @@ This report was generated on **Mon Oct 02 18:22:37 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:38 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:19 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-logging:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -6634,12 +6634,12 @@ This report was generated on **Mon Oct 02 18:22:38 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:38 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:19 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-backend:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-logging-backend:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -7404,12 +7404,12 @@ This report was generated on **Mon Oct 02 18:22:38 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:39 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:20 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-context:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-logging-context:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -8166,12 +8166,12 @@ This report was generated on **Mon Oct 02 18:22:39 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:40 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:21 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-fake-backend:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-logging-fake-backend:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.github.ajalt. **Name** : colormath. **Version** : 1.2.0. @@ -9100,12 +9100,12 @@ This report was generated on **Mon Oct 02 18:22:40 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:41 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:21 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-grpc-context:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-logging-grpc-context:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -9866,12 +9866,12 @@ This report was generated on **Mon Oct 02 18:22:41 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:41 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:22 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-log4j2-backend:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-logging-log4j2-backend:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -10648,12 +10648,12 @@ This report was generated on **Mon Oct 02 18:22:41 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:42 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:23 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-logging-smoke-test:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine:spine-logging-smoke-test:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -11464,12 +11464,12 @@ This report was generated on **Mon Oct 02 18:22:42 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:43 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Oct 03 12:06:24 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-testutil-logging:2.0.0-SNAPSHOT.225` +# Dependencies of `io.spine.tools:spine-testutil-logging:2.0.0-SNAPSHOT.226` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -12222,4 +12222,4 @@ This report was generated on **Mon Oct 02 18:22:43 EEST 2023** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Oct 02 18:22:43 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file +This report was generated on **Tue Oct 03 12:06:24 EEST 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2fe5fa6c..e5f90536 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ all modules and does not describe the project structure per-subproject. --> io.spine spine-logging -2.0.0-SNAPSHOT.225 +2.0.0-SNAPSHOT.226 2015 diff --git a/version.gradle.kts b/version.gradle.kts index f02129d8..7787ab90 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -24,4 +24,4 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -val versionToPublish: String by extra("2.0.0-SNAPSHOT.225") +val versionToPublish: String by extra("2.0.0-SNAPSHOT.226") From eaf5fd0f459ece71683125f1424e32dc93c8cd06 Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Tue, 3 Oct 2023 12:57:51 +0300 Subject: [PATCH 02/19] Update README to `logging-smoke-test` --- tests/logging-smoke-test/README.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/logging-smoke-test/README.md b/tests/logging-smoke-test/README.md index 4a9221cc..66b17a59 100644 --- a/tests/logging-smoke-test/README.md +++ b/tests/logging-smoke-test/README.md @@ -5,8 +5,25 @@ Spine modules to verify that the logging is actually happening. Only the most ba top-level functionality is tested. The main goal is to make sure that the logged messages don't go to some `/dev/null`. +Functionality of `spine-logging` is already covered with tests directly in the repository. +But due to the library complexity (i.e., KMP, runtime binding, classpath scan), it is still +better to have some real-life check-ups outside the development repository. + +### Applicability + As for now, it is only applicable to JVM modules. It is because testing involves usage -of Java Logging backend. This backend is default and allows to easier intercept the logged +of JUL-based backend. This backend is default and allows to easier intercept the logged text for further assertion. Take a look on `AbstractLoggingSmokeTest` for usage example. + +Please note, presence of `spine-logging` and `spine-logging-backend` is expected due to +Gradle configuration of `jvm-module` script plugin, which is applied to Spine JVM modules. + +`spine-logging` should be added manually if this smoke test is used in a module without +`jvm-module` configuration: + +``` +implementation("io.spine:spine-logging:$version") +runtimeOnly("io.spine:spine-logging-backend:$version) +``` From ff258d05cab81b47d0f9acd0eaee758e9b886353 Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Tue, 3 Oct 2023 13:49:54 +0300 Subject: [PATCH 03/19] Document the fake backend --- logging-fake-backend/README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 logging-fake-backend/README.md diff --git a/logging-fake-backend/README.md b/logging-fake-backend/README.md new file mode 100644 index 00000000..1db2ffd8 --- /dev/null +++ b/logging-fake-backend/README.md @@ -0,0 +1,29 @@ +## Spine Fake Backend + +**Note:** This is a specific backend implementation that is designed to be used in tests. + +Fake backend provides a backend factory that can switch the currently used backend +implementation in runtime. The logging facade doesn't provide such functionality. +Take a look on `DynamicBackendFactory` for details. + +This feature is quite helpful in tests. For example, to test a sole backend instance +or intercept the logged statements. + +### Logging interception + +For log statements interception, this module exposes `captureLogData { ... }` function. +This function uses `DynamicBackendFactory` to catch all `LogData` emitted during the execution +of the passed `action`. + +Usage example: + +```kotlin +val message = "logged text" +val logged = captureLogData { + val logger = LoggingFactory.forEnclosingClass() + logger.atInfo().log { message } +} +check(logged[0].literalArgument == message) +``` + +To use it, add this backend to `implementation` configuration instead of `runtimeOnly`. From faf063425782bf90879969591420d264c81b13cb Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Tue, 3 Oct 2023 14:21:46 +0300 Subject: [PATCH 04/19] Document `logging-context` --- logging-context/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 logging-context/README.md diff --git a/logging-context/README.md b/logging-context/README.md new file mode 100644 index 00000000..5dd31009 --- /dev/null +++ b/logging-context/README.md @@ -0,0 +1,16 @@ +## Standard logging context for JVM + +This module provides the basic implementation of the logging context. It is very +similar to that provided by gRPC logging context from Flogger. + +To use it, add `spine-logging-context` to `runtimeOnly` configuration: + +```kotlin +dependencies { + runtimeOnly("io.spine:spine-logging-context:$version") +} +``` + +Please note, this context is **not** used by default when no other contexts +are found on the classpath. `DefaultPlatform` uses `no-op` implementation when +the context is not passed explicitly. From 923f651b1e2ca2e491423e4054f2e472571100d7 Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Tue, 3 Oct 2023 15:03:45 +0300 Subject: [PATCH 05/19] Document `logging-backend` --- logging-backend/README.md | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 logging-backend/README.md diff --git a/logging-backend/README.md b/logging-backend/README.md new file mode 100644 index 00000000..cf8697c2 --- /dev/null +++ b/logging-backend/README.md @@ -0,0 +1,47 @@ +## Spine Logging Backend for JVM + +This module defines basic mechanisms that handle log statements produced by the logging facade. +They output logs to their destinations, depending on which backend implementation is used. + +### Default Platform + +`DefaultPlatform` is mostly responsible for runtime discovery of injectable services and +providing log site determination mechanism. + +The following services may be injected: + +| Service | Default | +|---|---| +| `BackendFactory` | `StdBackendFactory` | +| `ContextDataProvider` | `NoOpContextDataProvider` | +| `LogSites` | `SystemClock` | + +### Logger Backend and Factory + +`LoggerBackend` is a base interface for all backends. The corresponding factory is used +to create backend instances. `DefaultPlatform` looks for implementations of the factory +when discovering the present backends. + +Do the following to create a backend implementation: + +1. Add `spine-logging-backend` to `implementation` configuration. +2. Create your own backend implementation by extending `LoggerBackend`. +3. Create a factory for your backends by extending `BackendFactory`. +4. Expose the factory as a Java service, so that it can be loaded with `java.util.ServiceLoader`. + +### Standard JUL-based backend for JVM + +This module provides the default implementation of the logging backend for JVM. It uses +a built-in Java logging framework (also known as JUL or `java.util.logging`). Take a look +on `StdLoggerBackend` for details. + +To use it, add `spine-logging-backend` to `runtimeOnly` configuration: + +```kotlin +dependencies { + runtimeOnly("io.spine:spine-logging-backend:$version") +} +``` + +Please note, this backend is default for JVM. `DefaultPlatform` uses it when no other +backend implementation is passed. And this backend is **not** exposed as a Java service. From 4fb8df5fb96044d3416426e832d2053851dc6dc6 Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Tue, 3 Oct 2023 15:10:36 +0300 Subject: [PATCH 06/19] Rename `Module.md` to `README.md` --- logging/{Module.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename logging/{Module.md => README.md} (100%) diff --git a/logging/Module.md b/logging/README.md similarity index 100% rename from logging/Module.md rename to logging/README.md From 398fb0b30c0d57b8d8c58627a257d1db638877dd Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Tue, 3 Oct 2023 15:37:12 +0300 Subject: [PATCH 07/19] Configure visual guides for markdown documents --- .idea/codeStyles/Project.xml | 190 +---------------------------------- 1 file changed, 3 insertions(+), 187 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 23aec435..0dd7d871 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -85,195 +85,11 @@ + + - From f22aa6f271bebc5c503ad0c82bfb6b651b918a2a Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Tue, 3 Oct 2023 15:37:25 +0300 Subject: [PATCH 08/19] Update README to `logging` --- logging/README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/logging/README.md b/logging/README.md index 75f655f1..5e8c1792 100644 --- a/logging/README.md +++ b/logging/README.md @@ -1,8 +1,11 @@ -# Module Spine Logging +## Spine Logging -Spine Logging API and implementation are largely inspired by -[Google Flogger][flogger] logging API, and introduction of fluent logging API in -[SLF4J in v2.0.0][fluent-slf4j]. +This module contains multiplatform Spine Logging API. + +As for now, only JVM target is supported. + +API and implementation are largely inspired by [Google Flogger][flogger], +and the introduction of fluent logging API in [SLF4J in v2.0.0][fluent-slf4j]. [flogger]: https://google.github.io/flogger [fluent-slf4j]: https://www.slf4j.org/manual.html#fluent From aa307d2936ebd2ee811fa7a3d5ee7a0f397ff649 Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Tue, 3 Oct 2023 16:35:12 +0300 Subject: [PATCH 09/19] Update README to `flogger` --- flogger/README.md | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/flogger/README.md b/flogger/README.md index 64ed26de..49c81089 100644 --- a/flogger/README.md +++ b/flogger/README.md @@ -1,5 +1,39 @@ -# Google Flogger +## Google Flogger -This module contains Flogger [sources][flogger-github] built with Gradle. +This directory contains Flogger [modules][flogger-github] built with Gradle. + +### API + +Contains Flogger Logging API along with classes that handle log statements +before they are passed to a backend. + +Handling of a log statement includes controlling of rate limiting, attachment +of context and scope metadata, tracking log level restrictions, etc. + +### Platform Generator + +API declares `Platform`. It is a configuration point of the logging framework. +Implementations of this class should handle runtime discovery of injectable services +(backends, clocks and contexts), provide log site determination mechanism, +create backend instances, etc. + +Flogger is designed to be portable to different Java platforms. + +For example: + +- Server backends. +- [GWT apps][google-gwt]. +- Android. + +Potentially, we can have different `Platform` implementations for different +Java platforms. And this module was meant to generate different `PlatformProvider` +classes on different platforms. But as for now, it always generates a provider +that creates instances of `DefaultPlatform`. + +In the future, this module may be replaced with a single hard class. + +Take a look on issue [#67](https://github.com/SpineEventEngine/logging/issues/67) +for details. [flogger-github]: https://google.github.io/flogger +[google-gwt]: https://en.wikipedia.org/wiki/Google_Web_Toolkit From 081462d94c57f7bb06b0e005c5843452e2156905 Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Tue, 3 Oct 2023 17:31:34 +0300 Subject: [PATCH 10/19] Add entry point description --- logging/README.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/logging/README.md b/logging/README.md index 5e8c1792..324ac8f7 100644 --- a/logging/README.md +++ b/logging/README.md @@ -7,5 +7,46 @@ As for now, only JVM target is supported. API and implementation are largely inspired by [Google Flogger][flogger], and the introduction of fluent logging API in [SLF4J in v2.0.0][fluent-slf4j]. +### Entry points + +All logging operations are done with an instance of `io.spine.logging.Logger`. +To get a logger, one can use the following: + +1. Make the class that needs logging implement `WithLogging` interface. +2. Get a logger from `LoggingFactory`. + +The interface provides a default method `logger()` that returns a logger +for the implementing class or object: + +```kotlin +import io.spine.logging.WithLogging + +class Example : WithLogging { + fun doSomething() { + logger() // Call to the default method of `WithLogging`. + .atWarning() + .log { "..." } + } +} +``` + +`LoggingFactory` has two methods that return a logger for the enclosing class +and for the given `KClass`: + +```kotlin +import io.spine.logging.LoggingFactory + +class App { + private val logger1 = LoggingFactory.forEnclosingClass() + private val logger2 = LoggingFactory.loggerFor(this::class) + + fun doSomething() { + check(logger1 === logger2) // There is always one logger per class. + logger1.atWarning() + .log { "..." } + } +} +``` + [flogger]: https://google.github.io/flogger [fluent-slf4j]: https://www.slf4j.org/manual.html#fluent From 065ecf280daebddf683c8e6dd226f4f094b90d46 Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Tue, 3 Oct 2023 18:28:03 +0300 Subject: [PATCH 11/19] Update root README --- README.md | 115 +++++++++++++++++++++++++++++----------------- logging/README.md | 41 ----------------- 2 files changed, 74 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index 36a9cac6..4bea4bd2 100644 --- a/README.md +++ b/README.md @@ -5,33 +5,25 @@ # Spine Logging -Spine Logging is a versatile library designed for Kotlin and Java projects, with a potential -for multi-platform use. At present, we only provide a JVM implementation for Kotlin, -with a JavaScript implementation being our priority for future development. +Spine Logging is a versatile library designed for Kotlin and Java projects, +with a potential for multi-platform use. -This library draws inspiration from the logging API of [Google Flogger][flogger], and -the introduction of a fluent logging API in [SLF4J v2.0.0][fluent-slf4j]. +As for now, only JVM target is supported, with a JavaScript implementation +being our priority for future development. -## Current status: Experimental - -Please note that this library is still in the experimental phase of development and hence, -its API may undergo significant changes. As such, we advise using this library cautiously in -your projects until it has reached a stable release stage. - -## Logging backends +API and implementation are largely inspired by [Google Flogger][flogger], +and the introduction of fluent logging API in [SLF4J in v2.0.0][fluent-slf4j]. -Our JVM implementation currently employs Google Flogger. -Since Flogger is a logging facade, it requires a backend to perform the actual logging operations. -At the time of writing, the following Flogger backends are available: +## Current status: Experimental -* `com.google.flogger:flogger-system-backend:$floggerVersion` — utilizing `java.util.logging`. -* `com.google.flogger:flogger-log4j-backend:$floggerVersion` — utilizing Log4j. -* `com.google.flogger:flogger-log4j2-backend:$floggerVersion` — utilizing Log4j2. -* `com.google.flogger:flogger-slf4j-backend:$floggerVersion` — utilizing SLF4J (which is a facade itself!). +Please note that this library is still in the experimental phase of development, +and hence, its API may undergo significant changes. As such, we advise using +this library cautiously in your projects until it has reached a stable +release stage. -### How to Use `java.util.logging` as a backend +## Simple examples -To use `java.util.logging` in your project, add the following dependency: +To start logging, at least the following dependencies are needed: ```kotlin dependencies { @@ -39,45 +31,87 @@ dependencies { runtimeOnly("io.spine:spine-logging-backend:$version") } ``` -The second dependency replaces the default Flogger backend with a backend that resolves issues -with using LogLevelMap in the project. -### Utilizing other backends +The default logging backend outputs all logged statements to the console. + +All logging operations are done with an instance of `io.spine.logging.Logger`. +To get a logger, one can use the following: -If you prefer a backend other than java.util.logging, add dependencies that include a `runtimeOnly` -dependency for your chosen logging backend. For instance: +1. Make a logging class implement `WithLogging` interface. +2. Get a logger from `LoggingFactory`. + +The interface provides a default method `logger()` that returns a logger +for the implementing class or object: ```kotlin -dependencies { - implementation("io.spine:spine-logging:$version") - runtimeOnly("com.google.flogger:flogger-log4j2-backend:$floggerVersion") +import io.spine.logging.WithLogging + +class Example : WithLogging { + fun doSomething() { + logger() // Call to the default method of `WithLogging`. + .atWarning() + .log { "..." } + } } ``` -For SLF4J as a backend, your dependencies should also include a backend for SLF4J. For example: +`LoggingFactory` has two methods that return a logger for the enclosing class +and for the given `KClass`: + +```kotlin +import io.spine.logging.LoggingFactory + +class App { + private val logger1 = LoggingFactory.forEnclosingClass() + private val logger2 = LoggingFactory.loggerFor(this::class) + + fun doSomething() { + check(logger1 === logger2) // There is always one logger per class. + logger1.atWarning() + .log { "..." } + } +} +``` + +## Logging backends + +Please note, as for now, all backend implementations are for JVM. + +The following backends are available: + +* `io.spine:spine-logging-backend` (the default JUL-based backend). +* `io.spine:spine-logging-log4j2-backend`. + +Put a needed backend to `runtimeOnly` configuration, and the logging library +will discover it in the runtime. + +An example usage of Log4j2 backend: ```kotlin dependencies { implementation("io.spine:spine-logging:$version") - runtimeOnly("com.google.flogger:flogger-slf4j-backend:$floggerVersion") - runtimeOnly("org.slf4j:slf4j-reload4j:$slf4jVersion") + runtimeOnly("io.spine:spine-logging-log4j2-backend:$version") } ``` -## Logging context +Please note, only one backend implementation should be present in the runtime. +Two or more backends will cause an exception because the logging framework +will not be able to understand, which one should be used. + +## Logging contexts -A logging context refers to a set of attributes that are attached to all log records while -a context is installed. For instance, you can attach a user ID to all log records for -the current request. +A logging context refers to a set of attributes that are attached to all log +records while a context is installed. For instance, you can attach a user ID +to all log records for the current request. -The default implementation provides a no-op context. To use a logging context, a `runtimeOnly` -dependency for a context implementation should be added along with the above dependencies. +The default implementation provides a no-op context. To use a logging context, +a `runtimeOnly` dependency for a context implementation should be added along +with the mentioned above dependencies. If your project does not use gRPC, use the following dependency: ```kotlin dependencies { - //... rutimeOnly("io.spine:spine-logging-context:$version") } ``` @@ -86,8 +120,7 @@ If your project does use gRPC, add the following dependency: ```kotlin dependencies { - //... - rutimeOnly("com.google.flogger:flogger-grpc-context:$floggerVersion") + rutimeOnly("io.spine:spine-logging-grpc-context:$version") } ``` diff --git a/logging/README.md b/logging/README.md index 324ac8f7..5e8c1792 100644 --- a/logging/README.md +++ b/logging/README.md @@ -7,46 +7,5 @@ As for now, only JVM target is supported. API and implementation are largely inspired by [Google Flogger][flogger], and the introduction of fluent logging API in [SLF4J in v2.0.0][fluent-slf4j]. -### Entry points - -All logging operations are done with an instance of `io.spine.logging.Logger`. -To get a logger, one can use the following: - -1. Make the class that needs logging implement `WithLogging` interface. -2. Get a logger from `LoggingFactory`. - -The interface provides a default method `logger()` that returns a logger -for the implementing class or object: - -```kotlin -import io.spine.logging.WithLogging - -class Example : WithLogging { - fun doSomething() { - logger() // Call to the default method of `WithLogging`. - .atWarning() - .log { "..." } - } -} -``` - -`LoggingFactory` has two methods that return a logger for the enclosing class -and for the given `KClass`: - -```kotlin -import io.spine.logging.LoggingFactory - -class App { - private val logger1 = LoggingFactory.forEnclosingClass() - private val logger2 = LoggingFactory.loggerFor(this::class) - - fun doSomething() { - check(logger1 === logger2) // There is always one logger per class. - logger1.atWarning() - .log { "..." } - } -} -``` - [flogger]: https://google.github.io/flogger [fluent-slf4j]: https://www.slf4j.org/manual.html#fluent From dc10dd6cba974642c144ef11157905751dc3494c Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Tue, 3 Oct 2023 18:33:47 +0300 Subject: [PATCH 12/19] Proofread text --- README.md | 13 ++++++++----- logging-backend/README.md | 38 +++++++++++++++++++++----------------- logging-context/README.md | 2 +- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 4bea4bd2..0f55c484 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ and hence, its API may undergo significant changes. As such, we advise using this library cautiously in your projects until it has reached a stable release stage. -## Simple examples +## Simple example To start logging, at least the following dependencies are needed: @@ -75,14 +75,17 @@ class App { ## Logging backends -Please note, as for now, all backend implementations are for JVM. +A logging backend handles an actual output of the logged statement. +`LogRecord` may be printed to the console, be written to a file or sent by +the network to some log-aggregating service. It all is up to a chosen backend +and its configuration. The following backends are available: -* `io.spine:spine-logging-backend` (the default JUL-based backend). -* `io.spine:spine-logging-log4j2-backend`. +* `io.spine:spine-logging-backend` – the default JUL-based backend. +* `io.spine:spine-logging-log4j2-backend` – Log4j2 backend. -Put a needed backend to `runtimeOnly` configuration, and the logging library +Put a chosen backend to `runtimeOnly` configuration, and the logging library will discover it in the runtime. An example usage of Log4j2 backend: diff --git a/logging-backend/README.md b/logging-backend/README.md index cf8697c2..50bc9c28 100644 --- a/logging-backend/README.md +++ b/logging-backend/README.md @@ -1,38 +1,41 @@ ## Spine Logging Backend for JVM -This module defines basic mechanisms that handle log statements produced by the logging facade. -They output logs to their destinations, depending on which backend implementation is used. +This module defines basic mechanisms that handle log records produced by +the logging facade. ### Default Platform -`DefaultPlatform` is mostly responsible for runtime discovery of injectable services and -providing log site determination mechanism. +`DefaultPlatform` is mostly responsible for runtime discovery of injectable +services and providing log site determination mechanism. It uses `java.util.ServiceLoader` +to find available service implementations, and stack trace analysis to determine +a log site. The following services may be injected: -| Service | Default | -|---|---| -| `BackendFactory` | `StdBackendFactory` | +| Service | Default | +|-----------------------|---| +| `BackendFactory` | `StdBackendFactory` | | `ContextDataProvider` | `NoOpContextDataProvider` | -| `LogSites` | `SystemClock` | +| `Clock` | `SystemClock` | ### Logger Backend and Factory -`LoggerBackend` is a base interface for all backends. The corresponding factory is used -to create backend instances. `DefaultPlatform` looks for implementations of the factory -when discovering the present backends. +`LoggerBackend` is a base interface for all backends. The corresponding factory +is used to create backend instances. Do the following to create a backend implementation: 1. Add `spine-logging-backend` to `implementation` configuration. 2. Create your own backend implementation by extending `LoggerBackend`. 3. Create a factory for your backends by extending `BackendFactory`. -4. Expose the factory as a Java service, so that it can be loaded with `java.util.ServiceLoader`. +4. Expose the factory as a Java service, so that it can be loaded +with `java.util.ServiceLoader`. -### Standard JUL-based backend for JVM +### Standard JUL-based backend -This module provides the default implementation of the logging backend for JVM. It uses -a built-in Java logging framework (also known as JUL or `java.util.logging`). Take a look +This module provides the default implementation of the logging backend that outputs +to the console, if not given an additional configuration. It uses a built-in +Java logging framework (also known as JUL or `java.util.logging`). Take a look on `StdLoggerBackend` for details. To use it, add `spine-logging-backend` to `runtimeOnly` configuration: @@ -43,5 +46,6 @@ dependencies { } ``` -Please note, this backend is default for JVM. `DefaultPlatform` uses it when no other -backend implementation is passed. And this backend is **not** exposed as a Java service. +Please note, this backend is default for JVM. `DefaultPlatform` uses it when +no other backend implementation is passed. This backend is **not** exposed +as a Java service. diff --git a/logging-context/README.md b/logging-context/README.md index 5dd31009..f558e38f 100644 --- a/logging-context/README.md +++ b/logging-context/README.md @@ -12,5 +12,5 @@ dependencies { ``` Please note, this context is **not** used by default when no other contexts -are found on the classpath. `DefaultPlatform` uses `no-op` implementation when +are found on the classpath. `DefaultPlatform` uses a no-op implementation when the context is not passed explicitly. From 3c7782d8e07fc52656a70ecc423199c069178a60 Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Wed, 4 Oct 2023 13:15:55 +0300 Subject: [PATCH 13/19] Format a Markdown table --- logging-backend/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/logging-backend/README.md b/logging-backend/README.md index 50bc9c28..30a63c76 100644 --- a/logging-backend/README.md +++ b/logging-backend/README.md @@ -12,11 +12,11 @@ a log site. The following services may be injected: -| Service | Default | -|-----------------------|---| -| `BackendFactory` | `StdBackendFactory` | +| Service | Default | +|-----------------------|---------------------------| +| `BackendFactory` | `StdBackendFactory` | | `ContextDataProvider` | `NoOpContextDataProvider` | -| `Clock` | `SystemClock` | +| `Clock` | `SystemClock` | ### Logger Backend and Factory From f2d60f9dc2f589ca9a2cc9cfdb5b79e8119a02a2 Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Wed, 4 Oct 2023 14:58:53 +0300 Subject: [PATCH 14/19] Describe repackaging of Flogger sources --- flogger/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/flogger/README.md b/flogger/README.md index 49c81089..d518726b 100644 --- a/flogger/README.md +++ b/flogger/README.md @@ -2,6 +2,15 @@ This directory contains Flogger [modules][flogger-github] built with Gradle. +Original Flogger sources have been repackaged from `com.google.common.*` +to `io.spine.logging.flogger.*`. It prevents a runtime clash in situations +when a user has both `spine-logging` and `flogger` on the classpath. +However, a user is not meant to use two logging libraries simultaneously. +`flogger` may appear on the classpath as a transitive dependency. + +Further, Flogger sources should be migrated to Kotlin and merged with +our own code. + ### API Contains Flogger Logging API along with classes that handle log statements From b8a1573ddda229d6ee5214670e6d6e22319ea23f Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Wed, 4 Oct 2023 15:48:51 +0300 Subject: [PATCH 15/19] Add Gradle usage example for the fake backend --- logging-fake-backend/README.md | 40 ++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/logging-fake-backend/README.md b/logging-fake-backend/README.md index 1db2ffd8..ee8b8bf1 100644 --- a/logging-fake-backend/README.md +++ b/logging-fake-backend/README.md @@ -1,4 +1,4 @@ -## Spine Fake Backend +## Spine Fake Backend for JVM **Note:** This is a specific backend implementation that is designed to be used in tests. @@ -26,4 +26,40 @@ val logged = captureLogData { check(logged[0].literalArgument == message) ``` -To use it, add this backend to `implementation` configuration instead of `runtimeOnly`. +### Gradle configuration + +Please note, this module is **not published**. It can be used only within +`spine-logging` itself as a project dependency **for JVM**. + +Unlike other backends that are put to the runtime classpath, this one should be +available during compilation. It is because `DynamicBackendFactory` (which is +a Kotlin object) and/or `captureLogData { ... }` are meant to be used in code. + +An example usage of `logging-fake-backend` in a JVM module: + +```kotlin +dependencies { + implementation(project(":logging")) + testImplementation(project(":logging-fake-backend")) +} +``` + +In KMP modules there's no `testImplementation` configuration anymore. +Dependencies are split on the level of source sets. + +An example usage of `logging-fake-backend` in a KMP module: + +```kotlin +sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":logging")) + } + } + val jvmTest by getting { + dependencies { + implementation(project(":logging-fake-backend")) + } + } +} +``` From 9c2b0e62ef25438ce542d908f4cabc6cd96b9512 Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Wed, 4 Oct 2023 17:16:43 +0300 Subject: [PATCH 16/19] Fix typos --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0f55c484..d1191fe3 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ If your project does not use gRPC, use the following dependency: ```kotlin dependencies { - rutimeOnly("io.spine:spine-logging-context:$version") + runtimeOnly("io.spine:spine-logging-context:$version") } ``` @@ -123,7 +123,7 @@ If your project does use gRPC, add the following dependency: ```kotlin dependencies { - rutimeOnly("io.spine:spine-logging-grpc-context:$version") + runtimeOnly("io.spine:spine-logging-grpc-context:$version") } ``` From b93f1f6e3e49fb7739efae2c94ffe0210edeeb52 Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Wed, 4 Oct 2023 19:22:20 +0300 Subject: [PATCH 17/19] Add a context usage example --- README.md | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d1191fe3..b3a01e80 100644 --- a/README.md +++ b/README.md @@ -104,17 +104,92 @@ will not be able to understand, which one should be used. ## Logging contexts A logging context refers to a set of attributes that are attached to all log -records while a context is installed. For instance, you can attach a user ID -to all log records for the current request. +records while a context is installed. For example, rate limit counters are +always attached to the context. -The default implementation provides a no-op context. To use a logging context, -a `runtimeOnly` dependency for a context implementation should be added along -with the mentioned above dependencies. +Here is an example of rate limiters context metadata: + +```kotlin +import io.spine.logging.WithLogging + +class Example : WithLogging { + fun action() = repeat(12) { + logger.atInfo() + .every(7) // Should be emitted once per N calls. + .log { "Call #$it" } + } +} + +// Produces the following output (without timestamps): +// INFO: Call #0 [CONTEXT ratelimit_count=7 ] +// INFO: Call #7 [CONTEXT ratelimit_count=7 skipped=6 ] +``` + +Also, a user can attach its own metadata. For instance, you can attach +a user ID to all log records for the current request. + +Here is an example of how to attach a custom context metadata: + +```kotlin +import io.spine.logging.LoggingFactory.singleMetadataKey +import io.spine.logging.WithLogging +import io.spine.logging.context.ScopedLoggingContext + +typealias Action = String +typealias User = String + +data class Request( + val action: Action, + val user: User, +) + +class RequestHandler : WithLogging { + + companion object { + // Metadata is represented with key-value entries. + private val USER_KEY = singleMetadataKey("user", User::class) + } + + fun handle(request: Request) = withinUserContext(request.user) { + logger.atInfo().log { "Handling `${request.action}` request." } + // Do handle the request ... + } + + private fun withinUserContext(user: User, action: () -> Unit) = ScopedLoggingContext.newContext() + .withMetadata(USER_KEY, user) + .execute(action) +} +``` + +Let's send several requests to the created handler: + +```kotlin +val handler = RequestHandler() +with(handler) { + handle(Request(action = "create", user = "Maks")) + handle(Request(action = "update", user = "Maks")) + handle(Request(action = "remove", user = "Bill")) +} + +// Produces the following output (without timestamps): +// INFO: Handling `create` request. [CONTEXT user="Maks" ] +// INFO: Handling `update` request. [CONTEXT user="Maks" ] +// INFO: Handling `remove` request. [CONTEXT user="Bill" ] +``` + +### Gradle configuration + +The default implementation provides a no-op context. Any context metadata is +ignored in this case. + +To use a logging context, a `runtimeOnly` dependency for a context +implementation should be added. If your project does not use gRPC, use the following dependency: ```kotlin dependencies { + implementation("io.spine:spine-logging:$version") runtimeOnly("io.spine:spine-logging-context:$version") } ``` @@ -123,6 +198,7 @@ If your project does use gRPC, add the following dependency: ```kotlin dependencies { + implementation("io.spine:spine-logging:$version") runtimeOnly("io.spine:spine-logging-grpc-context:$version") } ``` From 5799d12816a522aa9548556e9db5bd9fe1778a65 Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Thu, 5 Oct 2023 11:32:14 +0300 Subject: [PATCH 18/19] Comment code snippets --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b3a01e80..02a8afa8 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ To get a logger, one can use the following: 1. Make a logging class implement `WithLogging` interface. 2. Get a logger from `LoggingFactory`. -The interface provides a default method `logger()` that returns a logger +The interface provides a default property `logger` that returns a logger for the implementing class or object: ```kotlin @@ -48,8 +48,7 @@ import io.spine.logging.WithLogging class Example : WithLogging { fun doSomething() { - logger() // Call to the default method of `WithLogging`. - .atWarning() + logger.atWarning() // Call to the default property of `WithLogging`. .log { "..." } } } @@ -107,7 +106,7 @@ A logging context refers to a set of attributes that are attached to all log records while a context is installed. For example, rate limit counters are always attached to the context. -Here is an example of rate limiters context metadata: +Here is an example of rate limiter context metadata: ```kotlin import io.spine.logging.WithLogging @@ -116,7 +115,7 @@ class Example : WithLogging { fun action() = repeat(12) { logger.atInfo() .every(7) // Should be emitted once per N calls. - .log { "Call #$it" } + .log { "Call #$it" } // Rate limiter metadata will be included here. } } @@ -126,9 +125,10 @@ class Example : WithLogging { ``` Also, a user can attach its own metadata. For instance, you can attach -a user ID to all log records for the current request. +a user ID to all log records for the current request, or force logging +level if the requested URL contains a debug parameter. -Here is an example of how to attach a custom context metadata: +Here is an example of how to attach a user ID: ```kotlin import io.spine.logging.LoggingFactory.singleMetadataKey @@ -152,7 +152,7 @@ class RequestHandler : WithLogging { fun handle(request: Request) = withinUserContext(request.user) { logger.atInfo().log { "Handling `${request.action}` request." } - // Do handle the request ... + // All log statements within this block will include `user` info. } private fun withinUserContext(user: User, action: () -> Unit) = ScopedLoggingContext.newContext() @@ -179,7 +179,7 @@ with(handler) { ### Gradle configuration -The default implementation provides a no-op context. Any context metadata is +The default implementation provides a no-op context. Context metadata is ignored in this case. To use a logging context, a `runtimeOnly` dependency for a context From 2cd0001663eac0832e8b8494f457d1ad923b102a Mon Sep 17 00:00:00 2001 From: Yevhenii Nadtochii Date: Thu, 5 Oct 2023 13:28:05 +0300 Subject: [PATCH 19/19] Use a more common given name in example snippets --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 02a8afa8..9db602e2 100644 --- a/README.md +++ b/README.md @@ -166,14 +166,14 @@ Let's send several requests to the created handler: ```kotlin val handler = RequestHandler() with(handler) { - handle(Request(action = "create", user = "Maks")) - handle(Request(action = "update", user = "Maks")) + handle(Request(action = "create", user = "Jack")) + handle(Request(action = "update", user = "Jack")) handle(Request(action = "remove", user = "Bill")) } // Produces the following output (without timestamps): -// INFO: Handling `create` request. [CONTEXT user="Maks" ] -// INFO: Handling `update` request. [CONTEXT user="Maks" ] +// INFO: Handling `create` request. [CONTEXT user="Jack" ] +// INFO: Handling `update` request. [CONTEXT user="Jack" ] // INFO: Handling `remove` request. [CONTEXT user="Bill" ] ```