Added Logger.MutateLog() on Tom's suggestion. Tried it out in one instance to make...
authormishaz <misha@curoverse.com>
Wed, 21 Jan 2015 01:31:17 +0000 (01:31 +0000)
committerTom Clegg <tom@curoverse.com>
Fri, 13 Feb 2015 21:25:31 +0000 (16:25 -0500)
sdk/go/logger/logger.go
services/datamanager/datamanager.go

index ea0be3336eef73cc8f69501a5e6ee22425ff08b2..2a4a962a0b1c2815765c447121f1f7891cc43318 100644 (file)
@@ -37,6 +37,17 @@ type LoggerParams struct {
        MinimumWriteInterval time.Duration               // Wait at least this long between log writes
 }
 
+// A LogMutator is a function which modifies the log entry.
+// It takes two maps as arguments, properties is the first and entry
+// is the second
+// properties is a shortcut for entry["properties"].(map[string]interface{})
+// properties can take any values you want to give it.
+// entry will only take the fields listed at http://doc.arvados.org/api/schema/Log.html
+// properties and entry are only safe to access inside the LogMutator,
+// they should not be stored anywhere, otherwise you'll risk
+// concurrent access.
+type LogMutator func(map[string]interface{}, map[string]interface{})
+
 // A Logger is used to build up a log entry over time and write every
 // version of it.
 type Logger struct {
@@ -51,7 +62,7 @@ type Logger struct {
        lastWrite time.Time // The last time we wrote a log entry
        modified  bool      // Has this data been modified since the last write
 
-       writeHooks []func(map[string]interface{}, map[string]interface{})
+       writeHooks []LogMutator
 }
 
 // Create a new logger based on the specified parameters.
@@ -81,13 +92,20 @@ func (l *Logger) Edit() (properties map[string]interface{}, entry map[string]int
        return l.properties, l.entry
 }
 
+// function to test new api, replacing Edit() and Record()
+func (l *Logger) MutateLog(mutator LogMutator) {
+       mutator(l.Edit())
+       l.Record()
+}
+
 // Adds a hook which will be called every time this logger writes an entry.
 // The hook takes properties and entry as arguments, in that order.
 // This is useful for stuff like memory profiling.
 // This must be called between Edit() and Record() (e.g. while holding the lock)
-func (l *Logger) AddWriteHook(hook func(map[string]interface{},
-       map[string]interface{})) {
+func (l *Logger) AddWriteHook(hook LogMutator) {
+       // TODO(misha): Acquire lock here! and erase comment about edit.
        l.writeHooks = append(l.writeHooks, hook)
+       // TODO(misha): consider flipping the dirty bit here.
 }
 
 // Write the log entry you've built up so far. Do not edit the maps
index e73bdb96530f56d39b8934087025c80a6e59ed02..deeea5dcb379ea9c05bee0b525f98b5f2f8bcf94 100644 (file)
@@ -53,21 +53,23 @@ func main() {
        }
 
        if arvLogger != nil {
-               properties, _ := arvLogger.Edit()
-               runInfo := make(map[string]interface{})
-               runInfo["start_time"] = time.Now()
-               runInfo["args"] = os.Args
-               hostname, err := os.Hostname()
-               if err != nil {
-                       runInfo["hostname_error"] = err.Error()
-               } else {
-                       runInfo["hostname"] = hostname
-               }
-               runInfo["pid"] = os.Getpid()
-               properties["run_info"] = runInfo
-
+               arvLogger.MutateLog(func(properties map[string]interface{},
+                       entry map[string]interface{}) {
+                               runInfo := make(map[string]interface{})
+                               runInfo["start_time"] = time.Now()
+                               runInfo["args"] = os.Args
+                               hostname, err := os.Hostname()
+                               if err != nil {
+                                       runInfo["hostname_error"] = err.Error()
+                               } else {
+                                       runInfo["hostname"] = hostname
+                               }
+                               runInfo["pid"] = os.Getpid()
+                               properties["run_info"] = runInfo
+                       })
+
+               arvLogger.Edit()
                arvLogger.AddWriteHook(LogMemoryAlloc)
-
                arvLogger.Record()
        }
 
@@ -98,7 +100,6 @@ func main() {
 }
 
 func LogMemoryAlloc(properties map[string]interface{}, entry map[string]interface{}) {
-       _ = entry // keep the compiler from complaining
        runInfo := properties["run_info"].(map[string]interface{})
        var memStats runtime.MemStats
        runtime.ReadMemStats(&memStats)