-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathctxlog.go
178 lines (154 loc) · 4.02 KB
/
ctxlog.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package glog
import (
"context"
"errors"
"sync"
"time"
"github.com/gw123/glog/common"
"go.opentelemetry.io/otel/trace"
)
type ctxLoggerMarker struct{}
type ctxLogger struct {
logger common.Logger
fields map[string]interface{}
topFields map[string]interface{}
mutex sync.RWMutex
lastTime time.Time
}
var IsDebug bool = false
var (
ctxLoggerKey = &ctxLoggerMarker{}
)
// AddFields 添加日志字段到日志中间件(ctx_logrus),添加的字段会在后面调用 info,debug,error 时候输出
func AddFields(ctx context.Context, fields map[string]interface{}) {
l, ok := ctx.Value(ctxLoggerKey).(*ctxLogger)
if !ok || l == nil {
return
}
l.mutex.Lock()
for k, v := range fields {
l.fields[k] = v
}
l.mutex.Unlock()
}
func AddTopField(ctx context.Context, key string, val interface{}) {
l, ok := ctx.Value(ctxLoggerKey).(*ctxLogger)
if !ok || l == nil {
return
}
l.mutex.Lock()
l.topFields[key] = val
l.mutex.Unlock()
}
// 添加日志字段到日志中间件(ctx_logrus),添加的字段会在后面调用 info,debug,error 时候输出
func AddField(ctx context.Context, key string, val interface{}) {
l, ok := ctx.Value(ctxLoggerKey).(*ctxLogger)
if !ok || l == nil {
return
}
l.mutex.Lock()
l.fields[key] = val
l.mutex.Unlock()
}
// AddTraceID 添加一个追踪规矩id 用来聚合同一次请求, 注意要用返回的contxt 替换传入的ctx
func AddTraceID(ctx context.Context, traceID string) {
AddTopField(ctx, common.KeyTraceID, traceID)
}
// ExtractTraceID requestID
func ExtractTraceID(ctx context.Context) string {
l, ok := ctx.Value(ctxLoggerKey).(*ctxLogger)
if !ok || l == nil {
if IsDebug {
panic(errors.New("not set ctxLogger"))
}
return ""
}
l.mutex.RLock()
val, ok := l.topFields[common.KeyTraceID].(string)
l.mutex.RUnlock()
if ok {
return val
}
return ""
}
// WithOTEL Otel traceID
func WithOTEL(ctx context.Context) common.Logger {
l, ok := ctx.Value(ctxLoggerKey).(*ctxLogger)
var logger common.Logger
if !ok || l == nil {
logger = DefaultLogger()
} else {
logger = l.logger
}
if span := trace.SpanContextFromContext(ctx); span.TraceID().IsValid() {
return logger.WithField("trace_id", span.TraceID().String())
}
return logger
}
// AddUserID add userID to ctx
func AddUserID(ctx context.Context, userID int64) {
AddTopField(ctx, common.KeyUserID, userID)
}
// ExtractUserID userID
func ExtractUserID(ctx context.Context) int64 {
l, ok := ctx.Value(ctxLoggerKey).(*ctxLogger)
if !ok || l == nil {
if IsDebug {
panic(errors.New("not set ctxLogger"))
}
return 0
}
l.mutex.RLock()
val, ok := l.topFields[common.KeyUserID].(int64)
l.mutex.RUnlock()
if ok {
return val
}
return val
}
// AddPathname add userID to ctx
func AddPathname(ctx context.Context, pathname string) {
AddTopField(ctx, common.KeyPathname, pathname)
}
// ExtractPathname pathname
func ExtractPathname(ctx context.Context) string {
l, ok := ctx.Value(ctxLoggerKey).(*ctxLogger)
if !ok || l == nil {
if IsDebug {
panic(errors.New("not set ctxLogger"))
}
return ""
}
l.mutex.RLock()
val, ok := l.topFields[common.KeyPathname].(string)
l.mutex.RUnlock()
if ok {
return val
}
return val
}
// ToContext 添加logrus.Entry到context, 这个操作添加的logrus.Entry在后面AddFields和Extract都会使用到
func ToContext(ctx context.Context, entry common.Logger) context.Context {
l := &ctxLogger{
logger: entry,
fields: map[string]interface{}{},
topFields: map[string]interface{}{},
mutex: sync.RWMutex{},
lastTime: time.Time{},
}
return context.WithValue(ctx, ctxLoggerKey, l)
}
// ExtractEntry extract ctx_logrus logrus_driver.Entry
func ExtractEntry(ctx context.Context) common.Logger {
var logger common.Logger
l, ok := ctx.Value(ctxLoggerKey).(*ctxLogger)
if ok && l != nil {
logger = l.logger.WithFields(l.topFields).WithFields(l.fields)
} else {
logger = DefaultLogger()
}
if span := trace.SpanContextFromContext(ctx); span.TraceID().IsValid() {
return logger.WithField("trace_id", span.TraceID().String())
}
return logger
}