05730f719f7857b3f84ea63521b755d74e9b506c
[ric-plt/resource-status-manager.git] / RSM / logger / logger.go
1 //
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
18 package logger
19
20 import (
21         "fmt"
22         "go.uber.org/zap"
23         "go.uber.org/zap/zapcore"
24         "strings"
25         "time"
26 )
27
28 type 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.
35 type LogLevel int8
36
37 const (
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
61 var 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
71 func 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
78 func 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 }
105 func(l *Logger)Sync() error {
106         l.Debugf("#logger.Sync - Going to flush buffered log")
107         return l.Logger.Sync()
108 }
109
110 func (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
117 func (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
124 func (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
129 func (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
134 func (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
140 func (l *Logger)InfoEnabled()bool{
141         return l.Logger.Core().Enabled(zap.InfoLevel)
142 }
143
144 func (l *Logger)DebugEnabled()bool{
145         return l.Logger.Core().Enabled(zap.DebugLevel)
146 }
147
148 func (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
153 func 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: rsmCallerEncoder,
170                 },
171         }
172         return cfg.Build()
173 }
174
175 func rsmCallerEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
176         enc.AppendString("RSM")
177 }
178
179 func epochMillisIntegerTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
180         nanos := t.UnixNano()
181         millis := int64(nanos) / int64(time.Millisecond)
182         enc.AppendInt64(millis)
183 }
184