Add log diagnostic context
[dcaegen2/collectors/hv-ves.git] / sources / hv-collector-utils / src / main / kotlin / org / onap / dcae / collectors / veshv / utils / logging / Logger.kt
1 /*
2  * ============LICENSE_START=======================================================
3  * dcaegen2-collectors-veshv
4  * ================================================================================
5  * Copyright (C) 2018 NOKIA
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.onap.dcae.collectors.veshv.utils.logging
21
22 import kotlin.reflect.KClass
23 import org.slf4j.LoggerFactory
24 import org.slf4j.MDC
25
26 typealias MappedDiagnosticContext = () -> Map<String, String>
27
28 @Suppress("TooManyFunctions", "SuboptimalLoggerUsage")
29 class Logger(logger: org.slf4j.Logger) {
30     constructor(clazz: KClass<out Any>) : this(LoggerFactory.getLogger(clazz.java))
31     constructor(name: String) : this(LoggerFactory.getLogger(name))
32
33     private val errorLogger = if (logger.isErrorEnabled) ErrorLevelLogger(logger) else OffLevelLogger
34     private val warnLogger = if (logger.isWarnEnabled) WarnLevelLogger(logger) else OffLevelLogger
35     private val infoLogger = if (logger.isInfoEnabled) InfoLevelLogger(logger) else OffLevelLogger
36     private val debugLogger = if (logger.isDebugEnabled) DebugLevelLogger(logger) else OffLevelLogger
37     private val traceLogger = if (logger.isTraceEnabled) TraceLevelLogger(logger) else OffLevelLogger
38
39     // ERROR
40
41     fun withError(block: AtLevelLogger.() -> Unit) = errorLogger.block()
42
43     fun withError(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
44             errorLogger.withMdc(mdc, block)
45
46     fun error(message: () -> String) = errorLogger.run {
47         log(message())
48     }
49
50     fun error(mdc: MappedDiagnosticContext, message: () -> String) =
51             errorLogger.withMdc(mdc) { log(message()) }
52
53     // WARN
54
55     fun withWarn(block: AtLevelLogger.() -> Unit) = warnLogger.block()
56
57     fun withWarn(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
58             warnLogger.withMdc(mdc, block)
59
60     fun warn(message: () -> String) = warnLogger.run {
61         log(message())
62     }
63
64     fun warn(mdc: MappedDiagnosticContext, message: () -> String) =
65             warnLogger.withMdc(mdc) { log(message()) }
66
67
68     // INFO
69
70     fun withInfo(block: AtLevelLogger.() -> Unit) = infoLogger.block()
71
72     fun withInfo(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
73             infoLogger.withMdc(mdc, block)
74
75     fun info(message: () -> String) = infoLogger.run {
76         log(message())
77     }
78
79     fun info(mdc: MappedDiagnosticContext, message: () -> String) =
80             infoLogger.withMdc(mdc) { log(message()) }
81
82     // DEBUG
83
84     fun withDebug(block: AtLevelLogger.() -> Unit) = debugLogger.block()
85
86     fun withDebug(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
87             debugLogger.withMdc(mdc, block)
88
89     fun debug(message: () -> String) = debugLogger.run {
90         log(message())
91     }
92
93     fun debug(mdc: MappedDiagnosticContext, message: () -> String) =
94             debugLogger.withMdc(mdc) { log(message()) }
95
96
97     // TRACE
98
99     fun withTrace(block: AtLevelLogger.() -> Unit) = traceLogger.block()
100
101     fun withTrace(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
102             traceLogger.withMdc(mdc, block)
103
104     fun trace(message: () -> String) = traceLogger.run {
105         log(message())
106     }
107
108     fun trace(mdc: MappedDiagnosticContext, message: () -> String) =
109             traceLogger.withMdc(mdc) { log(message()) }
110
111 }
112
113 abstract class AtLevelLogger {
114     abstract fun log(message: String)
115     abstract fun log(message: String, t: Throwable)
116     open val enabled: Boolean
117         get() = true
118
119     inline fun withMdc(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) {
120         if (enabled) {
121             try {
122                 MDC.setContextMap(mdc())
123                 block()
124             } finally {
125                 MDC.clear()
126             }
127         }
128     }
129 }
130
131 object OffLevelLogger : AtLevelLogger() {
132     override val enabled = false
133
134     override fun log(message: String) {
135         // do not log anything
136     }
137
138     override fun log(message: String, t: Throwable) {
139         // do not log anything
140     }
141 }
142
143 class ErrorLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
144     override fun log(message: String) {
145         logger.error(message)
146     }
147
148     override fun log(message: String, t: Throwable) {
149         logger.error(message, t)
150     }
151 }
152
153 class WarnLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
154     override fun log(message: String) {
155         logger.warn(message)
156     }
157
158     override fun log(message: String, t: Throwable) {
159         logger.warn(message, t)
160     }
161 }
162
163 class InfoLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
164     override fun log(message: String) {
165         logger.info(message)
166     }
167
168     override fun log(message: String, t: Throwable) {
169         logger.info(message, t)
170     }
171 }
172
173 class DebugLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
174     override fun log(message: String) {
175         logger.debug(message)
176     }
177
178     override fun log(message: String, t: Throwable) {
179         logger.debug(message, t)
180     }
181 }
182
183 class TraceLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
184     override fun log(message: String) {
185         logger.trace(message)
186     }
187
188     override fun log(message: String, t: Throwable) {
189         logger.trace(message, t)
190     }
191 }