Merge "Add metrics for dropped messages"
[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     fun error(mdc: MappedDiagnosticContext, marker: Marker, message: () -> String) =
54             errorLogger.withMdc(mdc) { log(marker, message()) }
55
56     // WARN
57
58     fun withWarn(block: AtLevelLogger.() -> Unit) = warnLogger.block()
59
60     fun withWarn(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
61             warnLogger.withMdc(mdc, block)
62
63     fun warn(message: () -> String) = warnLogger.run {
64         log(message())
65     }
66
67     fun warn(mdc: MappedDiagnosticContext, message: () -> String) =
68             warnLogger.withMdc(mdc) { log(message()) }
69
70     fun warn(mdc: MappedDiagnosticContext, marker: Marker, message: () -> String) =
71             warnLogger.withMdc(mdc) { log(marker, message()) }
72
73     // INFO
74
75     fun withInfo(block: AtLevelLogger.() -> Unit) = infoLogger.block()
76
77     fun withInfo(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
78             infoLogger.withMdc(mdc, block)
79
80     fun info(message: () -> String) = infoLogger.run {
81         log(message())
82     }
83
84     fun info(mdc: MappedDiagnosticContext, message: () -> String) =
85             infoLogger.withMdc(mdc) { log(message()) }
86
87     fun info(mdc: MappedDiagnosticContext, marker: Marker, message: () -> String) =
88             infoLogger.withMdc(mdc) { log(marker, message()) }
89
90     // DEBUG
91
92     fun withDebug(block: AtLevelLogger.() -> Unit) = debugLogger.block()
93
94     fun withDebug(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
95             debugLogger.withMdc(mdc, block)
96
97     fun debug(message: () -> String) = debugLogger.run {
98         log(message())
99     }
100
101     fun debug(mdc: MappedDiagnosticContext, message: () -> String) =
102             debugLogger.withMdc(mdc) { log(message()) }
103
104     fun debug(mdc: MappedDiagnosticContext, marker: Marker, message: () -> String) =
105             debugLogger.withMdc(mdc) { log(marker, message()) }
106
107     // TRACE
108
109     fun withTrace(block: AtLevelLogger.() -> Unit) = traceLogger.block()
110
111     fun withTrace(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) =
112             traceLogger.withMdc(mdc, block)
113
114     fun trace(message: () -> String) = traceLogger.run {
115         log(message())
116     }
117
118     fun trace(mdc: MappedDiagnosticContext, message: () -> String) =
119             traceLogger.withMdc(mdc) { log(message()) }
120
121     fun trace(mdc: MappedDiagnosticContext, marker: Marker, message: () -> String) =
122             traceLogger.withMdc(mdc) { log(marker, message()) }
123
124 }
125
126 abstract class AtLevelLogger {
127     abstract fun log(message: String)
128     abstract fun log(message: String, t: Throwable)
129     abstract fun log(marker: Marker, message: String)
130
131     open val enabled: Boolean
132         get() = true
133
134     inline fun withMdc(mdc: MappedDiagnosticContext, block: AtLevelLogger.() -> Unit) {
135         if (enabled) {
136             try {
137                 MDC.setContextMap(mdc())
138                 block()
139             } finally {
140                 MDC.clear()
141             }
142         }
143     }
144
145     protected fun withAdditionalMdc(mdc: Map<String, String>, block: () -> Unit) {
146         if (mdc.isEmpty()) {
147             block()
148         } else {
149             try {
150                 mdc.forEach(MDC::put)
151                 block()
152             } finally {
153                 mdc.keys.forEach(MDC::remove)
154             }
155         }
156     }
157 }
158
159 object OffLevelLogger : AtLevelLogger() {
160     override val enabled = false
161
162     override fun log(message: String) {
163         // do not log anything
164     }
165
166     override fun log(message: String, t: Throwable) {
167         // do not log anything
168     }
169
170     override fun log(marker: Marker, message: String) {
171         // do not log anything
172     }
173 }
174
175 @Suppress("SuboptimalLoggerUsage")
176 class ErrorLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
177     override fun log(message: String) {
178         logger.error(message)
179     }
180
181     override fun log(message: String, t: Throwable) {
182         logger.error(message, t)
183     }
184
185     override fun log(marker: Marker, message: String) =
186             withAdditionalMdc(marker.mdc) {
187                 logger.error(marker.slf4jMarker, message)
188             }
189 }
190
191 @Suppress("SuboptimalLoggerUsage")
192 class WarnLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
193     override fun log(message: String) {
194         logger.warn(message)
195     }
196
197     override fun log(message: String, t: Throwable) {
198         logger.warn(message, t)
199     }
200
201     override fun log(marker: Marker, message: String) =
202             withAdditionalMdc(marker.mdc) {
203                 logger.warn(marker.slf4jMarker, message)
204             }
205 }
206
207 @Suppress("SuboptimalLoggerUsage")
208 class InfoLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
209     override fun log(message: String) {
210         logger.info(message)
211     }
212
213     override fun log(message: String, t: Throwable) {
214         logger.info(message, t)
215     }
216
217     override fun log(marker: Marker, message: String) =
218             withAdditionalMdc(marker.mdc) {
219                 logger.info(marker.slf4jMarker, message)
220             }
221 }
222
223 @Suppress("SuboptimalLoggerUsage")
224 class DebugLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
225     override fun log(message: String) {
226         logger.debug(message)
227     }
228
229     override fun log(message: String, t: Throwable) {
230         logger.debug(message, t)
231     }
232
233     override fun log(marker: Marker, message: String) =
234             withAdditionalMdc(marker.mdc) {
235                 logger.debug(marker.slf4jMarker, message)
236             }
237 }
238
239 @Suppress("SuboptimalLoggerUsage")
240 class TraceLevelLogger(private val logger: org.slf4j.Logger) : AtLevelLogger() {
241     override fun log(message: String) {
242         logger.trace(message)
243     }
244
245     override fun log(message: String, t: Throwable) {
246         logger.trace(message, t)
247     }
248
249     override fun log(marker: Marker, message: String) =
250             withAdditionalMdc(marker.mdc) {
251                 logger.trace(marker.slf4jMarker, message)
252             }
253 }