pkg/etw: Add support for time.Time

This change adds support for encoding time.Time values as FILETIME
values in tracelogging events. FILETIME has slightly less precision than
time.Time (100ns vs 1ns), but it is the closest availble match.
This commit is contained in:
John Starks
2019-05-05 00:02:18 +00:00
parent 7776571819
commit 89c1d0e19d
2 changed files with 18 additions and 0 deletions
+6
View File
@@ -3,6 +3,7 @@ package etw
import (
"bytes"
"encoding/binary"
"syscall"
)
// eventData maintains a buffer which builds up the data for an ETW event. It
@@ -63,3 +64,8 @@ func (ed *eventData) writeUint32(value uint32) {
func (ed *eventData) writeUint64(value uint64) {
binary.Write(&ed.buffer, binary.LittleEndian, value)
}
// writeFiletime appends a FILETIME to the buffer.
func (ed *eventData) writeFiletime(value syscall.Filetime) {
binary.Write(&ed.buffer, binary.LittleEndian, value)
}
+12
View File
@@ -4,6 +4,8 @@ import (
"fmt"
"math"
"reflect"
"syscall"
"time"
"unsafe"
)
@@ -380,6 +382,14 @@ func Struct(name string, opts ...FieldOpt) FieldOpt {
}
}
// Time adds a time to the event.
func Time(name string, value time.Time) FieldOpt {
return func(em *eventMetadata, ed *eventData) {
em.writeField(name, inTypeFileTime, outTypeDateTimeUTC, 0)
ed.writeFiletime(syscall.NsecToFiletime(value.UTC().UnixNano()))
}
}
// Currently, we support logging basic builtin types (int, string, etc), slices
// of basic builtin types, error, types derived from the basic types (e.g. "type
// foo int"), and structs (recursively logging their fields). We do not support
@@ -454,6 +464,8 @@ func SmartField(name string, v interface{}) FieldOpt {
return Float64Array(name, v)
case error:
return StringField(name, v.Error())
case time.Time:
return Time(name, v)
default:
switch rv := reflect.ValueOf(v); rv.Kind() {
case reflect.Bool: