Support/improve interface-based logger mixin
diff --git a/log4j-api-kotlin-sample/src/main/kotlin/org/apache/logging/log4j/kotlin/sample/LoggingAppMixin.kt b/log4j-api-kotlin-sample/src/main/kotlin/org/apache/logging/log4j/kotlin/sample/LoggingAppMixin.kt
new file mode 100644
index 0000000..da3de0a
--- /dev/null
+++ b/log4j-api-kotlin-sample/src/main/kotlin/org/apache/logging/log4j/kotlin/sample/LoggingAppMixin.kt
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.kotlin.sample
+
+import org.apache.logging.log4j.Level
+import org.apache.logging.log4j.kotlin.Logging
+import org.apache.logging.log4j.kotlin.logger
+import java.util.*
+
+object LoggingAppMixin: Logging {
+ @JvmStatic
+ fun main(args: Array<String>) {
+ val s1 = "foo"
+ val s2 = "bar"
+ val t = RuntimeException("error")
+
+ logger.info { "Hello, world: $s1 $s2" }
+
+ logger.trace("Regular trace")
+
+ logger.trace {
+ logger.info("Inside trace extension!")
+ }
+
+ logger.trace({ "Trace extension with entry message." }) {
+ logger.info("Inside trace extension with supplier!")
+ }
+
+ fun getKey(): Int = logger.trace {
+ Random().nextInt(10)
+ }
+
+ fun getKeyError(): Int = logger.trace {
+ throw Exception("Oops!")
+ }
+
+ logger.info { "Key was ${getKey()}" }
+ try {
+ logger.info { "Key was ${getKeyError()}" }
+ } catch(e: Exception) {
+ Unit
+ }
+
+ logger.throwing(t)
+ logger.throwing(Level.INFO, t)
+
+ logger.catching(t)
+ }
+}
diff --git a/log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/Logger.kt b/log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/Logger.kt
index 627d1fa..6ed453e 100644
--- a/log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/Logger.kt
+++ b/log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/Logger.kt
@@ -208,11 +208,14 @@
}
/**
- * Logger instantiation. Use: `val log = logger()`.
+ * Logger instantiation by function. Use: `val log = logger()`.
*/
@Suppress("unused")
-inline fun <reified T : Any> T.logger(): FunctionalLogger =
- FunctionalLogger(LogManager.getContext(T::class.java.classLoader, false).getLogger(unwrapCompanionClass(T::class.java).name))
+inline fun <reified T : Any> T.logger() = loggerOf(T::class.java)
+
+fun loggerOf(ofClass: Class<*>): FunctionalLogger {
+ return FunctionalLogger(LogManager.getContext(ofClass.classLoader, false).getLogger(unwrapCompanionClass(ofClass).name))
+}
// unwrap companion class to enclosing class given a Java Class
fun <T : Any> unwrapCompanionClass(ofClass: Class<T>): Class<*> {
diff --git a/log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/Logging.kt b/log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/Logging.kt
index 28229e5..8bd11cd 100644
--- a/log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/Logging.kt
+++ b/log4j-api-kotlin/src/main/kotlin/org/apache/logging/log4j/kotlin/Logging.kt
@@ -1,7 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
package org.apache.logging.log4j.kotlin
-import org.apache.logging.log4j.Logger
-
/**
* An interface-based "mixin" to easily add a log val to a class, named by the enclosing class. This allows
* code like this:
@@ -10,24 +24,26 @@
* import org.apache.logging.log4j.kotlin.Logging
*
* class MyClass: Logging {
- * override val log: Logger = logger()
+ * // use `logger` as necessary
* }
*
* ```
*
- * A simpler mechanism is to use the class extension directly, like:
+ * Or declaring the interface on a companion object works just as well:
*
* ```
* import org.apache.logging.log4j.kotlin.logger
*
* class MyClass {
- * val log = logger()
+ * companion object: Logging
+ *
+ * // use `logger` as necessary
* }
*
* ```
*/
interface Logging {
- val log: Logger
-
- fun logger(): Logger = this.javaClass.logger()
+ @Suppress("unused")
+ val logger
+ get() = loggerOf(this.javaClass)
}
diff --git a/log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerCompanionTest.kt b/log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerCompanionTest.kt
index a661533..1d78b0b 100644
--- a/log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerCompanionTest.kt
+++ b/log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerCompanionTest.kt
@@ -24,7 +24,8 @@
}
@Test
- fun `Logging from companion logger works!`() {
+ fun `Logging from a function instantiation via companion logs the correct class name`() {
+ // this should log from class LoggerCompanionTest
log.error("This is an error log.")
}
}
diff --git a/log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerMixinCompanionExtendsTest.kt b/log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerMixinCompanionExtendsTest.kt
new file mode 100644
index 0000000..223a0b6
--- /dev/null
+++ b/log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerMixinCompanionExtendsTest.kt
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.kotlin
+
+import org.junit.Test
+
+class LoggerMixinCompanionExtendsTest {
+
+ companion object : Logging
+
+ @Test
+ fun `Logging from an interface mix-in via companion logs the correct class name`() {
+ // this should log from class LoggerMixinCompanionExtendsTest
+ logger.error("This is an error log.")
+ }
+}
diff --git a/log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerMixinExtendsTest.kt b/log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerMixinExtendsTest.kt
new file mode 100644
index 0000000..2939833
--- /dev/null
+++ b/log4j-api-kotlin/src/test/kotlin/org.apache.logging.log4j.kotlin/LoggerMixinExtendsTest.kt
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.kotlin
+
+import org.junit.Test
+
+class LoggerMixinExtendsTest : Logging {
+
+ @Test
+ fun `Logging using an interface mix-in logs the correct class name`() {
+ // this should log from class LoggerMixinExtendsTest
+ logger.error("This is an error log.")
+ }
+}