This is an automated email from the ASF dual-hosted git repository. vy pushed a commit to branch intro-revamp in repository https://gitbox.apache.org/repos/asf/logging-log4j-kotlin.git
commit 250b5cba9c87ceaa4c4d7ae28ba00d100b6c0678 Author: Volkan Yazıcı <[email protected]> AuthorDate: Fri Jul 5 12:51:44 2024 +0200 Revamp the explanation on creating loggers --- src/site/antora/modules/ROOT/pages/index.adoc | 134 +++++++++++++++++++++----- 1 file changed, 110 insertions(+), 24 deletions(-) diff --git a/src/site/antora/modules/ROOT/pages/index.adoc b/src/site/antora/modules/ROOT/pages/index.adoc index 89221cb..a239ad1 100644 --- a/src/site/antora/modules/ROOT/pages/index.adoc +++ b/src/site/antora/modules/ROOT/pages/index.adoc @@ -45,77 +45,163 @@ You need to have the `org.apache.logging.log4j:log4j-api-kotlin` dependency in y Java module name and OSGi `Bundle-SymbolicName` are set to `org.apache.logging.log4j.api.kotlin`. -[#usage] -== Usage +[#create-loggers] +== Creating loggers -You can start using the wrapper by extending from the provided `Logging` interface: +A `Logger` is the primary interface that users interact with Log4j Kotlin. +You can create ``Logger``s particularly in two ways: + +* <<class-loggers,Associate them with the class>> (*Recommended!*) +* <<instance-loggers,Associate them with the instance>> + +[#class-loggers] +=== [[usage]] Creating class loggers + +For most applications, we recommend you to create *a single logger instance per class definition* – not <<instance-loggers,per class instance>>! +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. +You can create class loggers in one of following ways: + +[#create-companion-logger] +==== Creating a logger in the companion object + +This is the traditional approach to create class loggers. +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. [source,kotlin] ---- -import org.apache.logging.log4j.kotlin.Logging +import org.apache.logging.log4j.kotlin.logger + +class DbTableService { + + companion object { -class MyClass: BaseClass, Logging { + private val LOGGER = logger() // <1> - fun doStuff() { - logger.info("Doing stuff") } - fun doStuffWithUser(user: User) { - logger.info { "Doing stuff with ${user.name}." } + fun truncateTable(tableName: String) { + LOGGER.warn { "truncating table `${tableName}`" } + db.truncate(tableName) } } ---- +<1> Create a `Logger` associated with the static class definition that all instances of the class share -The `Logging` interface can also be mixed into `object` declarations, including companions. -This is generally preferable over the previous approach as there is a single logger created for every instance of the class. +[#extend-companion] +==== Extending companion object from `Logging` + +`Logging` interface contains a `logger` getter that you can use by extending the companion object from the `Logging` class: [source,kotlin] ---- import org.apache.logging.log4j.kotlin.Logging -class MyClass: BaseClass { +class DbTableService { - companion object : Logging + companion object: Logging // <1> - // ... + fun truncateTable(tableName: String) { + logger.warn { "truncating table `${tableName}`" } + db.truncate(tableName) + } } ---- +<1> Extending the companion object from `Logging` effectively creates a single `Logger` instance +. Assigned to the `logger` field +. Associated with the static class definition that all instances of the class share + +[NOTE] +==== +This getter-based approach incurs an extra overhead (compared to <<create-companion-logger>>) due to the logger lookup involved at runtime. +==== -Alternatively, a more traditional style can be used to instantiate a logger instance: +[#instance-loggers] +=== Creating instance loggers + +Even though we recommend you to <<class-loggers,create class loggers>>, 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. +You can achieve this as follows: + +[#create-instance-logger] +==== Creating a logger in the class + +This is the traditional approach to create instance loggers. +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. [source,kotlin] ---- import org.apache.logging.log4j.kotlin.logger -class MyClass: BaseClass { +class DbTableService { - val logger = logger() + private val logger = logger() // <1> - // ... + fun truncateTable(tableName: String) { + logger.warn { "truncating table `${tableName}`" } + db.truncate(tableName) + } } ---- +<1> Create a `Logger` associated with the class instance -The function `logger()` is an extension function on the `Any` type (or more specifically, any type `T` that extends `Any`). +[#extend-instance] +==== Extending the class from `Logging` -Beginning in version 1.3.0, an extension property is also available on classes: +`Logging` interface contains a `logger` getter that you can use by extending the class from `Logging`: + +[source,kotlin] +---- +import org.apache.logging.log4j.kotlin.Logging + +class DbTableService: Logging { // <1> + + fun truncateTable(tableName: String) { + logger.warn { "truncating table `${tableName}`" } + db.truncate(tableName) + } + +} +---- +<1> Extending the class from `Logging` effectively creates a single `Logger` instance +. Assigned to the `logger` field +. Exclusively associated with the class instance (i.e., not shared among instances!) + +[NOTE] +==== +This getter-based approach incurs an extra overhead (compared to <<create-instance-logger>>) due to the logger lookup involved at runtime. +==== + +[#logger-extension] +==== Using `logger` extension property + +You can use the `logger` extension property to dynamically inject a logger at the spot: [source,kotlin] ---- import org.apache.logging.log4j.kotlin.logger -class MyClass: BaseClass { +class DbTableService { - fun doStuff() { - logger.info("Hello, world!") + fun truncateTable(tableName: String) { + logger.warn { "truncating table `${tableName}`" } // <1> + db.truncate(tableName) } } ---- +<1> `logger` will look up the associated `Logger` instance for the encapsulating class + +[NOTE] +==== +This getter-based approach incurs an extra overhead (compared to <<create-instance-logger>>) due to the logger lookup involved at runtime. +==== + +[#thread-context] +== Thread context -Also added in version 1.3.0, the `ThreadContext` API has two facade objects provided: `ContextMap` and `ContextStack`. +The `ThreadContext` API has two facade objects provided: `ContextMap` and `ContextStack`. [source,kotlin] ----
