event: constructors require metric description

Require a description in NewCounter, etc.

Also unexport MetricDescriptor.description for consistency with other
fields.

Change-Id: Id91279f89be9a65a528f3a3c9b4bde00ce622e54
Reviewed-on: https://go-review.googlesource.com/c/exp/+/326674
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/bench/event_test.go b/event/bench/event_test.go
index 07d45a8..1e8e59c 100644
--- a/event/bench/event_test.go
+++ b/event/bench/event_test.go
@@ -68,7 +68,7 @@
 		},
 	}
 
-	gauge       = event.NewFloatGauge("gauge")
+	gauge       = event.NewFloatGauge("gauge", "a gauge")
 	eventMetric = Hooks{
 		AStart: func(ctx context.Context, a int) context.Context {
 			event.To(ctx).With(aStat.Of(a)).Metric(gauge.Record(1))
diff --git a/event/builder_test.go b/event/builder_test.go
index 5e0174f..4f4166c 100644
--- a/event/builder_test.go
+++ b/event/builder_test.go
@@ -129,7 +129,7 @@
 
 func TestTraceDuration(t *testing.T) {
 	// Verify that a trace can can emit a latency metric.
-	dur := event.NewDuration("test")
+	dur := event.NewDuration("test", "")
 	want := 200 * time.Millisecond
 
 	check := func(t *testing.T, h *testTraceDurationHandler) {
@@ -171,7 +171,7 @@
 
 func BenchmarkBuildContext(b *testing.B) {
 	// How long does it take to deliver an event from a nested context?
-	c := event.NewCounter("c")
+	c := event.NewCounter("c", "")
 	for _, depth := range []int{1, 5, 7, 10} {
 		b.Run(fmt.Sprintf("depth %d", depth), func(b *testing.B) {
 			ctx := event.WithExporter(context.Background(), event.NewExporter(event.NopHandler{}, nil))
diff --git a/event/common_test.go b/event/common_test.go
index 4066f33..1fdfbd5 100644
--- a/event/common_test.go
+++ b/event/common_test.go
@@ -15,7 +15,7 @@
 
 func TestCommon(t *testing.T) {
 	ctx, h := eventtest.NewCapture()
-	m := event.NewCounter("m")
+	m := event.NewCounter("m", "")
 
 	const simple = "simple message"
 	const trace = "a trace"
diff --git a/event/event_test.go b/event/event_test.go
index 1656e56..4a01b72 100644
--- a/event/event_test.go
+++ b/event/event_test.go
@@ -23,9 +23,9 @@
 	l1      = keys.Int("l1").Of(1)
 	l2      = keys.Int("l2").Of(2)
 	l3      = keys.Int("l3").Of(3)
-	counter = event.NewCounter("hits")
-	gauge   = event.NewFloatGauge("temperature")
-	latency = event.NewDuration("latency")
+	counter = event.NewCounter("hits", "cache hits")
+	gauge   = event.NewFloatGauge("temperature", "CPU board temperature in Celsius")
+	latency = event.NewDuration("latency", "how long it took")
 )
 
 func TestPrint(t *testing.T) {
diff --git a/event/metric.go b/event/metric.go
index 52b27ed..0c989ef 100644
--- a/event/metric.go
+++ b/event/metric.go
@@ -18,7 +18,7 @@
 type MetricDescriptor struct {
 	namespace   string
 	name        string
-	Description string
+	description string
 	// TODO: deal with units. Follow otel, or define Go types for common units.
 	// We don't need a time unit because we'll use time.Duration, and the only
 	// other unit otel currently defines (besides dimensionless) is bytes.
@@ -28,11 +28,11 @@
 // The namespace defaults to the import path of the caller of NewMetricDescriptor.
 // Use SetNamespace to provide a different one.
 // Neither the name nor the namespace can be empty.
-func NewMetricDescriptor(name string) *MetricDescriptor {
-	return newMetricDescriptor(name)
+func NewMetricDescriptor(name, description string) *MetricDescriptor {
+	return newMetricDescriptor(name, description)
 }
 
-func newMetricDescriptor(name string) *MetricDescriptor {
+func newMetricDescriptor(name, description string) *MetricDescriptor {
 	if name == "" {
 		panic("name cannot be empty")
 	}
@@ -45,7 +45,8 @@
 		//   2  this function
 		//   3  caller of this function (one of the NewXXX methods in this package)
 		//   4  caller's caller
-		namespace: importPath(4, nil),
+		namespace:   importPath(4, nil),
+		description: description,
 	}
 }
 
@@ -61,8 +62,9 @@
 	return fmt.Sprintf("Metric(\"%s/%s\")", m.namespace, m.name)
 }
 
-func (m *MetricDescriptor) Name() string      { return m.name }
-func (m *MetricDescriptor) Namespace() string { return m.namespace }
+func (m *MetricDescriptor) Name() string        { return m.name }
+func (m *MetricDescriptor) Namespace() string   { return m.namespace }
+func (m *MetricDescriptor) Description() string { return m.description }
 
 // A MetricValue is a pair of a Metric and a Value.
 type MetricValue struct {
@@ -76,8 +78,8 @@
 }
 
 // NewCounter creates a counter with the given name.
-func NewCounter(name string) *Counter {
-	return &Counter{newMetricDescriptor(name)}
+func NewCounter(name, description string) *Counter {
+	return &Counter{newMetricDescriptor(name, description)}
 }
 
 // Descriptor returns the receiver's MetricDescriptor.
@@ -99,8 +101,8 @@
 }
 
 // NewFloatGauge creates a new FloatGauge with the given name.
-func NewFloatGauge(name string) *FloatGauge {
-	return &FloatGauge{newMetricDescriptor(name)}
+func NewFloatGauge(name, description string) *FloatGauge {
+	return &FloatGauge{newMetricDescriptor(name, description)}
 }
 
 // Descriptor returns the receiver's MetricDescriptor.
@@ -122,8 +124,8 @@
 }
 
 // NewDuration creates a new Duration with the given name.
-func NewDuration(name string) *Duration {
-	return &Duration{newMetricDescriptor(name)}
+func NewDuration(name, description string) *Duration {
+	return &Duration{newMetricDescriptor(name, description)}
 }
 
 // Descriptor returns the receiver's MetricDescriptor.