Added ReadOptions; Changed proto; Reimplemented Log(er)
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user