Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: grpc/logging/grpc_logger.go

Issue 2976583002: [grpc/logging] Update to LoggerV2. (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | grpc/logging/grpc_logger_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 // Package logging implements Logger, a gRPC glog.Logger implementation backed 5 // Package logging implements a gRPC glog.Logger implementation backed
6 // by a github.com/luci/luci-go/common/logging Logger. 6 // by a github.com/luci/luci-go/common/logging Logger.
7 //
8 // The logger can be installed by calling Install.
7 package logging 9 package logging
8 10
9 import ( 11 import (
10 "os" 12 "os"
11 "runtime" 13 "runtime"
12 "strings" 14 "strings"
13 15
14 » log "github.com/luci/luci-go/common/logging" 16 » "github.com/luci/luci-go/common/logging"
15 17
16 "google.golang.org/grpc/grpclog" 18 "google.golang.org/grpc/grpclog"
17 ) 19 )
18 20
21 // Suppress is a sentinel logging level that instructs the logger to suppress
22 // all non-fatal logging output. This is NOT a valid logging.Level, and should
23 // not be used as such.
24 var Suppress = logging.Level(logging.Error + 1)
25
19 type grpcLogger struct { 26 type grpcLogger struct {
20 » // Base is the base logger instance. 27 » base logging.Logger
21 » base log.Logger 28 » vLevel int
22
23 » // logPrints is true if Print statements should be logged.
24 » logPrints bool
25 } 29 }
26 30
27 // Install installs a logger as the gRPC library's logger. The installation is 31 // Install installs a logger as the gRPC library's logger. The installation is
28 // not protected by a mutex, so this must be set somewhere that atomic access is 32 // not protected by a mutex, so this must be set somewhere that atomic access is
29 // guaranteed. 33 // guaranteed.
30 func Install(base log.Logger, logPrints bool) { 34 //
31 » grpclog.SetLogger(&grpcLogger{ 35 // A special logging level, "Suppress", can be provided to suppress all
32 » » base: base, 36 // non-fatal logging output .
33 » » logPrints: logPrints, 37 //
38 // gRPC V=level and error terminology translation is as follows:
39 // - V=0, ERROR (low verbosity) is logged at logging.ERROR level.
40 // - V=1, WARNING (medium verbosity) is logged at logging.WARNING level.
41 // - V=2, INFO (high verbosity) is logged at logging.DEBUG level.
42 func Install(base logging.Logger, level logging.Level) {
43 » grpclog.SetLoggerV2(&grpcLogger{
44 » » base: base,
45 » » vLevel: translateLevel(level),
34 }) 46 })
35 } 47 }
36 48
37 func makeArgFormatString(args []interface{}) string { 49 func (gl *grpcLogger) Info(args ...interface{}) {
38 » if len(args) == 0 { 50 » if gl.V(2) {
39 » » return "" 51 » » gl.base.LogCall(logging.Debug, 2, makeArgFormatString(args), arg s)
40 } 52 }
41 » return strings.TrimSuffix(strings.Repeat("%v ", len(args)), " ") 53 }
54
55 func (gl *grpcLogger) Infof(format string, args ...interface{}) {
56 » if gl.V(2) {
57 » » gl.base.LogCall(logging.Debug, 2, format, args)
58 » }
59 }
60
61 func (gl *grpcLogger) Infoln(args ...interface{}) {
62 » if gl.V(2) {
63 » » gl.base.LogCall(logging.Debug, 2, makeArgFormatString(args), arg s)
64 » }
65 }
66
67 func (gl *grpcLogger) Warning(args ...interface{}) {
68 » if gl.V(1) {
69 » » gl.base.LogCall(logging.Warning, 2, makeArgFormatString(args), a rgs)
70 » }
71 }
72
73 func (gl *grpcLogger) Warningf(format string, args ...interface{}) {
74 » if gl.V(1) {
75 » » gl.base.LogCall(logging.Warning, 2, format, args)
76 » }
77 }
78
79 func (gl *grpcLogger) Warningln(args ...interface{}) {
80 » if gl.V(1) {
81 » » gl.base.LogCall(logging.Warning, 2, makeArgFormatString(args), a rgs)
82 » }
83 }
84
85 func (gl *grpcLogger) Error(args ...interface{}) {
86 » if gl.V(0) {
87 » » gl.base.LogCall(logging.Error, 2, makeArgFormatString(args), arg s)
88 » }
89 }
90
91 func (gl *grpcLogger) Errorf(format string, args ...interface{}) {
92 » if gl.V(0) {
93 » » gl.base.LogCall(logging.Error, 2, format, args)
94 » }
95 }
96
97 func (gl *grpcLogger) Errorln(args ...interface{}) {
98 » if gl.V(0) {
99 » » gl.base.LogCall(logging.Error, 2, makeArgFormatString(args), arg s)
100 » }
42 } 101 }
43 102
44 func (gl *grpcLogger) Fatal(args ...interface{}) { 103 func (gl *grpcLogger) Fatal(args ...interface{}) {
45 » gl.base.LogCall(log.Error, 2, makeArgFormatString(args), args) 104 » gl.base.LogCall(logging.Error, 2, makeArgFormatString(args), args)
46 gl.logStackTraceAndDie() 105 gl.logStackTraceAndDie()
47 } 106 }
48 107
49 func (gl *grpcLogger) Fatalf(format string, args ...interface{}) { 108 func (gl *grpcLogger) Fatalf(format string, args ...interface{}) {
50 » gl.base.LogCall(log.Error, 2, format, args) 109 » gl.base.LogCall(logging.Error, 2, format, args)
51 gl.logStackTraceAndDie() 110 gl.logStackTraceAndDie()
52 } 111 }
53 112
54 func (gl *grpcLogger) Fatalln(args ...interface{}) { 113 func (gl *grpcLogger) Fatalln(args ...interface{}) {
55 » gl.base.LogCall(log.Error, 2, makeArgFormatString(args), args) 114 » gl.base.LogCall(logging.Error, 2, makeArgFormatString(args), args)
56 gl.logStackTraceAndDie() 115 gl.logStackTraceAndDie()
57 } 116 }
58 117
59 func (gl *grpcLogger) Print(args ...interface{}) { 118 func (gl *grpcLogger) V(l int) bool {
60 » if !gl.logPrints { 119 » return gl.vLevel >= l
61 » » return
62 » }
63 » gl.base.LogCall(log.Info, 2, makeArgFormatString(args), args)
64 }
65
66 func (gl *grpcLogger) Printf(format string, args ...interface{}) {
67 » if !gl.logPrints {
68 » » return
69 » }
70 » gl.base.LogCall(log.Info, 2, format, args)
71 }
72
73 func (gl *grpcLogger) Println(args ...interface{}) {
74 » if !gl.logPrints {
75 » » return
76 » }
77 » gl.base.LogCall(log.Info, 2, makeArgFormatString(args), args)
78 } 120 }
79 121
80 func (gl *grpcLogger) logStackTraceAndDie() { 122 func (gl *grpcLogger) logStackTraceAndDie() {
81 » gl.base.LogCall(log.Error, 3, "Stack Trace:\n%s", []interface{}{stacks(t rue)}) 123 » gl.base.LogCall(logging.Error, 3, "Stack Trace:\n%s", []interface{}{stac ks(true)})
82 » osExit(255) 124 » fatalExit()
83 } 125 }
84 126
85 // osExit is an operating system exit function used by "Fatal" logs. It is a 127 // fatalExit is an operating system exit function used by "Fatal" logs. It is a
86 // variable here so it can be stubbed for testing. 128 // variable here so it can be stubbed for testing, but will exit with a non-zero
87 var osExit = func(rc int) { 129 // return code by default.
88 » os.Exit(rc) 130 var fatalExit = func() {
131 » os.Exit(1)
89 } 132 }
90 133
91 // stacks is a wrapper for runtime.Stack that attempts to recover the data for 134 // stacks is a wrapper for runtime.Stack that attempts to recover the data for
92 // all goroutines. 135 // all goroutines.
93 // 136 //
94 // This was copied from the glog library: 137 // This was copied from the glog library:
95 // https://github.com/golang/glog @ / 23def4e6c14b4da8ac2ed8007337bc5eb5007998 138 // https://github.com/golang/glog @ / 23def4e6c14b4da8ac2ed8007337bc5eb5007998
96 func stacks(all bool) []byte { 139 func stacks(all bool) []byte {
97 // We don't know how big the traces are, so grow a few times if they don 't fit. 140 // We don't know how big the traces are, so grow a few times if they don 't fit.
98 // Start large, though. 141 // Start large, though.
99 n := 10000 142 n := 10000
100 if all { 143 if all {
101 n = 100000 144 n = 100000
102 } 145 }
103 var trace []byte 146 var trace []byte
104 for i := 0; i < 5; i++ { 147 for i := 0; i < 5; i++ {
105 trace = make([]byte, n) 148 trace = make([]byte, n)
106 nbytes := runtime.Stack(trace, all) 149 nbytes := runtime.Stack(trace, all)
107 if nbytes < len(trace) { 150 if nbytes < len(trace) {
108 return trace[:nbytes] 151 return trace[:nbytes]
109 } 152 }
110 n *= 2 153 n *= 2
111 } 154 }
112 return trace 155 return trace
113 } 156 }
157
158 func makeArgFormatString(args []interface{}) string {
159 if len(args) == 0 {
160 return ""
161 }
162 return strings.TrimSuffix(strings.Repeat("%v ", len(args)), " ")
163 }
164
165 // translateLevel translates a "verbose level" to a logging level.
166 func translateLevel(l logging.Level) int {
167 switch l {
168 case Suppress:
169 return -1
170 case logging.Error:
171 return 0
172 case logging.Warning, logging.Info:
173 return 1
174 default:
175 return 2
176 }
177 }
OLDNEW
« no previous file with comments | « no previous file | grpc/logging/grpc_logger_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698