123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- /*
- *
- * Copyright 2018 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
- // Package binarylog implementation binary logging as defined in
- // https://github.com/grpc/proposal/blob/master/A16-binary-logging.md.
- package binarylog
- import (
- "fmt"
- "os"
- "google.golang.org/grpc/grpclog"
- "google.golang.org/grpc/internal/grpcutil"
- )
- var grpclogLogger = grpclog.Component("binarylog")
- // Logger specifies MethodLoggers for method names with a Log call that
- // takes a context.
- //
- // This is used in the 1.0 release of gcp/observability, and thus must not be
- // deleted or changed.
- type Logger interface {
- GetMethodLogger(methodName string) MethodLogger
- }
- // binLogger is the global binary logger for the binary. One of this should be
- // built at init time from the configuration (environment variable or flags).
- //
- // It is used to get a MethodLogger for each individual method.
- var binLogger Logger
- // SetLogger sets the binary logger.
- //
- // Only call this at init time.
- func SetLogger(l Logger) {
- binLogger = l
- }
- // GetLogger gets the binary logger.
- //
- // Only call this at init time.
- func GetLogger() Logger {
- return binLogger
- }
- // GetMethodLogger returns the MethodLogger for the given methodName.
- //
- // methodName should be in the format of "/service/method".
- //
- // Each MethodLogger returned by this method is a new instance. This is to
- // generate sequence id within the call.
- func GetMethodLogger(methodName string) MethodLogger {
- if binLogger == nil {
- return nil
- }
- return binLogger.GetMethodLogger(methodName)
- }
- func init() {
- const envStr = "GRPC_BINARY_LOG_FILTER"
- configStr := os.Getenv(envStr)
- binLogger = NewLoggerFromConfigString(configStr)
- }
- // MethodLoggerConfig contains the setting for logging behavior of a method
- // logger. Currently, it contains the max length of header and message.
- type MethodLoggerConfig struct {
- // Max length of header and message.
- Header, Message uint64
- }
- // LoggerConfig contains the config for loggers to create method loggers.
- type LoggerConfig struct {
- All *MethodLoggerConfig
- Services map[string]*MethodLoggerConfig
- Methods map[string]*MethodLoggerConfig
- Blacklist map[string]struct{}
- }
- type logger struct {
- config LoggerConfig
- }
- // NewLoggerFromConfig builds a logger with the given LoggerConfig.
- func NewLoggerFromConfig(config LoggerConfig) Logger {
- return &logger{config: config}
- }
- // newEmptyLogger creates an empty logger. The map fields need to be filled in
- // using the set* functions.
- func newEmptyLogger() *logger {
- return &logger{}
- }
- // Set method logger for "*".
- func (l *logger) setDefaultMethodLogger(ml *MethodLoggerConfig) error {
- if l.config.All != nil {
- return fmt.Errorf("conflicting global rules found")
- }
- l.config.All = ml
- return nil
- }
- // Set method logger for "service/*".
- //
- // New MethodLogger with same service overrides the old one.
- func (l *logger) setServiceMethodLogger(service string, ml *MethodLoggerConfig) error {
- if _, ok := l.config.Services[service]; ok {
- return fmt.Errorf("conflicting service rules for service %v found", service)
- }
- if l.config.Services == nil {
- l.config.Services = make(map[string]*MethodLoggerConfig)
- }
- l.config.Services[service] = ml
- return nil
- }
- // Set method logger for "service/method".
- //
- // New MethodLogger with same method overrides the old one.
- func (l *logger) setMethodMethodLogger(method string, ml *MethodLoggerConfig) error {
- if _, ok := l.config.Blacklist[method]; ok {
- return fmt.Errorf("conflicting blacklist rules for method %v found", method)
- }
- if _, ok := l.config.Methods[method]; ok {
- return fmt.Errorf("conflicting method rules for method %v found", method)
- }
- if l.config.Methods == nil {
- l.config.Methods = make(map[string]*MethodLoggerConfig)
- }
- l.config.Methods[method] = ml
- return nil
- }
- // Set blacklist method for "-service/method".
- func (l *logger) setBlacklist(method string) error {
- if _, ok := l.config.Blacklist[method]; ok {
- return fmt.Errorf("conflicting blacklist rules for method %v found", method)
- }
- if _, ok := l.config.Methods[method]; ok {
- return fmt.Errorf("conflicting method rules for method %v found", method)
- }
- if l.config.Blacklist == nil {
- l.config.Blacklist = make(map[string]struct{})
- }
- l.config.Blacklist[method] = struct{}{}
- return nil
- }
- // getMethodLogger returns the MethodLogger for the given methodName.
- //
- // methodName should be in the format of "/service/method".
- //
- // Each MethodLogger returned by this method is a new instance. This is to
- // generate sequence id within the call.
- func (l *logger) GetMethodLogger(methodName string) MethodLogger {
- s, m, err := grpcutil.ParseMethod(methodName)
- if err != nil {
- grpclogLogger.Infof("binarylogging: failed to parse %q: %v", methodName, err)
- return nil
- }
- if ml, ok := l.config.Methods[s+"/"+m]; ok {
- return NewTruncatingMethodLogger(ml.Header, ml.Message)
- }
- if _, ok := l.config.Blacklist[s+"/"+m]; ok {
- return nil
- }
- if ml, ok := l.config.Services[s]; ok {
- return NewTruncatingMethodLogger(ml.Header, ml.Message)
- }
- if l.config.All == nil {
- return nil
- }
- return NewTruncatingMethodLogger(l.config.All.Header, l.config.All.Message)
- }
|