/
zap.go
124 lines (106 loc) · 3.36 KB
/
zap.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2018 Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package stdio // import "istio.io/istio/mixer/adapter/stdio"
import (
"os"
"time"
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"istio.io/istio/mixer/adapter/stdio/config"
)
var levelToZap = map[config.Params_Level]zapcore.Level{
config.INFO: zapcore.InfoLevel,
config.WARNING: zapcore.WarnLevel,
config.ERROR: zapcore.ErrorLevel,
}
// Creates a zap core based on the given options
func newZapCore(options *config.Params) (zapcore.Core, func(), error) {
encCfg := zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
NameKey: "instance",
CallerKey: "caller",
StacktraceKey: "stack",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.LowercaseLevelEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
EncodeDuration: zapcore.StringDurationEncoder,
EncodeTime: formatDate,
}
var enc zapcore.Encoder
if options.OutputAsJson {
enc = zapcore.NewJSONEncoder(encCfg)
} else {
enc = zapcore.NewConsoleEncoder(encCfg)
}
var outputSink zapcore.WriteSyncer
var err error
var closer = func() {}
switch options.LogStream {
case config.ROTATED_FILE:
lj := &lumberjack.Logger{
Filename: options.OutputPath,
MaxSize: int(options.MaxMegabytesBeforeRotation),
MaxBackups: int(options.MaxDaysBeforeRotation),
MaxAge: int(options.MaxRotatedFiles),
}
outputSink = zapcore.AddSync(lj)
closer = func() { _ = lj.Close() }
case config.FILE:
if outputSink, closer, err = zap.Open(options.OutputPath); err != nil {
return nil, nil, err
}
case config.STDOUT:
outputSink = os.Stdout
case config.STDERR:
outputSink = os.Stderr
}
return zapcore.NewCore(enc, outputSink, zap.NewAtomicLevelAt(levelToZap[options.OutputLevel])), closer, nil
}
func formatDate(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
t = t.UTC()
year, month, day := t.Date()
hour, minute, second := t.Clock()
micros := t.Nanosecond() / 1000
buf := make([]byte, 27)
buf[0] = byte((year/1000)%10) + '0'
buf[1] = byte((year/100)%10) + '0'
buf[2] = byte((year/10)%10) + '0'
buf[3] = byte(year%10) + '0'
buf[4] = '-'
buf[5] = byte((month)/10) + '0'
buf[6] = byte((month)%10) + '0'
buf[7] = '-'
buf[8] = byte((day)/10) + '0'
buf[9] = byte((day)%10) + '0'
buf[10] = 'T'
buf[11] = byte((hour)/10) + '0'
buf[12] = byte((hour)%10) + '0'
buf[13] = ':'
buf[14] = byte((minute)/10) + '0'
buf[15] = byte((minute)%10) + '0'
buf[16] = ':'
buf[17] = byte((second)/10) + '0'
buf[18] = byte((second)%10) + '0'
buf[19] = '.'
buf[20] = byte((micros/100000)%10) + '0'
buf[21] = byte((micros/10000)%10) + '0'
buf[22] = byte((micros/1000)%10) + '0'
buf[23] = byte((micros/100)%10) + '0'
buf[24] = byte((micros/10)%10) + '0'
buf[25] = byte((micros)%10) + '0'
buf[26] = 'Z'
enc.AppendString(string(buf))
}