mirror of https://github.com/grpc/grpc-go.git
binarylog: generalize binarylog's MethodLogger preparing for new observability features (#5244)
This commit is contained in:
parent
63bdcbcce5
commit
1ffd63de37
|
@ -31,7 +31,7 @@ import (
|
||||||
// Logger is the global binary logger. It can be used to get binary logger for
|
// Logger is the global binary logger. It can be used to get binary logger for
|
||||||
// each method.
|
// each method.
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
getMethodLogger(methodName string) *MethodLogger
|
GetMethodLogger(methodName string) MethodLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
// binLogger is the global binary logger for the binary. One of this should be
|
// binLogger is the global binary logger for the binary. One of this should be
|
||||||
|
@ -49,17 +49,24 @@ func SetLogger(l Logger) {
|
||||||
binLogger = l
|
binLogger = l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetLogger gets the binarg logger.
|
||||||
|
//
|
||||||
|
// Only call this at init time.
|
||||||
|
func GetLogger() Logger {
|
||||||
|
return binLogger
|
||||||
|
}
|
||||||
|
|
||||||
// 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".
|
// methodName should be in the format of "/service/method".
|
||||||
//
|
//
|
||||||
// Each methodLogger returned by this method is a new instance. This is to
|
// Each methodLogger returned by this method is a new instance. This is to
|
||||||
// generate sequence id within the call.
|
// generate sequence id within the call.
|
||||||
func GetMethodLogger(methodName string) *MethodLogger {
|
func GetMethodLogger(methodName string) MethodLogger {
|
||||||
if binLogger == nil {
|
if binLogger == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return binLogger.getMethodLogger(methodName)
|
return binLogger.GetMethodLogger(methodName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -148,7 +155,7 @@ func (l *logger) setBlacklist(method string) error {
|
||||||
//
|
//
|
||||||
// Each methodLogger returned by this method is a new instance. This is to
|
// Each methodLogger returned by this method is a new instance. This is to
|
||||||
// generate sequence id within the call.
|
// generate sequence id within the call.
|
||||||
func (l *logger) getMethodLogger(methodName string) *MethodLogger {
|
func (l *logger) GetMethodLogger(methodName string) MethodLogger {
|
||||||
s, m, err := grpcutil.ParseMethod(methodName)
|
s, m, err := grpcutil.ParseMethod(methodName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
grpclogLogger.Infof("binarylogging: failed to parse %q: %v", methodName, err)
|
grpclogLogger.Infof("binarylogging: failed to parse %q: %v", methodName, err)
|
||||||
|
|
|
@ -93,7 +93,7 @@ func (s) TestGetMethodLogger(t *testing.T) {
|
||||||
t.Errorf("in: %q, failed to create logger from config string", tc.in)
|
t.Errorf("in: %q, failed to create logger from config string", tc.in)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ml := l.getMethodLogger(tc.method)
|
ml := l.GetMethodLogger(tc.method).(*methodLogger)
|
||||||
if ml == nil {
|
if ml == nil {
|
||||||
t.Errorf("in: %q, method logger is nil, want non-nil", tc.in)
|
t.Errorf("in: %q, method logger is nil, want non-nil", tc.in)
|
||||||
continue
|
continue
|
||||||
|
@ -149,7 +149,7 @@ func (s) TestGetMethodLoggerOff(t *testing.T) {
|
||||||
t.Errorf("in: %q, failed to create logger from config string", tc.in)
|
t.Errorf("in: %q, failed to create logger from config string", tc.in)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ml := l.getMethodLogger(tc.method)
|
ml := l.GetMethodLogger(tc.method)
|
||||||
if ml != nil {
|
if ml != nil {
|
||||||
t.Errorf("in: %q, method logger is non-nil, want nil", tc.in)
|
t.Errorf("in: %q, method logger is non-nil, want nil", tc.in)
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,11 @@ func (g *callIDGenerator) reset() {
|
||||||
var idGen callIDGenerator
|
var idGen callIDGenerator
|
||||||
|
|
||||||
// MethodLogger is the sub-logger for each method.
|
// MethodLogger is the sub-logger for each method.
|
||||||
type MethodLogger struct {
|
type MethodLogger interface {
|
||||||
|
Log(LogEntryConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
type methodLogger struct {
|
||||||
headerMaxLen, messageMaxLen uint64
|
headerMaxLen, messageMaxLen uint64
|
||||||
|
|
||||||
callID uint64
|
callID uint64
|
||||||
|
@ -57,8 +61,8 @@ type MethodLogger struct {
|
||||||
sink Sink // TODO(blog): make this plugable.
|
sink Sink // TODO(blog): make this plugable.
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMethodLogger(h, m uint64) *MethodLogger {
|
func newMethodLogger(h, m uint64) *methodLogger {
|
||||||
return &MethodLogger{
|
return &methodLogger{
|
||||||
headerMaxLen: h,
|
headerMaxLen: h,
|
||||||
messageMaxLen: m,
|
messageMaxLen: m,
|
||||||
|
|
||||||
|
@ -69,8 +73,10 @@ func newMethodLogger(h, m uint64) *MethodLogger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log creates a proto binary log entry, and logs it to the sink.
|
// Build is an internal only method for building the proto message out of the
|
||||||
func (ml *MethodLogger) Log(c LogEntryConfig) {
|
// input event. It's made public to enable other library to reuse as much logic
|
||||||
|
// in methodLogger as possible.
|
||||||
|
func (ml *methodLogger) Build(c LogEntryConfig) *pb.GrpcLogEntry {
|
||||||
m := c.toProto()
|
m := c.toProto()
|
||||||
timestamp, _ := ptypes.TimestampProto(time.Now())
|
timestamp, _ := ptypes.TimestampProto(time.Now())
|
||||||
m.Timestamp = timestamp
|
m.Timestamp = timestamp
|
||||||
|
@ -85,11 +91,15 @@ func (ml *MethodLogger) Log(c LogEntryConfig) {
|
||||||
case *pb.GrpcLogEntry_Message:
|
case *pb.GrpcLogEntry_Message:
|
||||||
m.PayloadTruncated = ml.truncateMessage(pay.Message)
|
m.PayloadTruncated = ml.truncateMessage(pay.Message)
|
||||||
}
|
}
|
||||||
|
return m
|
||||||
ml.sink.Write(m)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ml *MethodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated bool) {
|
// Log creates a proto binary log entry, and logs it to the sink.
|
||||||
|
func (ml *methodLogger) Log(c LogEntryConfig) {
|
||||||
|
ml.sink.Write(ml.Build(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ml *methodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated bool) {
|
||||||
if ml.headerMaxLen == maxUInt {
|
if ml.headerMaxLen == maxUInt {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -119,7 +129,7 @@ func (ml *MethodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated bool) {
|
||||||
return truncated
|
return truncated
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ml *MethodLogger) truncateMessage(msgPb *pb.Message) (truncated bool) {
|
func (ml *methodLogger) truncateMessage(msgPb *pb.Message) (truncated bool) {
|
||||||
if ml.messageMaxLen == maxUInt {
|
if ml.messageMaxLen == maxUInt {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -350,7 +350,7 @@ func (s) TestLog(t *testing.T) {
|
||||||
|
|
||||||
func (s) TestTruncateMetadataNotTruncated(t *testing.T) {
|
func (s) TestTruncateMetadataNotTruncated(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
ml *MethodLogger
|
ml *methodLogger
|
||||||
mpPb *pb.Metadata
|
mpPb *pb.Metadata
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
|
@ -417,7 +417,7 @@ func (s) TestTruncateMetadataNotTruncated(t *testing.T) {
|
||||||
|
|
||||||
func (s) TestTruncateMetadataTruncated(t *testing.T) {
|
func (s) TestTruncateMetadataTruncated(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
ml *MethodLogger
|
ml *methodLogger
|
||||||
mpPb *pb.Metadata
|
mpPb *pb.Metadata
|
||||||
|
|
||||||
entryLen int
|
entryLen int
|
||||||
|
@ -478,7 +478,7 @@ func (s) TestTruncateMetadataTruncated(t *testing.T) {
|
||||||
|
|
||||||
func (s) TestTruncateMessageNotTruncated(t *testing.T) {
|
func (s) TestTruncateMessageNotTruncated(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
ml *MethodLogger
|
ml *methodLogger
|
||||||
msgPb *pb.Message
|
msgPb *pb.Message
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
|
@ -511,7 +511,7 @@ func (s) TestTruncateMessageNotTruncated(t *testing.T) {
|
||||||
|
|
||||||
func (s) TestTruncateMessageTruncated(t *testing.T) {
|
func (s) TestTruncateMessageTruncated(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
ml *MethodLogger
|
ml *methodLogger
|
||||||
msgPb *pb.Message
|
msgPb *pb.Message
|
||||||
|
|
||||||
oldLength uint32
|
oldLength uint32
|
||||||
|
|
|
@ -462,7 +462,7 @@ type clientStream struct {
|
||||||
|
|
||||||
retryThrottler *retryThrottler // The throttler active when the RPC began.
|
retryThrottler *retryThrottler // The throttler active when the RPC began.
|
||||||
|
|
||||||
binlog *binarylog.MethodLogger // Binary logger, can be nil.
|
binlog binarylog.MethodLogger // Binary logger, can be nil.
|
||||||
// serverHeaderBinlogged is a boolean for whether server header has been
|
// serverHeaderBinlogged is a boolean for whether server header has been
|
||||||
// logged. Server header will be logged when the first time one of those
|
// logged. Server header will be logged when the first time one of those
|
||||||
// happens: stream.Header(), stream.Recv().
|
// happens: stream.Header(), stream.Recv().
|
||||||
|
@ -1434,7 +1434,7 @@ type serverStream struct {
|
||||||
|
|
||||||
statsHandler stats.Handler
|
statsHandler stats.Handler
|
||||||
|
|
||||||
binlog *binarylog.MethodLogger
|
binlog binarylog.MethodLogger
|
||||||
// serverHeaderBinlogged indicates whether server header has been logged. It
|
// serverHeaderBinlogged indicates whether server header has been logged. It
|
||||||
// will happen when one of the following two happens: stream.SendHeader(),
|
// will happen when one of the following two happens: stream.SendHeader(),
|
||||||
// stream.Send().
|
// stream.Send().
|
||||||
|
|
Loading…
Reference in New Issue