Added ReadOptions; Changed proto; Reimplemented Log(er)

This commit is contained in:
Milos Gajdos
2019-11-27 17:31:35 +00:00
parent 9e177be560
commit 7deafbc5ce
8 changed files with 195 additions and 115 deletions

View File

@@ -12,13 +12,13 @@ var (
DefaultSize = 1000
)
// defaultLogger is default micro logger
type defaultLogger struct {
// defaultLog is default micro log
type defaultLog struct {
*buffer.Buffer
}
// NewLogger returns default Logger with
func NewLogger(opts ...Option) Logger {
// NewLog returns default Logger with
func NewLog(opts ...Option) Log {
// get default options
options := DefaultOptions()
@@ -27,27 +27,43 @@ func NewLogger(opts ...Option) Logger {
o(&options)
}
return &defaultLogger{
return &defaultLog{
Buffer: buffer.New(options.Size),
}
}
// Write writes log into logger
func (l *defaultLogger) Write(v ...interface{}) {
l.log(fmt.Sprint(v...))
func (l *defaultLog) Write(v ...interface{}) {
l.Buffer.Put(fmt.Sprint(v...))
golog.Print(v...)
}
// Read reads logs from the logger
func (l *defaultLogger) Read(n int) []interface{} {
entries := l.Get(n)
vals := make([]interface{}, 0, len(entries))
for _, val := range entries {
vals = append(vals, val)
func (l *defaultLog) Read(opts ...ReadOption) []Record {
options := ReadOptions{}
// initialize the read options
for _, o := range opts {
o(&options)
}
return vals
}
func (l *defaultLogger) log(entry string) {
l.Buffer.Put(entry)
var entries []*buffer.Entry
// if Since options ha sbeen specified we honor it
if !options.Since.IsZero() {
entries = l.Buffer.Since(options.Since)
} else {
// otherwie return last count entries
entries = l.Buffer.Get(options.Count)
}
// TODO: if both Since and Count are set should we return
// last Count from the returned time scoped entries?
records := make([]Record, 0, len(entries))
for _, entry := range entries {
record := Record{
Timestamp: entry.Timestamp,
Value: entry.Value,
}
records = append(records, record)
}
return records
}

View File

@@ -6,21 +6,27 @@ import (
)
func TestLogger(t *testing.T) {
// set size to some value
size := 100
// override the global logger
logger = NewLog(Size(size))
// make sure we have the right size of the logger ring buffer
if logger.(*defaultLogger).Size() != DefaultSize {
t.Errorf("expected buffer size: %d, got: %d", DefaultSize, logger.(*defaultLogger).Size())
if logger.(*defaultLog).Size() != size {
t.Errorf("expected buffer size: %d, got: %d", size, logger.(*defaultLog).Size())
}
// Log some cruft
Log("foobar")
Logf("foo %s", "bar")
Info("foobar")
// increase the log level
level = LevelDebug
Debugf("foo %s", "bar")
// Check if the logs are stored in the logger ring buffer
expectedEntries := []string{"foobar", "foo bar"}
entries := logger.Read(len(expectedEntries))
expected := []string{"foobar", "foo bar"}
entries := logger.Read(Count(len(expected)))
for i, entry := range entries {
if !reflect.DeepEqual(entry, expectedEntries[i]) {
t.Errorf("expected %s, got %s", expectedEntries[i], entry)
if !reflect.DeepEqual(entry.Value, expected[i]) {
t.Errorf("expected %s, got %s", expected[i], entry.Value)
}
}
}

View File

@@ -4,25 +4,36 @@ package log
import (
"fmt"
"os"
"time"
)
var (
// logger is default Logger
logger Logger = NewLogger()
logger Log = NewLog()
// default log level is info
level = LevelInfo
// prefix for all messages
prefix string
)
// Logger is event logger
type Logger interface {
// Read reads specified number of log entries
Read(int) []interface{}
// Log is event log
type Log interface {
// Read reads log entries from the logger
Read(...ReadOption) []Record
// Write writes logs to logger
Write(...interface{})
}
// Record is log record entry
type Record struct {
// Timestamp of logged event
Timestamp time.Time
// Value contains log entry
Value interface{}
// Metadata to enrich log record
Metadata map[string]string
}
// level is a log level
type Level int
@@ -52,7 +63,7 @@ func init() {
}
}
func Log(v ...interface{}) {
func log(v ...interface{}) {
if len(prefix) > 0 {
logger.Write(fmt.Sprint(append([]interface{}{prefix, " "}, v...)...))
return
@@ -60,7 +71,7 @@ func Log(v ...interface{}) {
logger.Write(fmt.Sprint(v...))
}
func Logf(format string, v ...interface{}) {
func logf(format string, v ...interface{}) {
if len(prefix) > 0 {
format = prefix + " " + format
}
@@ -72,7 +83,7 @@ func WithLevel(l Level, v ...interface{}) {
if l > level {
return
}
Log(v...)
log(v...)
}
// WithLevel logs with the level specified
@@ -80,7 +91,7 @@ func WithLevelf(l Level, format string, v ...interface{}) {
if l > level {
return
}
Logf(format, v...)
logf(format, v...)
}
// Trace provides trace level logging
@@ -145,11 +156,6 @@ func Fatalf(format string, v ...interface{}) {
os.Exit(1)
}
// GetLogger returns the local logger
func GetLogger() Logger {
return logger
}
// SetLevel sets the log level
func SetLevel(l Level) {
level = l

View File

@@ -1,5 +1,7 @@
package log
import "time"
// Option used by the logger
type Option func(*Options)
@@ -22,3 +24,28 @@ func DefaultOptions() Options {
Size: DefaultSize,
}
}
// ReadOptions for querying the logs
type ReadOptions struct {
// Since what time in past to return the logs
Since time.Time
// Count specifies number of logs to return
Count int
}
// ReadOption used for reading the logs
type ReadOption func(*ReadOptions)
// Since sets the time since which to return the log records
func Since(s time.Time) ReadOption {
return func(o *ReadOptions) {
o.Since = s
}
}
// Count sets the number of log records to return
func Count(c int) ReadOption {
return func(o *ReadOptions) {
o.Count = c
}
}