summaryrefslogtreecommitdiff
path: root/odcsim-core/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'odcsim-core/src/main')
-rw-r--r--odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorContext.kt12
-rw-r--r--odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/Coroutines.kt8
-rw-r--r--odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/logging/LocationAwareLoggerImpl.kt567
-rw-r--r--odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/logging/LocationIgnorantLoggerImpl.kt440
-rw-r--r--odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/logging/LoggerImpl.kt77
5 files changed, 1104 insertions, 0 deletions
diff --git a/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorContext.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorContext.kt
index d5edd93f..b43a1bab 100644
--- a/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorContext.kt
+++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorContext.kt
@@ -24,6 +24,8 @@
package com.atlarge.odcsim
+import org.slf4j.Logger
+
/**
* Represents the context in which the execution of an actor's behavior takes place.
*
@@ -41,6 +43,16 @@ interface ActorContext<T : Any> {
val time: Instant
/**
+ * The [ActorSystem] the actor is part of.
+ */
+ val system: ActorSystem<*>
+
+ /**
+ * An actor specific logger instance.
+ */
+ val log: Logger
+
+ /**
* Send the specified message to the actor referenced by this [ActorRef].
*
* Please note that callees must guarantee that messages are sent strictly in increasing time.
diff --git a/odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/Coroutines.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/Coroutines.kt
index 70294ae5..1f040c5e 100644
--- a/odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/Coroutines.kt
+++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/Coroutines.kt
@@ -26,6 +26,7 @@ package com.atlarge.odcsim.internal
import com.atlarge.odcsim.ActorContext
import com.atlarge.odcsim.ActorRef
+import com.atlarge.odcsim.ActorSystem
import com.atlarge.odcsim.Behavior
import com.atlarge.odcsim.Duration
import com.atlarge.odcsim.Instant
@@ -36,6 +37,7 @@ import com.atlarge.odcsim.coroutines.SuspendingBehavior
import com.atlarge.odcsim.receiveSignal
import com.atlarge.odcsim.coroutines.suspendWithBehavior
import com.atlarge.odcsim.receiveMessage
+import org.slf4j.Logger
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.resume
@@ -92,6 +94,12 @@ internal class SuspendingBehaviorImpl<T : Any>(
override val time: Instant get() = actorContext.time
+ override val system: ActorSystem<*>
+ get() = actorContext.system
+
+ override val log: Logger
+ get() = actorContext.log
+
override fun <U : Any> send(ref: ActorRef<U>, msg: U, after: Duration) = actorContext.send(ref, msg, after)
override fun <U : Any> spawn(behavior: Behavior<U>, name: String) = actorContext.spawn(behavior, name)
diff --git a/odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/logging/LocationAwareLoggerImpl.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/logging/LocationAwareLoggerImpl.kt
new file mode 100644
index 00000000..bf50b5e8
--- /dev/null
+++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/logging/LocationAwareLoggerImpl.kt
@@ -0,0 +1,567 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 atlarge-research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.atlarge.odcsim.internal.logging
+
+import com.atlarge.odcsim.ActorContext
+import org.slf4j.Logger
+import org.slf4j.Marker
+import org.slf4j.helpers.MessageFormatter
+import org.slf4j.spi.LocationAwareLogger
+
+/**
+ * An actor-specific [Logger] implementation that is aware of the calling location.
+ *
+ * @param ctx The owning [ActorContext] of this logger.
+ * @param delegate The [LocationAwareLogger] to delegate the messages to.
+ */
+internal class LocationAwareLoggerImpl(
+ ctx: ActorContext<*>,
+ private val delegate: LocationAwareLogger
+) : LoggerImpl(ctx), Logger by delegate {
+ /**
+ * The fully qualified name of this class.
+ */
+ private val fqcn = LocationAwareLoggerImpl::class.java.name
+
+ override fun trace(format: String?, arg: Any?) {
+ if (!delegate.isTraceEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg).message
+ delegate.log(null, fqcn, LocationAwareLogger.TRACE_INT, formattedMessage, arrayOf(arg), null)
+ }
+ }
+
+ override fun trace(format: String?, arg1: Any?, arg2: Any?) {
+ if (!delegate.isTraceEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg1, arg2).message
+ delegate.log(null, fqcn, LocationAwareLogger.TRACE_INT, formattedMessage, arrayOf(arg1, arg2), null)
+ }
+ }
+
+ override fun trace(format: String?, argArray: Array<Any?>) {
+ if (!delegate.isTraceEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.arrayFormat(format, argArray).message
+ delegate.log(null, fqcn, LocationAwareLogger.TRACE_INT, formattedMessage, argArray, null)
+ }
+ }
+
+ override fun trace(msg: String?, t: Throwable?) {
+ if (!delegate.isTraceEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(null, fqcn, LocationAwareLogger.TRACE_INT, msg, null, t)
+ }
+ }
+
+ override fun trace(marker: Marker?, msg: String?) {
+ if (!delegate.isTraceEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(marker, fqcn, LocationAwareLogger.TRACE_INT, msg, null, null)
+ }
+ }
+
+ override fun trace(marker: Marker?, format: String?, arg: Any?) {
+ if (!delegate.isTraceEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg).message
+ delegate.log(marker, fqcn, LocationAwareLogger.TRACE_INT, formattedMessage, arrayOf(arg), null)
+ }
+ }
+
+ override fun trace(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
+ if (!delegate.isTraceEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg1, arg2).message
+ delegate.log(marker, fqcn, LocationAwareLogger.TRACE_INT, formattedMessage, arrayOf(arg1, arg2), null)
+ }
+ }
+
+ override fun trace(marker: Marker?, format: String?, argArray: Array<Any?>) {
+ if (!delegate.isTraceEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.arrayFormat(format, argArray).message
+ delegate.log(marker, fqcn, LocationAwareLogger.TRACE_INT, formattedMessage, argArray, null)
+ }
+ }
+
+ override fun trace(marker: Marker?, msg: String?, t: Throwable?) {
+ if (!delegate.isTraceEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(marker, fqcn, LocationAwareLogger.TRACE_INT, msg, null, t)
+ }
+ }
+
+ override fun debug(msg: String?) {
+ if (!delegate.isDebugEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(null, fqcn, LocationAwareLogger.DEBUG_INT, msg, null, null)
+ }
+ }
+
+ override fun debug(format: String?, arg: Any?) {
+ if (!delegate.isDebugEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg).message
+ delegate.log(null, fqcn, LocationAwareLogger.DEBUG_INT, formattedMessage, arrayOf(arg), null)
+ }
+ }
+
+ override fun debug(format: String?, arg1: Any?, arg2: Any?) {
+ if (!delegate.isDebugEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg1, arg2).message
+ delegate.log(null, fqcn, LocationAwareLogger.DEBUG_INT, formattedMessage, arrayOf(arg1, arg2), null)
+ }
+ }
+
+ override fun debug(format: String?, argArray: Array<Any?>) {
+ if (!delegate.isDebugEnabled) {
+ return
+ }
+
+ withMdc {
+ val ft = MessageFormatter.arrayFormat(format, argArray)
+ delegate.log(null, fqcn, LocationAwareLogger.DEBUG_INT, ft.message, ft.argArray, ft.throwable)
+ }
+ }
+
+ override fun debug(msg: String?, t: Throwable?) {
+ if (!delegate.isDebugEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(null, fqcn, LocationAwareLogger.DEBUG_INT, msg, null, t)
+ }
+ }
+
+ override fun debug(marker: Marker?, msg: String?) {
+ if (!delegate.isDebugEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(marker, fqcn, LocationAwareLogger.DEBUG_INT, msg, null, null)
+ }
+ }
+
+ override fun debug(marker: Marker?, format: String?, arg: Any?) {
+ if (!delegate.isDebugEnabled) {
+ return
+ }
+
+ withMdc {
+ val ft = MessageFormatter.format(format, arg)
+ delegate.log(marker, fqcn, LocationAwareLogger.DEBUG_INT, ft.message, ft.argArray, ft.throwable)
+ }
+ }
+
+ override fun debug(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
+ if (!delegate.isDebugEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg1, arg2).message
+ delegate.log(marker, fqcn, LocationAwareLogger.DEBUG_INT, formattedMessage, arrayOf(arg1, arg2), null)
+ }
+ }
+
+ override fun debug(marker: Marker?, format: String?, argArray: Array<Any?>) {
+ if (!delegate.isDebugEnabled) {
+ return
+ }
+
+ withMdc {
+ val ft = MessageFormatter.arrayFormat(format, argArray)
+ delegate.log(marker, fqcn, LocationAwareLogger.DEBUG_INT, ft.message, argArray, ft.throwable)
+ }
+ }
+
+ override fun debug(marker: Marker?, msg: String?, t: Throwable?) {
+ if (!delegate.isDebugEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(marker, fqcn, LocationAwareLogger.DEBUG_INT, msg, null, t)
+ }
+ }
+
+ override fun info(msg: String?) {
+ if (!delegate.isInfoEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(null, fqcn, LocationAwareLogger.INFO_INT, msg, null, null)
+ }
+ }
+
+ override fun info(format: String?, arg: Any?) {
+ if (!delegate.isInfoEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg).message
+ delegate.log(null, fqcn, LocationAwareLogger.INFO_INT, formattedMessage, arrayOf(arg), null)
+ }
+ }
+
+ override fun info(format: String?, arg1: Any?, arg2: Any?) {
+ if (!delegate.isInfoEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg1, arg2).message
+ delegate.log(null, fqcn, LocationAwareLogger.INFO_INT, formattedMessage, arrayOf(arg1, arg2), null)
+ }
+ }
+
+ override fun info(format: String?, argArray: Array<Any?>) {
+ if (!delegate.isInfoEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.arrayFormat(format, argArray).message
+ delegate.log(null, fqcn, LocationAwareLogger.INFO_INT, formattedMessage, argArray, null)
+ }
+ }
+
+ override fun info(msg: String?, t: Throwable?) {
+ if (!delegate.isInfoEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(null, fqcn, LocationAwareLogger.INFO_INT, msg, null, t)
+ }
+ }
+
+ override fun info(marker: Marker?, msg: String?) {
+ if (!delegate.isInfoEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(marker, fqcn, LocationAwareLogger.INFO_INT, msg, null, null)
+ }
+ }
+
+ override fun info(marker: Marker?, format: String?, arg: Any?) {
+ if (!delegate.isInfoEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg).message
+ delegate.log(marker, fqcn, LocationAwareLogger.INFO_INT, formattedMessage, arrayOf(arg), null)
+ }
+ }
+
+ override fun info(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
+ if (!delegate.isInfoEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg1, arg2).message
+ delegate.log(marker, fqcn, LocationAwareLogger.INFO_INT, formattedMessage, arrayOf(arg1, arg2), null)
+ }
+ }
+
+ override fun info(marker: Marker?, format: String?, argArray: Array<Any?>) {
+ if (!delegate.isInfoEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.arrayFormat(format, argArray).message
+ delegate.log(marker, fqcn, LocationAwareLogger.INFO_INT, formattedMessage, argArray, null)
+ }
+ }
+
+ override fun info(marker: Marker?, msg: String?, t: Throwable?) {
+ if (!delegate.isInfoEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(marker, fqcn, LocationAwareLogger.INFO_INT, msg, null, t)
+ }
+ }
+
+ override fun warn(msg: String?) {
+ if (!delegate.isWarnEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(null, fqcn, LocationAwareLogger.WARN_INT, msg, null, null)
+ }
+ }
+
+ override fun warn(format: String?, arg: Any?) {
+ if (!delegate.isWarnEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg).message
+ delegate.log(null, fqcn, LocationAwareLogger.WARN_INT, formattedMessage, arrayOf(arg), null)
+ }
+ }
+
+ override fun warn(format: String?, arg1: Any?, arg2: Any?) {
+ if (!delegate.isWarnEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg1, arg2).message
+ delegate.log(null, fqcn, LocationAwareLogger.WARN_INT, formattedMessage, arrayOf(arg1, arg2), null)
+ }
+ }
+
+ override fun warn(format: String?, argArray: Array<Any?>) {
+ if (!delegate.isWarnEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.arrayFormat(format, argArray).message
+ delegate.log(null, fqcn, LocationAwareLogger.WARN_INT, formattedMessage, argArray, null)
+ }
+ }
+
+ override fun warn(msg: String?, t: Throwable?) {
+ if (!delegate.isWarnEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(null, fqcn, LocationAwareLogger.WARN_INT, msg, null, t)
+ }
+ }
+
+ override fun warn(marker: Marker?, msg: String?) {
+ if (!delegate.isWarnEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(marker, fqcn, LocationAwareLogger.WARN_INT, msg, null, null)
+ }
+ }
+
+ override fun warn(marker: Marker?, format: String?, arg: Any?) {
+ if (!delegate.isWarnEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg).message
+ delegate.log(marker, fqcn, LocationAwareLogger.WARN_INT, formattedMessage, arrayOf(arg), null)
+ }
+ }
+
+ override fun warn(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
+ if (!delegate.isWarnEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg1, arg2).message
+ delegate.log(marker, fqcn, LocationAwareLogger.WARN_INT, formattedMessage, arrayOf(arg1, arg2), null)
+ }
+ }
+
+ override fun warn(marker: Marker?, format: String?, argArray: Array<Any?>) {
+ if (!delegate.isWarnEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.arrayFormat(format, argArray).message
+ delegate.log(marker, fqcn, LocationAwareLogger.WARN_INT, formattedMessage, argArray, null)
+ }
+ }
+
+ override fun warn(marker: Marker?, msg: String?, t: Throwable?) {
+ if (!delegate.isWarnEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(marker, fqcn, LocationAwareLogger.WARN_INT, msg, null, t)
+ }
+ }
+
+ override fun error(msg: String?) {
+ if (!delegate.isErrorEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(null, fqcn, LocationAwareLogger.ERROR_INT, msg, null, null)
+ }
+ }
+
+ override fun error(format: String?, arg: Any?) {
+ if (!delegate.isErrorEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg).message
+ delegate.log(null, fqcn, LocationAwareLogger.ERROR_INT, formattedMessage, arrayOf(arg), null)
+ }
+ }
+
+ override fun error(format: String?, arg1: Any?, arg2: Any?) {
+ if (!delegate.isErrorEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg1, arg2).message
+ delegate.log(null, fqcn, LocationAwareLogger.ERROR_INT, formattedMessage, arrayOf(arg1, arg2), null)
+ }
+ }
+
+ override fun error(format: String?, argArray: Array<Any?>) {
+ if (!delegate.isErrorEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.arrayFormat(format, argArray).message
+ delegate.log(null, fqcn, LocationAwareLogger.ERROR_INT, formattedMessage, argArray, null)
+ }
+ }
+
+ override fun error(msg: String?, t: Throwable?) {
+ if (!delegate.isErrorEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(null, fqcn, LocationAwareLogger.ERROR_INT, msg, null, t)
+ }
+ }
+
+ override fun error(marker: Marker?, msg: String?) {
+ if (!delegate.isErrorEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(marker, fqcn, LocationAwareLogger.ERROR_INT, msg, null, null)
+ }
+ }
+
+ override fun error(marker: Marker?, format: String?, arg: Any?) {
+ if (!delegate.isErrorEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg).message
+ delegate.log(marker, fqcn, LocationAwareLogger.ERROR_INT, formattedMessage, arrayOf(arg), null)
+ }
+ }
+
+ override fun error(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
+ if (!delegate.isErrorEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.format(format, arg1, arg2).message
+ delegate.log(marker, fqcn, LocationAwareLogger.ERROR_INT, formattedMessage, arrayOf(arg1, arg2), null)
+ }
+ }
+
+ override fun error(marker: Marker?, format: String?, argArray: Array<Any?>) {
+ if (!delegate.isErrorEnabled) {
+ return
+ }
+
+ withMdc {
+ val formattedMessage = MessageFormatter.arrayFormat(format, argArray).message
+ delegate.log(marker, fqcn, LocationAwareLogger.ERROR_INT, formattedMessage, argArray, null)
+ }
+ }
+
+ override fun error(marker: Marker?, msg: String?, t: Throwable?) {
+ if (!delegate.isErrorEnabled) {
+ return
+ }
+
+ withMdc {
+ delegate.log(marker, fqcn, LocationAwareLogger.ERROR_INT, msg, null, t)
+ }
+ }
+}
diff --git a/odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/logging/LocationIgnorantLoggerImpl.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/logging/LocationIgnorantLoggerImpl.kt
new file mode 100644
index 00000000..999e30e6
--- /dev/null
+++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/logging/LocationIgnorantLoggerImpl.kt
@@ -0,0 +1,440 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 atlarge-research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.atlarge.odcsim.internal.logging
+
+import com.atlarge.odcsim.ActorContext
+import org.slf4j.Logger
+import org.slf4j.Marker
+
+/**
+ * A [Logger] implementation that is not aware of the calling location.
+ *
+ * @param ctx The owning [ActorContext] of this logger.
+ * @param delegate The [Logger] to delegate the messages to.
+ */
+internal class LocationIgnorantLoggerImpl(
+ ctx: ActorContext<*>,
+ private val delegate: Logger
+) : LoggerImpl(ctx), Logger by delegate {
+ override fun warn(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
+ if (!isWarnEnabled) {
+ return
+ }
+
+ withMdc { delegate.warn(marker, format, arg1, arg2) }
+ }
+
+ override fun warn(format: String?, arg1: Any?, arg2: Any?) {
+ if (!isWarnEnabled) {
+ return
+ }
+
+ withMdc { delegate.warn(format, arg1, arg2) }
+ }
+
+ override fun warn(msg: String?) {
+ if (!isWarnEnabled) {
+ return
+ }
+
+ withMdc { delegate.warn(msg) }
+ }
+
+ override fun warn(marker: Marker?, format: String?, arg: Any?) {
+ if (!isWarnEnabled) {
+ return
+ }
+
+ withMdc { delegate.warn(marker, format, arg) }
+ }
+
+ override fun warn(marker: Marker?, format: String?, vararg arguments: Any?) {
+ if (!isWarnEnabled) {
+ return
+ }
+
+ withMdc { delegate.warn(marker, format, arguments) }
+ }
+
+ override fun warn(format: String?, arg: Any?) {
+ if (!isWarnEnabled) {
+ return
+ }
+
+ withMdc { delegate.warn(format, arg) }
+ }
+
+ override fun warn(marker: Marker?, msg: String?) {
+ if (!isWarnEnabled) {
+ return
+ }
+
+ withMdc { delegate.warn(marker, msg) }
+ }
+
+ override fun warn(msg: String?, t: Throwable?) {
+ if (!isWarnEnabled) {
+ return
+ }
+
+ withMdc { delegate.warn(msg, t) }
+ }
+
+ override fun warn(format: String?, vararg arguments: Any?) {
+ if (!isWarnEnabled) {
+ return
+ }
+
+ withMdc { delegate.warn(format, *arguments) }
+ }
+
+ override fun warn(marker: Marker?, msg: String?, t: Throwable?) {
+ if (!isWarnEnabled) {
+ return
+ }
+
+ withMdc { delegate.warn(marker, msg, t) }
+ }
+
+ override fun info(marker: Marker?, format: String?, vararg arguments: Any?) {
+ if (!isInfoEnabled) {
+ return
+ }
+
+ withMdc { delegate.info(marker, format, *arguments) }
+ }
+
+ override fun info(format: String?, arg: Any?) {
+ if (!isInfoEnabled) {
+ return
+ }
+
+ withMdc { delegate.info(format, arg) }
+ }
+
+ override fun info(marker: Marker?, msg: String?, t: Throwable?) {
+ if (!isInfoEnabled) {
+ return
+ }
+
+ withMdc { delegate.info(marker, msg, t) }
+ }
+
+ override fun info(msg: String?) {
+ if (!isInfoEnabled) {
+ return
+ }
+
+ withMdc { delegate.info(msg) }
+ }
+
+ override fun info(format: String?, vararg arguments: Any?) {
+ if (!isInfoEnabled) {
+ return
+ }
+
+ withMdc { delegate.info(format, *arguments) }
+ }
+
+ override fun info(format: String?, arg1: Any?, arg2: Any?) {
+ if (!isInfoEnabled) {
+ return
+ }
+
+ withMdc { delegate.info(format, arg1, arg2) }
+ }
+
+ override fun info(marker: Marker?, msg: String?) {
+ if (!isInfoEnabled) {
+ return
+ }
+
+ withMdc { delegate.info(marker, msg) }
+ }
+
+ override fun info(marker: Marker?, format: String?, arg: Any?) {
+ if (!isInfoEnabled) {
+ return
+ }
+
+ withMdc { delegate.info(marker, format, arg) }
+ }
+
+ override fun info(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
+ if (!isInfoEnabled) {
+ return
+ }
+
+ withMdc { delegate.info(marker, format, arg1, arg2) }
+ }
+
+ override fun info(msg: String?, t: Throwable?) {
+ if (!isInfoEnabled) {
+ return
+ }
+
+ withMdc { delegate.info(msg, t) }
+ }
+
+ override fun error(msg: String?) {
+ if (!isErrorEnabled) {
+ return
+ }
+
+ withMdc { delegate.error(msg) }
+ }
+
+ override fun error(marker: Marker?, msg: String?) {
+ if (!isErrorEnabled) {
+ return
+ }
+
+ withMdc { delegate.error(marker, msg) }
+ }
+
+ override fun error(format: String?, vararg arguments: Any?) {
+ if (!isErrorEnabled) {
+ return
+ }
+
+ withMdc { delegate.error(format, *arguments) }
+ }
+
+ override fun error(format: String?, arg: Any?) {
+ if (!isErrorEnabled) {
+ return
+ }
+
+ withMdc { delegate.error(format, arg) }
+ }
+
+ override fun error(msg: String?, t: Throwable?) {
+ if (!isErrorEnabled) {
+ return
+ }
+
+ withMdc { delegate.error(msg, t) }
+ }
+
+ override fun error(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
+ if (!isErrorEnabled) {
+ return
+ }
+
+ withMdc { delegate.error(marker, format, arg1, arg2) }
+ }
+
+ override fun error(marker: Marker?, format: String?, vararg arguments: Any?) {
+ if (!isErrorEnabled) {
+ return
+ }
+
+ withMdc { delegate.error(marker, format, *arguments) }
+ }
+
+ override fun error(marker: Marker?, msg: String?, t: Throwable?) {
+ if (!isErrorEnabled) {
+ return
+ }
+
+ withMdc { delegate.error(marker, msg, t) }
+ }
+
+ override fun error(format: String?, arg1: Any?, arg2: Any?) {
+ if (!isErrorEnabled) {
+ return
+ }
+
+ withMdc { delegate.error(format, arg1, arg2) }
+ }
+
+ override fun error(marker: Marker?, format: String?, arg: Any?) {
+ if (!isErrorEnabled) {
+ return
+ }
+
+ withMdc { delegate.error(marker, format, arg) }
+ }
+
+ override fun debug(format: String?, vararg arguments: Any?) {
+ if (!isDebugEnabled) {
+ return
+ }
+
+ withMdc { delegate.debug(format, *arguments) }
+ }
+
+ override fun debug(format: String?, arg1: Any?, arg2: Any?) {
+ if (!isDebugEnabled) {
+ return
+ }
+
+ withMdc { delegate.debug(format, arg1, arg2) }
+ }
+
+ override fun debug(msg: String?, t: Throwable?) {
+ if (!isDebugEnabled) {
+ return
+ }
+
+ withMdc { delegate.debug(msg, t) }
+ }
+
+ override fun debug(format: String?, arg: Any?) {
+ if (!isDebugEnabled) {
+ return
+ }
+
+ withMdc { delegate.debug(format, arg) }
+ }
+
+ override fun debug(marker: Marker?, msg: String?) {
+ if (!isDebugEnabled) {
+ return
+ }
+
+ withMdc { delegate.debug(marker, msg) }
+ }
+
+ override fun debug(msg: String?) {
+ if (!isDebugEnabled) {
+ return
+ }
+
+ withMdc { delegate.debug(msg) }
+ }
+
+ override fun debug(marker: Marker?, msg: String?, t: Throwable?) {
+ if (!isDebugEnabled) {
+ return
+ }
+
+ withMdc { delegate.debug(marker, msg, t) }
+ }
+
+ override fun debug(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
+ if (!isDebugEnabled) {
+ return
+ }
+
+ withMdc { delegate.debug(marker, format, arg1, arg2) }
+ }
+
+ override fun debug(marker: Marker?, format: String?, arg: Any?) {
+ if (!isDebugEnabled) {
+ return
+ }
+
+ withMdc { delegate.debug(marker, format, arg) }
+ }
+
+ override fun debug(marker: Marker?, format: String?, vararg arguments: Any?) {
+ if (!isDebugEnabled) {
+ return
+ }
+
+ withMdc { delegate.debug(marker, format, *arguments) }
+ }
+
+ override fun trace(format: String?, arg: Any?) {
+ if (!isTraceEnabled) {
+ return
+ }
+
+ withMdc { delegate.trace(format, arg) }
+ }
+
+ override fun trace(marker: Marker?, msg: String?) {
+ if (!isTraceEnabled) {
+ return
+ }
+
+ withMdc { delegate.trace(marker, msg) }
+ }
+
+ override fun trace(msg: String?) {
+ if (!isTraceEnabled) {
+ return
+ }
+
+ withMdc { delegate.trace(msg) }
+ }
+
+ override fun trace(msg: String?, t: Throwable?) {
+ if (!isTraceEnabled) {
+ return
+ }
+
+ withMdc { delegate.trace(msg, t) }
+ }
+
+ override fun trace(format: String?, arg1: Any?, arg2: Any?) {
+ if (!isTraceEnabled) {
+ return
+ }
+
+ withMdc { delegate.trace(format, arg1, arg2) }
+ }
+
+ override fun trace(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
+ if (!isTraceEnabled) {
+ return
+ }
+
+ withMdc { delegate.trace(marker, format, arg1, arg2) }
+ }
+
+ override fun trace(marker: Marker?, format: String?, arg: Any?) {
+ if (!isTraceEnabled) {
+ return
+ }
+
+ withMdc { delegate.trace(marker, format, arg) }
+ }
+
+ override fun trace(marker: Marker?, format: String?, vararg argArray: Any?) {
+ if (!isTraceEnabled) {
+ return
+ }
+
+ withMdc { delegate.trace(marker, format, *argArray) }
+ }
+
+ override fun trace(marker: Marker?, msg: String?, t: Throwable?) {
+ if (!isTraceEnabled) {
+ return
+ }
+
+ withMdc { delegate.trace(marker, msg, t) }
+ }
+
+ override fun trace(format: String?, vararg arguments: Any?) {
+ if (!isTraceEnabled) {
+ return
+ }
+
+ withMdc { delegate.trace(format, *arguments) }
+ }
+}
diff --git a/odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/logging/LoggerImpl.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/logging/LoggerImpl.kt
new file mode 100644
index 00000000..f971f08d
--- /dev/null
+++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/internal/logging/LoggerImpl.kt
@@ -0,0 +1,77 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 atlarge-research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.atlarge.odcsim.internal.logging
+
+import com.atlarge.odcsim.ActorContext
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.slf4j.MDC
+import org.slf4j.spi.LocationAwareLogger
+
+/**
+ * An actor-specific [Logger] implementation.
+ *
+ * @param ctx The owning [ActorContext] of this logger.
+ */
+abstract class LoggerImpl internal constructor(protected val ctx: ActorContext<*>) : Logger {
+ /**
+ * Configure [MDC] with actor-specific information.
+ */
+ protected inline fun withMdc(block: () -> Unit) {
+ MDC.put(MDC_ACTOR_SYSTEM, ctx.system.name)
+ MDC.put(MDC_ACTOR_TIME, String.format("%.2f", ctx.time))
+ MDC.put(MDC_ACTOR_REF, ctx.self.path.toString())
+ try {
+ block()
+ } finally {
+ MDC.remove(MDC_ACTOR_SYSTEM)
+ MDC.remove(MDC_ACTOR_TIME)
+ MDC.remove(MDC_ACTOR_REF)
+ }
+ }
+
+ /**
+ * Mapped Diagnostic Context (MDC) attribute names.
+ */
+ companion object {
+ val MDC_ACTOR_SYSTEM = "actor.system"
+ val MDC_ACTOR_TIME = "actor.time"
+ val MDC_ACTOR_REF = "actor.ref"
+
+ /**
+ * Create a [Logger] for the specified [ActorContext].
+ *
+ * @param ctx The actor context to create the logger for.
+ */
+ operator fun invoke(ctx: ActorContext<*>): Logger {
+ val logger = LoggerFactory.getLogger(ctx.javaClass)
+ return if (logger is LocationAwareLogger) {
+ LocationAwareLoggerImpl(ctx, logger)
+ } else {
+ LocationIgnorantLoggerImpl(ctx, logger)
+ }
+ }
+ }
+}