event: various builder changes

- Add At method to set time.

- Factor out common log code.

- Fix minor bugs.

Change-Id: I98d6ff262e3178b3470945bd3644dc9474dc3d56
Reviewed-on: https://go-review.googlesource.com/c/exp/+/319729
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/event/builder.go b/event/builder.go
index 68f9483..e636acc 100644
--- a/event/builder.go
+++ b/event/builder.go
@@ -10,6 +10,7 @@
 	"context"
 	"fmt"
 	"sync"
+	"time"
 )
 
 // Builder is a fluent builder for construction of new events.
@@ -106,7 +107,7 @@
 
 // WithAll adds all the supplied labels to the event being constructed.
 func (b Builder) WithAll(labels ...Label) Builder {
-	if b.data != nil || len(labels) == 0 {
+	if b.data == nil || len(labels) == 0 {
 		return b
 	}
 	if len(b.data.Event.Labels) == 0 {
@@ -117,17 +118,20 @@
 	return b
 }
 
+func (b Builder) At(t time.Time) Builder {
+	if b.data != nil {
+		b.data.Event.At = t
+	}
+	return b
+}
+
 // Log is a helper that calls Deliver with LogKind.
 func (b Builder) Log(message string) {
 	if b.data == nil {
 		return
 	}
 	if b.data.exporter.log != nil {
-		b.data.exporter.mu.Lock()
-		defer b.data.exporter.mu.Unlock()
-		b.data.Event.Message = message
-		b.data.exporter.prepare(&b.data.Event)
-		b.data.exporter.log.Log(b.data.ctx, &b.data.Event)
+		b.log(message)
 	}
 	b.done()
 }
@@ -139,15 +143,19 @@
 		return
 	}
 	if b.data.exporter.log != nil {
-		b.data.exporter.mu.Lock()
-		defer b.data.exporter.mu.Unlock()
-		b.data.Event.Message = fmt.Sprintf(template, args...)
-		b.data.exporter.prepare(&b.data.Event)
-		b.data.exporter.log.Log(b.data.ctx, &b.data.Event)
+		b.log(fmt.Sprintf(template, args...))
 	}
 	b.done()
 }
 
+func (b Builder) log(message string) {
+	b.data.exporter.mu.Lock()
+	defer b.data.exporter.mu.Unlock()
+	b.data.Event.Message = message
+	b.data.exporter.prepare(&b.data.Event)
+	b.data.exporter.log.Log(b.data.ctx, &b.data.Event)
+}
+
 // Metric is a helper that calls Deliver with MetricKind.
 func (b Builder) Metric() {
 	if b.data == nil {
@@ -207,7 +215,7 @@
 
 // WithAll adds all the supplied labels to the event being constructed.
 func (b TraceBuilder) WithAll(labels ...Label) TraceBuilder {
-	if b.data != nil || len(labels) == 0 {
+	if b.data == nil || len(labels) == 0 {
 		return b
 	}
 	if len(b.data.Event.Labels) == 0 {
@@ -218,6 +226,13 @@
 	return b
 }
 
+func (b TraceBuilder) At(t time.Time) TraceBuilder {
+	if b.data != nil {
+		b.data.Event.At = t
+	}
+	return b
+}
+
 // Start delivers a start event with the given name and labels.
 // Its second return value is a function that should be called to deliver the
 // matching end event.