/* * * 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 binarylogimport ()// NewLoggerFromConfigString reads the string and build a logger. It can be used// to build a new logger and assign it to binarylog.Logger.//// Example filter config strings:// - "" Nothing will be logged// - "*" All headers and messages will be fully logged.// - "*{h}" Only headers will be logged.// - "*{m:256}" Only the first 256 bytes of each message will be logged.// - "Foo/*" Logs every method in service Foo// - "Foo/*,-Foo/Bar" Logs every method in service Foo except method /Foo/Bar// - "Foo/*,Foo/Bar{m:256}" Logs the first 256 bytes of each message in method// /Foo/Bar, logs all headers and messages in every other method in service// Foo.//// If two configs exist for one certain method or service, the one specified// later overrides the previous config.func ( string) Logger {if == "" {returnnil } := newEmptyLogger() := strings.Split(, ",")for , := range {if := .fillMethodLoggerWithConfigString(); != nil {grpclogLogger.Warningf("failed to parse binary log config: %v", )returnnil } }return}// fillMethodLoggerWithConfigString parses config, creates TruncatingMethodLogger and adds// it to the right map in the logger.func ( *logger) ( string) error {// "" is invalid.if == "" {returnerrors.New("empty string is not a valid method binary logging config") }// "-service/method", blacklist, no * or {} allowed.if [0] == '-' { , , , := parseMethodConfigAndSuffix([1:])if != nil {returnfmt.Errorf("invalid config: %q, %v", , ) }if == "*" {returnfmt.Errorf("invalid config: %q, %v", , "* not allowed in blacklist config") }if != "" {returnfmt.Errorf("invalid config: %q, %v", , "header/message limit not allowed in blacklist config") }if := .setBlacklist( + "/" + ); != nil {returnfmt.Errorf("invalid config: %v", ) }returnnil }// "*{h:256;m:256}"if [0] == '*' { , , := parseHeaderMessageLengthConfig([1:])if != nil {returnfmt.Errorf("invalid config: %q, %v", , ) }if := .setDefaultMethodLogger(&MethodLoggerConfig{Header: , Message: }); != nil {returnfmt.Errorf("invalid config: %v", ) }returnnil } , , , := parseMethodConfigAndSuffix()if != nil {returnfmt.Errorf("invalid config: %q, %v", , ) } , , := parseHeaderMessageLengthConfig()if != nil {returnfmt.Errorf("invalid header/message length config: %q, %v", , ) }if == "*" {if := .setServiceMethodLogger(, &MethodLoggerConfig{Header: , Message: }); != nil {returnfmt.Errorf("invalid config: %v", ) } } else {if := .setMethodMethodLogger(+"/"+, &MethodLoggerConfig{Header: , Message: }); != nil {returnfmt.Errorf("invalid config: %v", ) } }returnnil}const (// TODO: this const is only used by env_config now. But could be useful for // other config. Move to binarylog.go if necessary. maxUInt = ^uint64(0)// For "p.s/m" plus any suffix. Suffix will be parsed again. See test for // expected output. longMethodConfigRegexpStr = `^([\w./]+)/((?:\w+)|[*])(.+)?$`// For suffix from above, "{h:123,m:123}". See test for expected output. optionalLengthRegexpStr = `(?::(\d+))?`// Optional ":123". headerConfigRegexpStr = `^{h` + optionalLengthRegexpStr + `}$` messageConfigRegexpStr = `^{m` + optionalLengthRegexpStr + `}$` headerMessageConfigRegexpStr = `^{h` + optionalLengthRegexpStr + `;m` + optionalLengthRegexpStr + `}$`)var ( longMethodConfigRegexp = regexp.MustCompile(longMethodConfigRegexpStr) headerConfigRegexp = regexp.MustCompile(headerConfigRegexpStr) messageConfigRegexp = regexp.MustCompile(messageConfigRegexpStr) headerMessageConfigRegexp = regexp.MustCompile(headerMessageConfigRegexpStr))// Turn "service/method{h;m}" into "service", "method", "{h;m}".func parseMethodConfigAndSuffix( string) (, , string, error) {// Regexp result: // // in: "p.s/m{h:123,m:123}", // out: []string{"p.s/m{h:123,m:123}", "p.s", "m", "{h:123,m:123}"}, := longMethodConfigRegexp.FindStringSubmatch()if == nil {return"", "", "", fmt.Errorf("%q contains invalid substring", ) } = [1] = [2] = [3]return}// Turn "{h:123;m:345}" into 123, 345.//// Return maxUInt if length is unspecified.func parseHeaderMessageLengthConfig( string) (, uint64, error) {if == "" {returnmaxUInt, maxUInt, nil }// Header config only.if := headerConfigRegexp.FindStringSubmatch(); != nil {if := [1]; != "" { , = strconv.ParseUint(, 10, 64)if != nil {return0, 0, fmt.Errorf("failed to convert %q to uint", ) }return , 0, nil }returnmaxUInt, 0, nil }// Message config only.if := messageConfigRegexp.FindStringSubmatch(); != nil {if := [1]; != "" { , = strconv.ParseUint(, 10, 64)if != nil {return0, 0, fmt.Errorf("failed to convert %q to uint", ) }return0, , nil }return0, maxUInt, nil }// Header and message config both.if := headerMessageConfigRegexp.FindStringSubmatch(); != nil {// Both hdr and msg are specified, but one or two of them might be empty. = maxUInt = maxUIntif := [1]; != "" { , = strconv.ParseUint(, 10, 64)if != nil {return0, 0, fmt.Errorf("failed to convert %q to uint", ) } }if := [2]; != "" { , = strconv.ParseUint(, 10, 64)if != nil {return0, 0, fmt.Errorf("failed to convert %q to uint", ) } }return , , nil }return0, 0, fmt.Errorf("%q contains invalid substring", )}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.