move to structured logging

This commit is contained in:
Asim Aslam 2019-12-18 16:02:11 +00:00
parent a82af19d43
commit f0e841595c
10 changed files with 102 additions and 71 deletions

@ -24,7 +24,7 @@ func TestKubernetes(t *testing.T) {
meta := make(map[string]string)
write := log.Record{
Timestamp: time.Unix(0, 0).UTC(),
Value: "Test log entry",
Message: "Test log entry",
Metadata: meta,
}
meta["foo"] = "bar"

@ -25,11 +25,11 @@ type Log interface {
// Record is log record entry
type Record struct {
// Timestamp of logged event
Timestamp time.Time `json:"time"`
// Value contains log entry
Value interface{} `json:"value"`
Timestamp time.Time `json:"timestamp"`
// Metadata to enrich log record
Metadata map[string]string `json:"metadata"`
// Value contains log entry
Message interface{} `json:"message"`
}
// Stream returns a log stream

@ -35,7 +35,7 @@ func NewLog(opts ...log.Option) log.Log {
// Write writes logs into logger
func (l *memoryLog) Write(r log.Record) error {
l.Buffer.Put(fmt.Sprint(r.Value))
l.Buffer.Put(fmt.Sprint(r.Message))
return nil
}
@ -74,7 +74,7 @@ func (l *memoryLog) Read(opts ...log.ReadOption) ([]log.Record, error) {
for _, entry := range entries {
record := log.Record{
Timestamp: entry.Timestamp,
Value: entry.Value,
Message: entry.Value,
}
records = append(records, record)
}
@ -98,7 +98,7 @@ func (l *memoryLog) Stream() (log.Stream, error) {
for _, entry := range last10 {
records <- log.Record{
Timestamp: entry.Timestamp,
Value: entry.Value,
Message: entry.Value,
Metadata: make(map[string]string),
}
}
@ -106,7 +106,7 @@ func (l *memoryLog) Stream() (log.Stream, error) {
for entry := range stream {
records <- log.Record{
Timestamp: entry.Timestamp,
Value: entry.Value,
Message: entry.Value,
Metadata: make(map[string]string),
}
}

@ -18,15 +18,15 @@ func TestLogger(t *testing.T) {
}
// Log some cruft
lg.Write(log.Record{Value: "foobar"})
lg.Write(log.Record{Value: "foo bar"})
lg.Write(log.Record{Message: "foobar"})
lg.Write(log.Record{Message: "foo bar"})
// Check if the logs are stored in the logger ring buffer
expected := []string{"foobar", "foo bar"}
entries, _ := lg.Read(log.Count(len(expected)))
for i, entry := range entries {
if !reflect.DeepEqual(entry.Value, expected[i]) {
t.Errorf("expected %s, got %s", expected[i], entry.Value)
if !reflect.DeepEqual(entry.Message, expected[i]) {
t.Errorf("expected %s, got %s", expected[i], entry.Message)
}
}
}

@ -87,7 +87,7 @@ func (o *osLog) run() {
} else {
r = Record{
Timestamp: time.Now(),
Value: strings.TrimSuffix(line, "\n"),
Message: strings.TrimSuffix(line, "\n"),
Metadata: make(map[string]string),
}
}
@ -125,7 +125,7 @@ func (o *osLog) Read(...ReadOption) ([]Record, error) {
// Write writes records to log
func (o *osLog) Write(r Record) error {
b, _ := json.Marshal(r)
_, err := os.Stderr.Write(b)
_, err := os.Stderr.Write(append(b, byte('\n')))
return err
}

@ -65,7 +65,7 @@ func (d *debugClient) streamLogs(lg *logStream, stream pb.Debug_LogService) {
record := log.Record{
Timestamp: time.Unix(resp.Timestamp, 0),
Value: resp.Value,
Message: resp.Message,
Metadata: metadata,
}

@ -111,7 +111,7 @@ func (d *Debug) sendRecord(record log.Record, stream server.Stream) error {
return stream.Send(&proto.Record{
Timestamp: record.Timestamp.Unix(),
Value: record.Value.(string),
Message: record.Message.(string),
Metadata: metadata,
})
}

@ -299,13 +299,13 @@ func (m *LogRequest) GetSince() int64 {
type Record struct {
// timestamp of log record
Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
// record value
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
// record metadata
Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
Metadata map[string]string `protobuf:"bytes,2,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
// message
Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Record) Reset() { *m = Record{} }
@ -340,13 +340,6 @@ func (m *Record) GetTimestamp() int64 {
return 0
}
func (m *Record) GetValue() string {
if m != nil {
return m.Value
}
return ""
}
func (m *Record) GetMetadata() map[string]string {
if m != nil {
return m.Metadata
@ -354,6 +347,13 @@ func (m *Record) GetMetadata() map[string]string {
return nil
}
func (m *Record) GetMessage() string {
if m != nil {
return m.Message
}
return ""
}
func init() {
proto.RegisterType((*HealthRequest)(nil), "HealthRequest")
proto.RegisterType((*HealthResponse)(nil), "HealthResponse")
@ -369,30 +369,31 @@ func init() {
}
var fileDescriptor_dea322649cde1ef2 = []byte{
// 399 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x52, 0xc1, 0x6e, 0xd4, 0x30,
0x10, 0xdd, 0xac, 0x9b, 0xb4, 0x3b, 0x65, 0x17, 0x64, 0x15, 0x64, 0xad, 0x90, 0xa8, 0x7c, 0x0a,
0x42, 0x78, 0xa1, 0x5c, 0x10, 0x5c, 0x41, 0xe2, 0x50, 0x2e, 0xe6, 0x0b, 0xdc, 0x64, 0x94, 0x2e,
0x34, 0x71, 0xb0, 0x27, 0x95, 0xf6, 0xc4, 0xb7, 0x70, 0xe7, 0x23, 0x51, 0x6c, 0x2f, 0x6d, 0x44,
0xa5, 0xbd, 0xcd, 0x7b, 0xf3, 0xf4, 0x3c, 0x33, 0x7e, 0xa0, 0xda, 0x6d, 0xe5, 0xec, 0xa6, 0xb1,
0xaf, 0x63, 0x51, 0xe3, 0xd5, 0xd0, 0x6c, 0x3c, 0xba, 0xdb, 0x6d, 0x85, 0x9b, 0xde, 0x59, 0x4a,
0x9c, 0x0a, 0xb5, 0x7c, 0x09, 0xcb, 0x2f, 0x68, 0x6e, 0xe8, 0x5a, 0xe3, 0xcf, 0x01, 0x3d, 0x71,
0x01, 0xc7, 0x49, 0x2d, 0xb2, 0xf3, 0xac, 0x5c, 0xe8, 0x3d, 0x94, 0x25, 0xac, 0xf6, 0x52, 0xdf,
0xdb, 0xce, 0x23, 0x7f, 0x06, 0x85, 0x27, 0x43, 0x83, 0x4f, 0xd2, 0x84, 0x64, 0x09, 0x8f, 0xbe,
0x91, 0x21, 0x7f, 0xd8, 0xf3, 0x77, 0x06, 0xcb, 0x24, 0x4d, 0x9e, 0xcf, 0x61, 0x41, 0xdb, 0x16,
0x3d, 0x99, 0xb6, 0x0f, 0xea, 0x23, 0x7d, 0x47, 0x04, 0x27, 0x32, 0x8e, 0xb0, 0x16, 0xf3, 0xd0,
0xdb, 0xc3, 0x71, 0x96, 0xa1, 0x1f, 0x85, 0x82, 0x85, 0x46, 0x42, 0x23, 0xdf, 0x62, 0x6b, 0xdd,
0x4e, 0x1c, 0x45, 0x3e, 0xa2, 0xd1, 0x89, 0xae, 0x1d, 0x9a, 0xda, 0x8b, 0x3c, 0x3a, 0x25, 0xc8,
0x57, 0x30, 0x6f, 0x2a, 0x51, 0x04, 0x72, 0xde, 0x54, 0xf2, 0x3b, 0xc0, 0xa5, 0x6d, 0x0e, 0xee,
0x12, 0xaf, 0xe1, 0xd0, 0xb4, 0x61, 0xb4, 0x13, 0x9d, 0x10, 0x3f, 0x83, 0xbc, 0xb2, 0x43, 0x47,
0x61, 0x30, 0xa6, 0x23, 0x18, 0x59, 0xbf, 0xed, 0x2a, 0x0c, 0x63, 0x31, 0x1d, 0x81, 0xfc, 0x93,
0x41, 0xa1, 0xb1, 0xb2, 0xae, 0xfe, 0xff, 0x10, 0xec, 0xfe, 0x21, 0xce, 0x20, 0xbf, 0x35, 0x37,
0x03, 0x86, 0xb7, 0x16, 0x3a, 0x02, 0xfe, 0x16, 0x4e, 0x5a, 0x24, 0x53, 0x1b, 0x32, 0x82, 0x9d,
0xb3, 0xf2, 0xf4, 0xe2, 0xa9, 0x8a, 0x76, 0xea, 0x6b, 0xe2, 0x3f, 0x77, 0xe4, 0x76, 0xfa, 0x9f,
0x6c, 0xfd, 0x11, 0x96, 0x93, 0x16, 0x7f, 0x02, 0xec, 0x07, 0xee, 0xd2, 0x72, 0x63, 0xf9, 0xf0,
0x5b, 0x1f, 0xe6, 0xef, 0xb3, 0x8b, 0x5f, 0x90, 0x7f, 0x1a, 0xc3, 0xc4, 0x5f, 0x41, 0x11, 0xb3,
0xc1, 0x57, 0x6a, 0x92, 0xa7, 0xf5, 0x63, 0x35, 0x0d, 0x8d, 0x9c, 0xf1, 0x12, 0xf2, 0xf0, 0xe7,
0x7c, 0xa9, 0xee, 0xc7, 0x64, 0xbd, 0x52, 0x93, 0x28, 0xc8, 0x19, 0x7f, 0x01, 0xec, 0xd2, 0x36,
0xfc, 0x54, 0xdd, 0x7d, 0xc0, 0xfa, 0x38, 0x6d, 0x24, 0x67, 0x6f, 0xb2, 0xab, 0x22, 0xa4, 0xf8,
0xdd, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xea, 0xdf, 0xa5, 0x1d, 0xf7, 0x02, 0x00, 0x00,
// 407 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xcf, 0x6e, 0x13, 0x31,
0x10, 0xc6, 0xb3, 0xbb, 0xcd, 0xb6, 0x99, 0x92, 0x80, 0x2c, 0x40, 0x56, 0x84, 0x44, 0xe5, 0xd3,
0x22, 0x84, 0x03, 0xe5, 0x82, 0xe0, 0x0a, 0x12, 0x87, 0x72, 0x31, 0x4f, 0xe0, 0xee, 0x8e, 0xb6,
0x81, 0x3a, 0x0e, 0xf6, 0x6c, 0xa5, 0x9c, 0x78, 0x16, 0xde, 0x80, 0x47, 0x44, 0xfe, 0xb3, 0xb4,
0xab, 0x1e, 0x7a, 0xf3, 0xef, 0xf3, 0xe7, 0xd1, 0xcc, 0xf8, 0x03, 0x69, 0xb6, 0xad, 0xb3, 0x9b,
0xde, 0xbe, 0x49, 0x87, 0x0e, 0x2f, 0x87, 0x7e, 0xe3, 0xd1, 0xdd, 0x6c, 0x5b, 0xdc, 0xec, 0x9d,
0xa5, 0xac, 0xc9, 0x78, 0x16, 0xaf, 0x60, 0xf9, 0x15, 0xf5, 0x35, 0x5d, 0x29, 0xfc, 0x35, 0xa0,
0x27, 0xc6, 0xe1, 0x38, 0xbb, 0x79, 0x71, 0x56, 0x34, 0x0b, 0x35, 0xa2, 0x68, 0x60, 0x35, 0x5a,
0xfd, 0xde, 0xee, 0x3c, 0xb2, 0xe7, 0x50, 0x7b, 0xd2, 0x34, 0xf8, 0x6c, 0xcd, 0x24, 0x1a, 0x78,
0xf4, 0x9d, 0x34, 0xf9, 0x87, 0x6b, 0xfe, 0x29, 0x60, 0x99, 0xad, 0xb9, 0xe6, 0x0b, 0x58, 0xd0,
0xd6, 0xa0, 0x27, 0x6d, 0xf6, 0xd1, 0x7d, 0xa4, 0x6e, 0x85, 0x58, 0x89, 0xb4, 0x23, 0xec, 0x78,
0x19, 0xef, 0x46, 0x0c, 0xbd, 0x0c, 0xfb, 0x60, 0xe4, 0x55, 0xbc, 0xc8, 0x14, 0x74, 0x83, 0xc6,
0xba, 0x03, 0x3f, 0x4a, 0x7a, 0xa2, 0x50, 0x89, 0xae, 0x1c, 0xea, 0xce, 0xf3, 0x79, 0xaa, 0x94,
0x91, 0xad, 0xa0, 0xec, 0x5b, 0x5e, 0x47, 0xb1, 0xec, 0x5b, 0xf1, 0x03, 0xe0, 0xc2, 0xf6, 0x0f,
0xce, 0x92, 0xb6, 0xe1, 0x50, 0x9b, 0xd8, 0xda, 0x89, 0xca, 0xc4, 0x9e, 0xc2, 0xbc, 0xb5, 0xc3,
0x8e, 0x62, 0x63, 0x95, 0x4a, 0x10, 0x54, 0xbf, 0xdd, 0xb5, 0x18, 0xdb, 0xaa, 0x54, 0x02, 0xf1,
0xb7, 0x80, 0x5a, 0x61, 0x6b, 0x5d, 0x77, 0x7f, 0x11, 0xd5, 0xdd, 0x45, 0xbc, 0x83, 0x13, 0x83,
0xa4, 0x3b, 0x4d, 0x9a, 0x97, 0x67, 0x55, 0x73, 0x7a, 0xfe, 0x4c, 0xa6, 0x87, 0xf2, 0x5b, 0xd6,
0xbf, 0xec, 0xc8, 0x1d, 0xd4, 0x7f, 0x5b, 0xe8, 0xdc, 0xa0, 0xf7, 0xba, 0x4f, 0x2b, 0x5a, 0xa8,
0x11, 0xd7, 0x9f, 0x60, 0x39, 0x79, 0xc4, 0x9e, 0x40, 0xf5, 0x13, 0x0f, 0x79, 0xc0, 0x70, 0x0c,
0xed, 0xde, 0xe8, 0xeb, 0x01, 0xe3, 0x6c, 0x0b, 0x95, 0xe0, 0x63, 0xf9, 0xa1, 0x38, 0xff, 0x0d,
0xf3, 0xcf, 0x21, 0x50, 0xec, 0x35, 0xd4, 0x29, 0x1f, 0x6c, 0x25, 0x27, 0x99, 0x5a, 0x3f, 0x96,
0xd3, 0xe0, 0x88, 0x19, 0x6b, 0x60, 0x1e, 0xff, 0x9d, 0x2d, 0xe5, 0xdd, 0xa8, 0xac, 0x57, 0x72,
0x12, 0x07, 0x31, 0x63, 0x2f, 0xa1, 0xba, 0xb0, 0x3d, 0x3b, 0x95, 0xb7, 0x9f, 0xb0, 0x3e, 0xce,
0xb3, 0x8a, 0xd9, 0xdb, 0xe2, 0xb2, 0x8e, 0x49, 0x7e, 0xff, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x4e,
0xd3, 0x4c, 0xce, 0xfb, 0x02, 0x00, 0x00,
}

@ -54,8 +54,8 @@ message LogRequest {
message Record {
// timestamp of log record
int64 timestamp = 1;
// record value
string value = 2;
// record metadata
map<string,string> metadata = 3;
map<string,string> metadata = 2;
// message
string message = 3;
}

@ -4,9 +4,9 @@ package log
import (
"fmt"
"os"
"time"
"github.com/go-log/log"
golog "github.com/go-log/log/log"
"github.com/micro/go-micro/debug/log"
)
// level is a log level
@ -23,7 +23,7 @@ const (
var (
// the local logger
logger log.Logger = golog.New()
logger log.Log = log.DefaultLog
// default log level is info
level = LevelInfo
@ -49,21 +49,51 @@ func init() {
}
}
// Log makes use of github.com/go-log/log.Log
func Log(v ...interface{}) {
if len(prefix) > 0 {
logger.Log(append([]interface{}{prefix, " "}, v...)...)
return
func (l Level) String() string {
switch l {
case LevelTrace:
return "trace"
case LevelDebug:
return "debug"
case LevelWarn:
return "warn"
case LevelInfo:
return "info"
case LevelError:
return "error"
case LevelFatal:
return "fatal"
default:
return "unknown"
}
logger.Log(v...)
}
// Logf makes use of github.com/go-log/log.Logf
// Log makes use of github.com/micro/debug/log
func Log(v ...interface{}) {
if len(prefix) > 0 {
v = append([]interface{}{prefix, " "}, v...)
}
logger.Write(log.Record{
Timestamp: time.Now(),
Message: fmt.Sprint(v...),
Metadata: map[string]string{
"level": level.String(),
},
})
}
// Logf makes use of github.com/micro/debug/log
func Logf(format string, v ...interface{}) {
if len(prefix) > 0 {
format = prefix + " " + format
}
logger.Logf(format, v...)
logger.Write(log.Record{
Timestamp: time.Now(),
Message: fmt.Sprintf(format, v...),
Metadata: map[string]string{
"level": level.String(),
},
})
}
// WithLevel logs with the level specified
@ -145,12 +175,12 @@ func Fatalf(format string, v ...interface{}) {
}
// SetLogger sets the local logger
func SetLogger(l log.Logger) {
func SetLogger(l log.Log) {
logger = l
}
// GetLogger returns the local logger
func GetLogger() log.Logger {
func GetLogger() log.Log {
return logger
}