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