blob: 0cdfd2f3f8be46ac4225bc41c299ad90f57b03f7 [file] [log] [blame]
ss412g07ef76d2019-08-12 17:26:40 +03001//
2// Copyright 2019 AT&T Intellectual Property
3// Copyright 2019 Nokia
4//
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
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
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.
nm755n15d39822019-11-28 16:56:00 +000016
17// This source code is part of the near-RT RIC (RAN Intelligent Controller)
18// platform project (RICP).
19
ss412g07ef76d2019-08-12 17:26:40 +030020
21package logger
22
23import (
24 "fmt"
25 "go.uber.org/zap"
26 "go.uber.org/zap/zapcore"
27 "strings"
28 "time"
29)
30
31type Logger struct {
32 Logger *zap.Logger
33}
34
35// Copied from zap logger
36//
37// A Level is a logging priority. Higher levels are more important.
38type LogLevel int8
39
40const (
41 // DebugLevel logs are typically voluminous, and are usually disabled in
42 // production.
43 DebugLevel LogLevel = iota - 1
44 // InfoLevel is the default logging priority.
45 InfoLevel
46 // WarnLevel logs are more important than Info, but don't need individual
47 // human review.
48 WarnLevel
49 // ErrorLevel logs are high-priority. If an application is running smoothly,
50 // it shouldn't generate any error-level logs.
51 ErrorLevel
52 // DPanicLevel logs are particularly important errors. In development the
53 // logger panics after writing the message.
54 DPanicLevel
55 // PanicLevel logs a message, then panics.
56 PanicLevel
57 // FatalLevel logs a message, then calls os.Exit(1).
58 FatalLevel
59
60 _minLevel = DebugLevel
61 _maxLevel = FatalLevel
62)
63
64var logLevelTokenToLevel = map[string] LogLevel {
65 "debug" : DebugLevel,
66 "info": InfoLevel,
67 "warn": WarnLevel,
68 "error": ErrorLevel,
69 "dpanic": DPanicLevel,
70 "panic": PanicLevel,
71 "fatal": FatalLevel,
72}
73
74func LogLevelTokenToLevel(level string) (LogLevel, bool) {
75 if level, ok := logLevelTokenToLevel[strings.TrimSpace(strings.ToLower(level))];ok {
76 return level, true
77 }
78 return _maxLevel+1, false
79}
80
81func InitLogger(requested LogLevel) (*Logger, error) {
82 var logger *zap.Logger
83 var err error
84 switch requested {
85 case DebugLevel:
86 logger, err = initLoggerByLevel(zapcore.DebugLevel)
87 case InfoLevel:
88 logger, err = initLoggerByLevel(zapcore.InfoLevel)
89 case WarnLevel:
90 logger, err = initLoggerByLevel(zapcore.WarnLevel)
91 case ErrorLevel:
92 logger, err = initLoggerByLevel(zapcore.ErrorLevel)
93 case DPanicLevel:
94 logger, err = initLoggerByLevel(zapcore.DPanicLevel)
95 case PanicLevel:
96 logger, err = initLoggerByLevel(zapcore.PanicLevel)
97 case FatalLevel:
98 logger, err = initLoggerByLevel(zapcore.FatalLevel)
99 default:
100 err = fmt.Errorf("Invalid logging Level :%d",requested)
101 }
102 if err != nil {
103 return nil, err
104 }
105 return &Logger{Logger:logger}, nil
106
107}
108func(l *Logger)Sync() error {
109 l.Debugf("#logger.Sync - Going to flush buffered log")
110 return l.Logger.Sync()
111}
112
113func (l *Logger)Infof(formatMsg string, a ...interface{}) {
114 if l.InfoEnabled() {
115 msg := fmt.Sprintf(formatMsg, a...)
116 l.Logger.Info(msg, zap.Any("mdc", l.getTimeStampMdc()))
117 }
118}
119
120func (l *Logger)Debugf(formatMsg string, a ...interface{}) {
121 if l.DebugEnabled(){
122 msg := fmt.Sprintf(formatMsg, a...)
123 l.Logger.Debug(msg, zap.Any("mdc", l.getTimeStampMdc()))
124 }
125}
126
127func (l *Logger)Errorf(formatMsg string, a ...interface{}) {
128 msg := fmt.Sprintf(formatMsg, a...)
129 l.Logger.Error(msg, zap.Any("mdc", l.getTimeStampMdc()))
130}
131
132func (l *Logger)Warnf(formatMsg string, a ...interface{}) {
133 msg := fmt.Sprintf(formatMsg, a...)
134 l.Logger.Warn(msg, zap.Any("mdc", l.getTimeStampMdc()))
135}
136
137func (l *Logger) getTimeStampMdc() map[string]string {
138 timeStr := time.Now().Format("2006-01-02 15:04:05.000")
139 mdc := map[string]string{"time": timeStr}
140 return mdc
141}
142
143func (l *Logger)InfoEnabled()bool{
144 return l.Logger.Core().Enabled(zap.InfoLevel)
145}
146
147func (l *Logger)DebugEnabled()bool{
148 return l.Logger.Core().Enabled(zap.DebugLevel)
149}
150
151func (l *Logger)DPanicf(formatMsg string, a ...interface{}) {
152 msg := fmt.Sprintf(formatMsg, a...)
153 l.Logger.DPanic(msg, zap.Any("mdc", l.getTimeStampMdc()))
154}
155
156func initLoggerByLevel(l zapcore.Level) (*zap.Logger, error) {
157 cfg := zap.Config{
158 Encoding: "json",
159 Level: zap.NewAtomicLevelAt(l),
160 OutputPaths: []string{"stdout"},
161 ErrorOutputPaths: []string{"stderr"},
162 EncoderConfig: zapcore.EncoderConfig{
163 MessageKey: "msg",
164
165 LevelKey: "crit",
166 EncodeLevel: zapcore.CapitalLevelEncoder,
167
168 TimeKey: "ts",
169 EncodeTime: epochMillisIntegerTimeEncoder,
170
171 CallerKey: "id",
172 EncodeCaller: e2ManagerCallerEncoder,
173 },
174 }
175 return cfg.Build()
176}
177
178func e2ManagerCallerEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
179 enc.AppendString("E2Manager")
180}
181
182func epochMillisIntegerTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
183 nanos := t.UnixNano()
184 millis := int64(nanos) / int64(time.Millisecond)
185 enc.AppendInt64(millis)
186}
187