]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/google.golang.org/grpc/internal/binarylog/binarylog.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / google.golang.org / grpc / internal / binarylog / binarylog.go
1 /*
2 *
3 * Copyright 2018 gRPC authors.
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
19 // Package binarylog implementation binary logging as defined in
20 // https://github.com/grpc/proposal/blob/master/A16-binary-logging.md.
21 package binarylog
22
23 import (
24 "fmt"
25 "os"
26
27 "google.golang.org/grpc/grpclog"
28 )
29
30 // Logger is the global binary logger. It can be used to get binary logger for
31 // each method.
32 type Logger interface {
33 getMethodLogger(methodName string) *MethodLogger
34 }
35
36 // binLogger is the global binary logger for the binary. One of this should be
37 // built at init time from the configuration (environment varialbe or flags).
38 //
39 // It is used to get a methodLogger for each individual method.
40 var binLogger Logger
41
42 // SetLogger sets the binarg logger.
43 //
44 // Only call this at init time.
45 func SetLogger(l Logger) {
46 binLogger = l
47 }
48
49 // GetMethodLogger returns the methodLogger for the given methodName.
50 //
51 // methodName should be in the format of "/service/method".
52 //
53 // Each methodLogger returned by this method is a new instance. This is to
54 // generate sequence id within the call.
55 func GetMethodLogger(methodName string) *MethodLogger {
56 if binLogger == nil {
57 return nil
58 }
59 return binLogger.getMethodLogger(methodName)
60 }
61
62 func init() {
63 const envStr = "GRPC_BINARY_LOG_FILTER"
64 configStr := os.Getenv(envStr)
65 binLogger = NewLoggerFromConfigString(configStr)
66 }
67
68 type methodLoggerConfig struct {
69 // Max length of header and message.
70 hdr, msg uint64
71 }
72
73 type logger struct {
74 all *methodLoggerConfig
75 services map[string]*methodLoggerConfig
76 methods map[string]*methodLoggerConfig
77
78 blacklist map[string]struct{}
79 }
80
81 // newEmptyLogger creates an empty logger. The map fields need to be filled in
82 // using the set* functions.
83 func newEmptyLogger() *logger {
84 return &logger{}
85 }
86
87 // Set method logger for "*".
88 func (l *logger) setDefaultMethodLogger(ml *methodLoggerConfig) error {
89 if l.all != nil {
90 return fmt.Errorf("conflicting global rules found")
91 }
92 l.all = ml
93 return nil
94 }
95
96 // Set method logger for "service/*".
97 //
98 // New methodLogger with same service overrides the old one.
99 func (l *logger) setServiceMethodLogger(service string, ml *methodLoggerConfig) error {
100 if _, ok := l.services[service]; ok {
101 return fmt.Errorf("conflicting rules for service %v found", service)
102 }
103 if l.services == nil {
104 l.services = make(map[string]*methodLoggerConfig)
105 }
106 l.services[service] = ml
107 return nil
108 }
109
110 // Set method logger for "service/method".
111 //
112 // New methodLogger with same method overrides the old one.
113 func (l *logger) setMethodMethodLogger(method string, ml *methodLoggerConfig) error {
114 if _, ok := l.blacklist[method]; ok {
115 return fmt.Errorf("conflicting rules for method %v found", method)
116 }
117 if _, ok := l.methods[method]; ok {
118 return fmt.Errorf("conflicting rules for method %v found", method)
119 }
120 if l.methods == nil {
121 l.methods = make(map[string]*methodLoggerConfig)
122 }
123 l.methods[method] = ml
124 return nil
125 }
126
127 // Set blacklist method for "-service/method".
128 func (l *logger) setBlacklist(method string) error {
129 if _, ok := l.blacklist[method]; ok {
130 return fmt.Errorf("conflicting rules for method %v found", method)
131 }
132 if _, ok := l.methods[method]; ok {
133 return fmt.Errorf("conflicting rules for method %v found", method)
134 }
135 if l.blacklist == nil {
136 l.blacklist = make(map[string]struct{})
137 }
138 l.blacklist[method] = struct{}{}
139 return nil
140 }
141
142 // getMethodLogger returns the methodLogger for the given methodName.
143 //
144 // methodName should be in the format of "/service/method".
145 //
146 // Each methodLogger returned by this method is a new instance. This is to
147 // generate sequence id within the call.
148 func (l *logger) getMethodLogger(methodName string) *MethodLogger {
149 s, m, err := parseMethodName(methodName)
150 if err != nil {
151 grpclog.Infof("binarylogging: failed to parse %q: %v", methodName, err)
152 return nil
153 }
154 if ml, ok := l.methods[s+"/"+m]; ok {
155 return newMethodLogger(ml.hdr, ml.msg)
156 }
157 if _, ok := l.blacklist[s+"/"+m]; ok {
158 return nil
159 }
160 if ml, ok := l.services[s]; ok {
161 return newMethodLogger(ml.hdr, ml.msg)
162 }
163 if l.all == nil {
164 return nil
165 }
166 return newMethodLogger(l.all.hdr, l.all.msg)
167 }