2 * Copyright (c) 2019 AT&T Intellectual Property.
3 * Copyright (c) 2018-2019 Nokia.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * This source code is part of the near-RT RIC (RAN Intelligent Controller)
18 * platform project (RICP).
21 // Package golog implements a simple structured logging with MDC (Mapped Diagnostics Context) support.
34 // Level is a type define for the logging level.
38 // ERR is an error level log entry.
40 // WARN is a warning level log entry.
42 // INFO is an info level log entry.
44 // DEBUG is a debug level log entry.
48 // MdcLogger is the logger instance, created with InitLogger() function.
49 type MdcLogger struct {
57 type logEntry struct {
59 Crit string `json:"crit"`
61 Mdc map[string]string `json:"mdc"`
62 Msg string `json:"msg"`
65 func levelString(level Level) string {
80 func getTime() int64 {
81 ns := time.Time.UnixNano(time.Now())
82 return ns / int64(time.Millisecond)
85 func (l *MdcLogger) formatLog(level Level, msg string) ([]byte, error) {
86 log := logEntry{getTime(), levelString(level), l.proc, l.mdc, msg}
87 buf := bytes.NewBuffer(nil)
88 encoder := json.NewEncoder(buf)
89 encoder.SetEscapeHTML(false)
90 err := encoder.Encode(log)
91 return buf.Bytes(), err
94 func initLogger(proc string, writer io.Writer) (*MdcLogger, error) {
95 return &MdcLogger{proc: proc, writer: writer, mdc: make(map[string]string), level: DEBUG}, nil
98 // InitLogger is the init routine which returns a new logger instance.
99 // The program identity is given as a parameter. The identity
100 // is added to every log writing.
101 // The function returns a new instance or an error.
102 func InitLogger(proc string) (*MdcLogger, error) {
103 return initLogger(proc, os.Stdout)
106 // Log is the basic logging function to write a log message with
108 func (l *MdcLogger) Log(level Level, formatMsg string, a ...interface{}) {
110 defer l.mutex.Unlock()
114 log, err := l.formatLog(level, fmt.Sprintf(formatMsg, a...))
120 // Error is the "error" level logging function.
121 func (l *MdcLogger) Error(formatMsg string, a ...interface{}) {
122 l.Log(ERR, formatMsg, a...)
125 // Warning is the "warning" level logging function.
126 func (l *MdcLogger) Warning(formatMsg string, a ...interface{}) {
127 l.Log(WARN, formatMsg, a...)
130 // Info is the "info" level logging function.
131 func (l *MdcLogger) Info(formatMsg string, a ...interface{}) {
132 l.Log(INFO, formatMsg, a...)
135 // Debug is the "debug" level logging function.
136 func (l *MdcLogger) Debug(formatMsg string, a ...interface{}) {
137 l.Log(DEBUG, formatMsg, a...)
140 // LevelSet sets the current logging level.
141 // Log writings with less significant level are discarded.
142 func (l *MdcLogger) LevelSet(level Level) {
146 // LevelGet returns the current logging level.
147 func (l *MdcLogger) LevelGet() Level {
151 // MdcAdd adds a new MDC key value pair to the logger.
152 func (l *MdcLogger) MdcAdd(key string, value string) {
154 defer l.mutex.Unlock()
158 // MdcRemove removes an MDC key from the logger.
159 func (l *MdcLogger) MdcRemove(key string) {
161 defer l.mutex.Unlock()
165 // MdcGet gets the value of an MDC from the logger.
166 // The function returns the value string and a boolean
167 // which tells if the key was found or not.
168 func (l *MdcLogger) MdcGet(key string) (string, bool) {
170 defer l.mutex.Unlock()
171 val, ok := l.mdc[key]
175 // MdcClean removes all MDC keys from the logger.
176 func (l *MdcLogger) MdcClean() {
178 defer l.mutex.Unlock()
179 l.mdc = make(map[string]string)