From: mishaz Date: Thu, 8 Jan 2015 01:47:51 +0000 (+0000) Subject: Added logger to write log messages that grow over time. Not working yet. X-Git-Tag: 1.1.0~1505^2~65 X-Git-Url: https://git.arvados.org/arvados.git/commitdiff_plain/3594ad790c998c1b1711ea65057fcae9477986d4 Added logger to write log messages that grow over time. Not working yet. --- diff --git a/sdk/go/logger/logger.go b/sdk/go/logger/logger.go new file mode 100644 index 0000000000..6835750812 --- /dev/null +++ b/sdk/go/logger/logger.go @@ -0,0 +1,79 @@ +// Periodically writes a log to the Arvados SDK. +// +// This package is useful for maintaining a log object that is built +// up over time. Every time the object is modified, it will be written +// to the log. Writes will be throttled to no more than one every +// WriteFrequencySeconds +// +// This package is safe for concurrent use. +// +// Usage: +// arvLogger := logger.NewLogger(params) +// logData := arvLogger.Acquire() // This will block if others are using the logger +// // Modify the logObject however you want here .. +// logData = arvLogger.Release() // This triggers the actual write, and replaces logObject with a nil pointer so you don't try to modify it when you're no longer holding the lock + +package logger + +import ( + "git.curoverse.com/arvados.git/sdk/go/arvadosclient" + "log" + "sync" + "time" +) + +const ( + eventTypeLabel string = "event-type" + propertiesLabel string = "properties" +) + +type LoggerParams struct { + Client arvadosclient.ArvadosClient // The client we use to write log entries + EventType string // The event type to assign to the log entry. + MinimumWriteInterval time.Duration // Wait at least this long between log writes +} + +type Logger struct { + data map[string]interface{} + lock sync.Locker + params LoggerParams +} + +func NewLogger(params LoggerParams) *Logger { + l := &Logger{data: make(map[string]interface{}), + lock: &sync.Mutex{}, + // TODO(misha): Consider copying the params so they're not + // modified after creation. + params: params} + l.data[propertiesLabel] = make(map[string]interface{}) + return l +} + +func (l *Logger) Acquire() map[string]interface{} { + l.lock.Lock() + return l.data[propertiesLabel].(map[string]interface{}) +} + +func (l *Logger) Release() map[string]interface{} { + // TODO(misha): Add a check (and storage) to make sure we respect MinimumWriteInterval + l.write() + l.lock.Unlock() + return nil +} + +func (l *Logger) write() { + // Update the event type in case it was modified or is missing. + // l.data[eventTypeLabel] = l.params.EventType + // m := make(map[string]interface{}) + // m["body"] = l.data + // //err := l.params.Client.Create("logs", l.data, nil) + // //err := l.params.Client.Create("logs", m, nil) + // var results map[string]interface{} + err := l.params.Client.Create("logs", + arvadosclient.Dict{"log": arvadosclient.Dict{ + eventTypeLabel: l.params.EventType, + propertiesLabel: l.data}}, nil) + if err != nil { + log.Fatalf("Received error writing log: %v", err) + } +} diff --git a/sdk/go/logger/main/testlogger.go b/sdk/go/logger/main/testlogger.go new file mode 100644 index 0000000000..5a12352043 --- /dev/null +++ b/sdk/go/logger/main/testlogger.go @@ -0,0 +1,32 @@ +// This binary tests the logger package. +// It's not a standard unit test. Instead it writes to the actual log +// and you have to clean up after it. + +package main + +import ( + "git.curoverse.com/arvados.git/sdk/go/arvadosclient" + "git.curoverse.com/arvados.git/sdk/go/logger" + "log" +) + +const ( + eventType string = "experimental-logger-testing" +) + + +func main() { + arv, err := arvadosclient.MakeArvadosClient() + if err != nil { + log.Fatalf("Error setting up arvados client %v", err) + } + + l := logger.NewLogger(logger.LoggerParams{Client: arv, + EventType: eventType, + // No minimum write interval + }) + + logData := l.Acquire() + logData["Ninja"] = "Misha" + logData = l.Release() +}