82ce50a9f685ffe1dcc204174baf12a17a617df6
[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 ch.qos.logback.classic.LoggerContext
23 import kotlin.reflect.KClass
24 import org.slf4j.LoggerFactory
25 import org.slf4j.MDC
26
27 typealias MappedDiagnosticContext = () -> Map<String, String>
28
29 @Suppress("TooManyFunctions", "SuboptimalLoggerUsage")
30 class Logger(logger: org.slf4j.Logger) {
31     constructor(clazz: KClass<out Any>) : this(LoggerFactory.getLogger(clazz.java))
32     constructor(name: String) : this(LoggerFactory.getLogger(name))
33
34     private val errorLogger = if (logger.isErrorEnabled) ErrorLevelLogger(logger) else OffLevelLogger
35     private val warnLogger = if (logger.isWarnEnabled) WarnLevelLogger(logger) else OffLevelLogger
36     private val infoLogger = if (logger.isInfoEnabled) InfoLevelLogger(logger) else OffLevelLogger
37     private val debugLogger = if (logger.isDebugEnabled) DebugLevelLogger(logger) else OffLevelLogger
38     private val traceLogger = if (logger.isTraceEnabled) TraceLevelLogger(logger) else OffLevelLogger
39
40     // ERROR
41
42     fun withError(block: AtLevelLogger.() -> Unit) = errorLogger.block()
43
44     fun withError(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
45         errorLogger.withMdc(mdc, block)
46
47     fun error(message: () -> String) = errorLogger.run {
48         log(message())
49     }
50
51     fun error(mdc: MappedDiagnosticContext, message: () -> String) =
52         errorLogger.withMdc(mdc) { log(message()) }
53
54     fun error(mdc: MappedDiagnosticContext, marker: Marker, message: () -> String) =
55         errorLogger.withMdc(mdc) { log(marker, message()) }
56
57     // WARN
58
59     fun withWarn(block: AtLevelLogger.() -> Unit) = warnLogger.block()
60
61     fun withWarn(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
62         warnLogger.withMdc(mdc, block)
63
64     fun warn(message: () -> String) = warnLogger.run {
65         log(message())
66     }
67
68     fun warn(mdc: MappedDiagnosticContext, message: () -> String) =
69         warnLogger.withMdc(mdc) { log(message()) }
70
71     fun warn(mdc: MappedDiagnosticContext, marker: Marker, message: () -> String) =
72         warnLogger.withMdc(mdc) { log(marker, message()) }
73
74     // INFO
75
76     fun withInfo(block: AtLevelLogger.() -> Unit) = infoLogger.block()
77
78     fun withInfo(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
79         infoLogger.withMdc(mdc, block)
80
81     fun info(message: () -> String) = infoLogger.run {
82         log(message())
83     }
84
85     fun info(mdc: MappedDiagnosticContext, message: () -> String) =
86         infoLogger.withMdc(mdc) { log(message()) }
87
88     fun info(mdc: MappedDiagnosticContext, marker: Marker, message: () -> String) =
89         infoLogger.withMdc(mdc) { log(marker, message()) }
90
91     // DEBUG
92
93     fun withDebug(block: AtLevelLogger.() -> Unit) = debugLogger.block()
94
95     fun withDebug(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
96         debugLogger.withMdc(mdc, block)
97
98     fun debug(message: () -> String) = debugLogger.run {
99         log(message())
100     }
101
102     fun debug(mdc: MappedDiagnosticContext, message: () -> String) =
103         debugLogger.withMdc(mdc) { log(message()) }
104
105     fun debug(mdc: MappedDiagnosticContext, marker: Marker, message: () -> String) =
106         debugLogger.withMdc(mdc) { log(marker, message()) }
107
108     // TRACE
109
110     fun withTrace(block: AtLevelLogger.() -> Unit) = traceLogger.block()
111
112     fun withTrace(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
113         traceLogger.withMdc(mdc, block)
114
115     fun trace(message: () -> String) = traceLogger.run {
116         log(message())
117     }
118
119     fun trace(mdc: MappedDiagnosticContext, message: () -> String) =
120         traceLogger.withMdc(mdc) { log(message()) }
121
122     fun trace(mdc: MappedDiagnosticContext, marker: Marker, message: () -> String) =
123         traceLogger.withMdc(mdc) { log(marker, message()) }
124
125     companion object {
126         fun setLogLevel(packageName: String, level: LogLevel) {
127             val loggerContext = LoggerFactory.getILoggerFactory() as LoggerContext
128             loggerContext.getLogger(packageName).level = level()
129         }
130     }
131 }
132
133 abstract class AtLevelLogger {
134     abstract fun log(message: String)
135     abstract fun log(message: String, t: Throwable)
136     abstract fun log(marker: Marker, message: String)
137
138     open val enabled: Boolean
139         get() = true
140
141     inline fun withMdc(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) {
142         if (enabled) {
143             try {
144                 MDC.setContextMap(mdc())
145                 block()
146             } finally {
147                 MDC.clear()
148             }
149         }
150     }
151
152     protected fun withAdditionalMdc(mdc: Map<String, String>, block: () -> Unit) {
153         if (mdc.isEmpty()) {
154             block()
155         } else {
156             try {
157                 mdc.forEach(MDC::put)
158                 block()
159             } finally {
160                 mdc.keys.forEach(MDC::remove)
161             }
162         }
163     }
164 }
165
166 object OffLevelLogger : AtLevelLogger() {
167     override val enabled = false
168
169     override fun log(message: String) {
170         // do not log anything
171     }
172
173     override fun log(message: String, t: Throwable) {
174         // do not log anything
175     }
176
177     override fun log(marker: Marker, message: String) {
178         // do not log anything
179     }
180 }
181
182 @Suppress("SuboptimalLoggerUsage")
183 class ErrorLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
184     override fun log(message: String) {
185         logger.error(message)
186     }
187
188     override fun log(message: String, t: Throwable) {
189         logger.error(message, t)
190     }
191
192     override fun log(marker: Marker, message: String) =
193         withAdditionalMdc(marker.mdc) {
194             logger.error(marker.slf4jMarker, message)
195         }
196 }
197
198 @Suppress("SuboptimalLoggerUsage")
199 class WarnLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
200     override fun log(message: String) {
201         logger.warn(message)
202     }
203
204     override fun log(message: String, t: Throwable) {
205         logger.warn(message, t)
206     }
207
208     override fun log(marker: Marker, message: String) =
209         withAdditionalMdc(marker.mdc) {
210             logger.warn(marker.slf4jMarker, message)
211         }
212 }
213
214 @Suppress("SuboptimalLoggerUsage")
215 class InfoLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
216     override fun log(message: String) {
217         logger.info(message)
218     }
219
220     override fun log(message: String, t: Throwable) {
221         logger.info(message, t)
222     }
223
224     override fun log(marker: Marker, message: String) =
225         withAdditionalMdc(marker.mdc) {
226             logger.info(marker.slf4jMarker, message)
227         }
228 }
229
230 @Suppress("SuboptimalLoggerUsage")
231 class DebugLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
232     override fun log(message: String) {
233         logger.debug(message)
234     }
235
236     override fun log(message: String, t: Throwable) {
237         logger.debug(message, t)
238     }
239
240     override fun log(marker: Marker, message: String) =
241         withAdditionalMdc(marker.mdc) {
242             logger.debug(marker.slf4jMarker, message)
243         }
244 }
245
246 @Suppress("SuboptimalLoggerUsage")
247 class TraceLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
248     override fun log(message: String) {
249         logger.trace(message)
250     }
251
252     override fun log(message: String, t: Throwable) {
253         logger.trace(message, t)
254     }
255
256     override fun log(marker: Marker, message: String) =
257         withAdditionalMdc(marker.mdc) {
258             logger.trace(marker.slf4jMarker, message)
259         }
260 }