mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
36
vendor/google.golang.org/grpc/internal/binarylog/binarylog.go
generated
vendored
36
vendor/google.golang.org/grpc/internal/binarylog/binarylog.go
generated
vendored
@ -27,16 +27,42 @@ import (
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
// Logger is the global binary logger for the binary. One of this should be
|
||||
// Logger is the global binary logger. It can be used to get binary logger for
|
||||
// each method.
|
||||
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 varialbe or flags).
|
||||
//
|
||||
// It is used to get a methodLogger for each individual method.
|
||||
var Logger *logger
|
||||
var binLogger Logger
|
||||
|
||||
// SetLogger sets the binarg logger.
|
||||
//
|
||||
// Only call this at init time.
|
||||
func SetLogger(l Logger) {
|
||||
binLogger = l
|
||||
}
|
||||
|
||||
// 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)
|
||||
Logger = newLoggerFromConfigString(configStr)
|
||||
binLogger = NewLoggerFromConfigString(configStr)
|
||||
}
|
||||
|
||||
type methodLoggerConfig struct {
|
||||
@ -113,13 +139,13 @@ func (l *logger) setBlacklist(method string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMethodLogger returns the methodLogger for the given methodName.
|
||||
// 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 {
|
||||
func (l *logger) getMethodLogger(methodName string) *MethodLogger {
|
||||
s, m, err := parseMethodName(methodName)
|
||||
if err != nil {
|
||||
grpclog.Infof("binarylogging: failed to parse %q: %v", methodName, err)
|
||||
|
1044
vendor/google.golang.org/grpc/internal/binarylog/binarylog_end2end_test.go
generated
vendored
Normal file
1044
vendor/google.golang.org/grpc/internal/binarylog/binarylog_end2end_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
vendor/google.golang.org/grpc/internal/binarylog/binarylog_test.go
generated
vendored
8
vendor/google.golang.org/grpc/internal/binarylog/binarylog_test.go
generated
vendored
@ -78,12 +78,12 @@ func TestGetMethodLogger(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
l := newLoggerFromConfigString(tc.in)
|
||||
l := NewLoggerFromConfigString(tc.in)
|
||||
if l == nil {
|
||||
t.Errorf("in: %q, failed to create logger from config string", tc.in)
|
||||
continue
|
||||
}
|
||||
ml := l.GetMethodLogger(tc.method)
|
||||
ml := l.getMethodLogger(tc.method)
|
||||
if ml == nil {
|
||||
t.Errorf("in: %q, method logger is nil, want non-nil", tc.in)
|
||||
continue
|
||||
@ -134,12 +134,12 @@ func TestGetMethodLoggerOff(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
l := newLoggerFromConfigString(tc.in)
|
||||
l := NewLoggerFromConfigString(tc.in)
|
||||
if l == nil {
|
||||
t.Errorf("in: %q, failed to create logger from config string", tc.in)
|
||||
continue
|
||||
}
|
||||
ml := l.GetMethodLogger(tc.method)
|
||||
ml := l.getMethodLogger(tc.method)
|
||||
if ml != nil {
|
||||
t.Errorf("in: %q, method logger is non-nil, want nil", tc.in)
|
||||
}
|
||||
|
42
vendor/google.golang.org/grpc/internal/binarylog/binarylog_testutil.go
generated
vendored
Normal file
42
vendor/google.golang.org/grpc/internal/binarylog/binarylog_testutil.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
// This file contains exported variables/functions that are exported for testing
|
||||
// only.
|
||||
//
|
||||
// An ideal way for this would be to put those in a *_test.go but in binarylog
|
||||
// package. But this doesn't work with staticcheck with go module. Error was:
|
||||
// "MdToMetadataProto not declared by package binarylog". This could be caused
|
||||
// by the way staticcheck looks for files for a certain package, which doesn't
|
||||
// support *_test.go files.
|
||||
//
|
||||
// Move those to binary_test.go when staticcheck is fixed.
|
||||
|
||||
package binarylog
|
||||
|
||||
var (
|
||||
// AllLogger is a logger that logs all headers/messages for all RPCs. It's
|
||||
// for testing only.
|
||||
AllLogger = NewLoggerFromConfigString("*")
|
||||
// MdToMetadataProto converts metadata to a binary logging proto message.
|
||||
// It's for testing only.
|
||||
MdToMetadataProto = mdToMetadataProto
|
||||
// AddrToProto converts an address to a binary logging proto message. It's
|
||||
// for testing only.
|
||||
AddrToProto = addrToProto
|
||||
)
|
8
vendor/google.golang.org/grpc/internal/binarylog/env_config.go
generated
vendored
8
vendor/google.golang.org/grpc/internal/binarylog/env_config.go
generated
vendored
@ -28,7 +28,8 @@ import (
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
// newLoggerFromConfigString reads the string and build a logger.
|
||||
// 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
|
||||
@ -43,7 +44,10 @@ import (
|
||||
//
|
||||
// If two configs exist for one certain method or service, the one specified
|
||||
// later overrides the privous config.
|
||||
func newLoggerFromConfigString(s string) *logger {
|
||||
func NewLoggerFromConfigString(s string) Logger {
|
||||
if s == "" {
|
||||
return nil
|
||||
}
|
||||
l := newEmptyLogger()
|
||||
methods := strings.Split(s, ",")
|
||||
for _, method := range methods {
|
||||
|
4
vendor/google.golang.org/grpc/internal/binarylog/env_config_test.go
generated
vendored
4
vendor/google.golang.org/grpc/internal/binarylog/env_config_test.go
generated
vendored
@ -34,7 +34,7 @@ func TestNewLoggerFromConfigString(t *testing.T) {
|
||||
fullM2 = s1 + "/" + m2
|
||||
)
|
||||
c := fmt.Sprintf("*{h:1;m:2},%s{h},%s{m},%s{h;m}", s1+"/*", fullM1, fullM2)
|
||||
l := newLoggerFromConfigString(c)
|
||||
l := NewLoggerFromConfigString(c).(*logger)
|
||||
|
||||
if l.all.hdr != 1 || l.all.msg != 2 {
|
||||
t.Errorf("l.all = %#v, want headerLen: 1, messageLen: 2", l.all)
|
||||
@ -83,7 +83,7 @@ func TestNewLoggerFromConfigStringInvalid(t *testing.T) {
|
||||
"*,*{h:1;m:1}",
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
l := newLoggerFromConfigString(tc)
|
||||
l := NewLoggerFromConfigString(tc)
|
||||
if l != nil {
|
||||
t.Errorf("With config %q, want logger %v, got %v", tc, nil, l)
|
||||
}
|
||||
|
10
vendor/google.golang.org/grpc/internal/binarylog/method_logger.go
generated
vendored
10
vendor/google.golang.org/grpc/internal/binarylog/method_logger.go
generated
vendored
@ -206,8 +206,8 @@ func (c *ServerHeader) toProto() *pb.GrpcLogEntry {
|
||||
// ClientMessage configs the binary log entry to be a ClientMessage entry.
|
||||
type ClientMessage struct {
|
||||
OnClientSide bool
|
||||
// Message should only be a proto.Message. Could add support for other
|
||||
// message types in the future.
|
||||
// Message can be a proto.Message or []byte. Other messages formats are not
|
||||
// supported.
|
||||
Message interface{}
|
||||
}
|
||||
|
||||
@ -246,8 +246,8 @@ func (c *ClientMessage) toProto() *pb.GrpcLogEntry {
|
||||
// ServerMessage configs the binary log entry to be a ServerMessage entry.
|
||||
type ServerMessage struct {
|
||||
OnClientSide bool
|
||||
// Message should only be a proto.Message. Could add support for other
|
||||
// message types in the future.
|
||||
// Message can be a proto.Message or []byte. Other messages formats are not
|
||||
// supported.
|
||||
Message interface{}
|
||||
}
|
||||
|
||||
@ -372,7 +372,7 @@ func (c *Cancel) toProto() *pb.GrpcLogEntry {
|
||||
// omitted.
|
||||
func metadataKeyOmit(key string) bool {
|
||||
switch key {
|
||||
case "lb-token", ":path", ":authority", "content-encoding", "user-agent", "te":
|
||||
case "lb-token", ":path", ":authority", "content-encoding", "content-type", "user-agent", "te":
|
||||
return true
|
||||
case "grpc-trace-bin": // grpc-trace-bin is special because it's visiable to users.
|
||||
return false
|
||||
|
4
vendor/google.golang.org/grpc/internal/binarylog/method_logger_test.go
generated
vendored
4
vendor/google.golang.org/grpc/internal/binarylog/method_logger_test.go
generated
vendored
@ -37,7 +37,7 @@ func TestLog(t *testing.T) {
|
||||
ml := newMethodLogger(10, 10)
|
||||
// Set sink to testing buffer.
|
||||
buf := bytes.NewBuffer(nil)
|
||||
ml.sink = NewWriterSink(buf)
|
||||
ml.sink = newWriterSink(buf)
|
||||
|
||||
addr := "1.2.3.4"
|
||||
port := 790
|
||||
@ -337,7 +337,7 @@ func TestLog(t *testing.T) {
|
||||
tc.want.SequenceIdWithinCall = uint64(i + 1)
|
||||
ml.Log(tc.config)
|
||||
inSink := new(pb.GrpcLogEntry)
|
||||
if err := proto.Unmarshal(buf.Bytes(), inSink); err != nil {
|
||||
if err := proto.Unmarshal(buf.Bytes()[4:], inSink); err != nil {
|
||||
t.Errorf("failed to unmarshal bytes in sink to proto: %v", err)
|
||||
continue
|
||||
}
|
||||
|
110
vendor/google.golang.org/grpc/internal/binarylog/sink.go
generated
vendored
110
vendor/google.golang.org/grpc/internal/binarylog/sink.go
generated
vendored
@ -19,7 +19,13 @@
|
||||
package binarylog
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
pb "google.golang.org/grpc/binarylog/grpc_binarylog_v1"
|
||||
@ -34,20 +40,34 @@ var (
|
||||
//
|
||||
// Not thread safe. Only set during initialization.
|
||||
func SetDefaultSink(s Sink) {
|
||||
if defaultSink != nil {
|
||||
defaultSink.Close()
|
||||
}
|
||||
defaultSink = s
|
||||
}
|
||||
|
||||
// Sink writes log entry into the binary log sink.
|
||||
type Sink interface {
|
||||
Write(*pb.GrpcLogEntry)
|
||||
// Write will be called to write the log entry into the sink.
|
||||
//
|
||||
// It should be thread-safe so it can be called in parallel.
|
||||
Write(*pb.GrpcLogEntry) error
|
||||
// Close will be called when the Sink is replaced by a new Sink.
|
||||
Close() error
|
||||
}
|
||||
|
||||
type noopSink struct{}
|
||||
|
||||
func (ns *noopSink) Write(*pb.GrpcLogEntry) {}
|
||||
func (ns *noopSink) Write(*pb.GrpcLogEntry) error { return nil }
|
||||
func (ns *noopSink) Close() error { return nil }
|
||||
|
||||
// NewWriterSink creates a binary log sink with the given writer.
|
||||
func NewWriterSink(w io.Writer) Sink {
|
||||
// newWriterSink creates a binary log sink with the given writer.
|
||||
//
|
||||
// Write() marshalls the proto message and writes it to the given writer. Each
|
||||
// message is prefixed with a 4 byte big endian unsigned integer as the length.
|
||||
//
|
||||
// No buffer is done, Close() doesn't try to close the writer.
|
||||
func newWriterSink(w io.Writer) *writerSink {
|
||||
return &writerSink{out: w}
|
||||
}
|
||||
|
||||
@ -55,10 +75,88 @@ type writerSink struct {
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
func (fs *writerSink) Write(e *pb.GrpcLogEntry) {
|
||||
func (ws *writerSink) Write(e *pb.GrpcLogEntry) error {
|
||||
b, err := proto.Marshal(e)
|
||||
if err != nil {
|
||||
grpclog.Infof("binary logging: failed to marshal proto message: %v", err)
|
||||
}
|
||||
fs.out.Write(b)
|
||||
hdr := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(hdr, uint32(len(b)))
|
||||
if _, err := ws.out.Write(hdr); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := ws.out.Write(b); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ws *writerSink) Close() error { return nil }
|
||||
|
||||
type bufWriteCloserSink struct {
|
||||
mu sync.Mutex
|
||||
closer io.Closer
|
||||
out *writerSink // out is built on buf.
|
||||
buf *bufio.Writer // buf is kept for flush.
|
||||
|
||||
writeStartOnce sync.Once
|
||||
writeTicker *time.Ticker
|
||||
}
|
||||
|
||||
func (fs *bufWriteCloserSink) Write(e *pb.GrpcLogEntry) error {
|
||||
// Start the write loop when Write is called.
|
||||
fs.writeStartOnce.Do(fs.startFlushGoroutine)
|
||||
fs.mu.Lock()
|
||||
if err := fs.out.Write(e); err != nil {
|
||||
fs.mu.Unlock()
|
||||
return err
|
||||
}
|
||||
fs.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
bufFlushDuration = 60 * time.Second
|
||||
)
|
||||
|
||||
func (fs *bufWriteCloserSink) startFlushGoroutine() {
|
||||
fs.writeTicker = time.NewTicker(bufFlushDuration)
|
||||
go func() {
|
||||
for range fs.writeTicker.C {
|
||||
fs.mu.Lock()
|
||||
fs.buf.Flush()
|
||||
fs.mu.Unlock()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (fs *bufWriteCloserSink) Close() error {
|
||||
if fs.writeTicker != nil {
|
||||
fs.writeTicker.Stop()
|
||||
}
|
||||
fs.mu.Lock()
|
||||
fs.buf.Flush()
|
||||
fs.closer.Close()
|
||||
fs.out.Close()
|
||||
fs.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func newBufWriteCloserSink(o io.WriteCloser) Sink {
|
||||
bufW := bufio.NewWriter(o)
|
||||
return &bufWriteCloserSink{
|
||||
closer: o,
|
||||
out: newWriterSink(bufW),
|
||||
buf: bufW,
|
||||
}
|
||||
}
|
||||
|
||||
// NewTempFileSink creates a temp file and returns a Sink that writes to this
|
||||
// file.
|
||||
func NewTempFileSink() (Sink, error) {
|
||||
tempFile, err := ioutil.TempFile("/tmp", "grpcgo_binarylog_*.txt")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create temp file: %v", err)
|
||||
}
|
||||
return newBufWriteCloserSink(tempFile), nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user