3
* Copyright 2018 gRPC authors.
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
9
* http://www.apache.org/licenses/LICENSE-2.0
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.
19
// Package binarylog implementation binary logging as defined in
20
// https://github.com/grpc/proposal/blob/master/A16-binary-logging.md.
27
"google.golang.org/grpc/grpclog"
28
"google.golang.org/grpc/internal/grpcutil"
31
// Logger is the global binary logger. It can be used to get binary logger for
33
type Logger interface {
34
getMethodLogger(methodName string) *MethodLogger
37
// binLogger is the global binary logger for the binary. One of this should be
38
// built at init time from the configuration (environment variable or flags).
40
// It is used to get a methodLogger for each individual method.
43
var grpclogLogger = grpclog.Component("binarylog")
45
// SetLogger sets the binarg logger.
47
// Only call this at init time.
48
func SetLogger(l Logger) {
52
// GetMethodLogger returns the methodLogger for the given methodName.
54
// methodName should be in the format of "/service/method".
56
// Each methodLogger returned by this method is a new instance. This is to
57
// generate sequence id within the call.
58
func GetMethodLogger(methodName string) *MethodLogger {
62
return binLogger.getMethodLogger(methodName)
66
const envStr = "GRPC_BINARY_LOG_FILTER"
67
configStr := os.Getenv(envStr)
68
binLogger = NewLoggerFromConfigString(configStr)
71
type methodLoggerConfig struct {
72
// Max length of header and message.
77
all *methodLoggerConfig
78
services map[string]*methodLoggerConfig
79
methods map[string]*methodLoggerConfig
81
blacklist map[string]struct{}
84
// newEmptyLogger creates an empty logger. The map fields need to be filled in
85
// using the set* functions.
86
func newEmptyLogger() *logger {
90
// Set method logger for "*".
91
func (l *logger) setDefaultMethodLogger(ml *methodLoggerConfig) error {
93
return fmt.Errorf("conflicting global rules found")
99
// Set method logger for "service/*".
101
// New methodLogger with same service overrides the old one.
102
func (l *logger) setServiceMethodLogger(service string, ml *methodLoggerConfig) error {
103
if _, ok := l.services[service]; ok {
104
return fmt.Errorf("conflicting service rules for service %v found", service)
106
if l.services == nil {
107
l.services = make(map[string]*methodLoggerConfig)
109
l.services[service] = ml
113
// Set method logger for "service/method".
115
// New methodLogger with same method overrides the old one.
116
func (l *logger) setMethodMethodLogger(method string, ml *methodLoggerConfig) error {
117
if _, ok := l.blacklist[method]; ok {
118
return fmt.Errorf("conflicting blacklist rules for method %v found", method)
120
if _, ok := l.methods[method]; ok {
121
return fmt.Errorf("conflicting method rules for method %v found", method)
123
if l.methods == nil {
124
l.methods = make(map[string]*methodLoggerConfig)
126
l.methods[method] = ml
130
// Set blacklist method for "-service/method".
131
func (l *logger) setBlacklist(method string) error {
132
if _, ok := l.blacklist[method]; ok {
133
return fmt.Errorf("conflicting blacklist rules for method %v found", method)
135
if _, ok := l.methods[method]; ok {
136
return fmt.Errorf("conflicting method rules for method %v found", method)
138
if l.blacklist == nil {
139
l.blacklist = make(map[string]struct{})
141
l.blacklist[method] = struct{}{}
145
// getMethodLogger returns the methodLogger for the given methodName.
147
// methodName should be in the format of "/service/method".
149
// Each methodLogger returned by this method is a new instance. This is to
150
// generate sequence id within the call.
151
func (l *logger) getMethodLogger(methodName string) *MethodLogger {
152
s, m, err := grpcutil.ParseMethod(methodName)
154
grpclogLogger.Infof("binarylogging: failed to parse %q: %v", methodName, err)
157
if ml, ok := l.methods[s+"/"+m]; ok {
158
return newMethodLogger(ml.hdr, ml.msg)
160
if _, ok := l.blacklist[s+"/"+m]; ok {
163
if ml, ok := l.services[s]; ok {
164
return newMethodLogger(ml.hdr, ml.msg)
169
return newMethodLogger(l.all.hdr, l.all.msg)