1 package grpc_zap_test
2
3 import (
4 "bytes"
5 "context"
6 "encoding/json"
7 "io"
8 "testing"
9
10 "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap"
11 grpc_ctxtags "github.com/grpc-ecosystem/go-grpc-middleware/tags"
12 grpc_testing "github.com/grpc-ecosystem/go-grpc-middleware/testing"
13 pb_testproto "github.com/grpc-ecosystem/go-grpc-middleware/testing/testproto"
14 "go.uber.org/zap"
15 "go.uber.org/zap/zapcore"
16 "google.golang.org/grpc/codes"
17 )
18
19 var (
20 goodPing = &pb_testproto.PingRequest{Value: "something", SleepTimeMs: 9999}
21 )
22
23 type loggingPingService struct {
24 pb_testproto.TestServiceServer
25 }
26
27 func (s *loggingPingService) Ping(ctx context.Context, ping *pb_testproto.PingRequest) (*pb_testproto.PingResponse, error) {
28 grpc_ctxtags.Extract(ctx).Set("custom_tags.string", "something").Set("custom_tags.int", 1337)
29 ctxzap.AddFields(ctx, zap.String("custom_field", "custom_value"))
30 ctxzap.Extract(ctx).Info("some ping")
31 return s.TestServiceServer.Ping(ctx, ping)
32 }
33
34 func (s *loggingPingService) PingError(ctx context.Context, ping *pb_testproto.PingRequest) (*pb_testproto.Empty, error) {
35 return s.TestServiceServer.PingError(ctx, ping)
36 }
37
38 func (s *loggingPingService) PingList(ping *pb_testproto.PingRequest, stream pb_testproto.TestService_PingListServer) error {
39 grpc_ctxtags.Extract(stream.Context()).Set("custom_tags.string", "something").Set("custom_tags.int", 1337)
40 ctxzap.Extract(stream.Context()).Info("some pinglist")
41 return s.TestServiceServer.PingList(ping, stream)
42 }
43
44 func (s *loggingPingService) PingEmpty(ctx context.Context, empty *pb_testproto.Empty) (*pb_testproto.PingResponse, error) {
45 return s.TestServiceServer.PingEmpty(ctx, empty)
46 }
47
48 func newBaseZapSuite(t *testing.T) *zapBaseSuite {
49 b := &bytes.Buffer{}
50 muB := grpc_testing.NewMutexReadWriter(b)
51 zap.NewDevelopmentConfig()
52 jsonEncoder := zapcore.NewJSONEncoder(zapcore.EncoderConfig{
53 TimeKey: "ts",
54 LevelKey: "level",
55 NameKey: "logger",
56 CallerKey: "caller",
57 MessageKey: "msg",
58 StacktraceKey: "stacktrace",
59 EncodeLevel: zapcore.LowercaseLevelEncoder,
60 EncodeTime: zapcore.EpochTimeEncoder,
61 EncodeDuration: zapcore.SecondsDurationEncoder,
62 })
63 core := zapcore.NewCore(jsonEncoder, zapcore.AddSync(muB), zap.LevelEnablerFunc(func(zapcore.Level) bool { return true }))
64 log := zap.New(core)
65 s := &zapBaseSuite{
66 log: log,
67 buffer: b,
68 mutexBuffer: muB,
69 InterceptorTestSuite: &grpc_testing.InterceptorTestSuite{
70 TestService: &loggingPingService{&grpc_testing.TestPingService{T: t}},
71 },
72 }
73 return s
74 }
75
76 type zapBaseSuite struct {
77 *grpc_testing.InterceptorTestSuite
78 mutexBuffer *grpc_testing.MutexReadWriter
79 buffer *bytes.Buffer
80 log *zap.Logger
81 timestampFormat string
82 }
83
84 func (s *zapBaseSuite) SetupTest() {
85 s.mutexBuffer.Lock()
86 s.buffer.Reset()
87 s.mutexBuffer.Unlock()
88 }
89
90 func (s *zapBaseSuite) getOutputJSONs() []map[string]interface{} {
91 ret := make([]map[string]interface{}, 0)
92 dec := json.NewDecoder(s.mutexBuffer)
93
94 for {
95 var val map[string]interface{}
96 err := dec.Decode(&val)
97 if err == io.EOF {
98 break
99 }
100 if err != nil {
101 s.T().Fatalf("failed decoding output from Logrus JSON: %v", err)
102 }
103
104 ret = append(ret, val)
105 }
106
107 return ret
108 }
109
110 func StubMessageProducer(ctx context.Context, msg string, level zapcore.Level, code codes.Code, err error, duration zapcore.Field) {
111
112 ctxzap.Extract(ctx).Check(level, "custom message").Write(
113 zap.Error(err),
114 zap.String("grpc.code", code.String()),
115 duration,
116 )
117 }
118
View as plain text