Repository: census-instrumentation/opencensus-go
Pull request #384 (2018-01-30 19:13:52)

Calculate span duration using the monotonic clock
Fixes: #381

ramonza: Updated to restore EndTime and just adjust it.
ramonza: @rakyll PTAL

Patch:
diff --git a/exporter/jaeger/jaeger.go b/exporter/jaeger/jaeger.go
index 2f283b3..b41bd73 100644
--- a/exporter/jaeger/jaeger.go
+++ b/exporter/jaeger/jaeger.go
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 // Package jaeger contains an OpenCensus tracing exporter for Jaeger.
-package jaeger
+package jaeger // import "go.opencensus.io/exporter/jaeger"
 
 import (
 	"bytes"
diff --git a/exporter/prometheus/prometheus.go b/exporter/prometheus/prometheus.go
index b133021..e14abc3 100644
--- a/exporter/prometheus/prometheus.go
+++ b/exporter/prometheus/prometheus.go
@@ -16,7 +16,7 @@
 // Stackdriver Monitoring.
 //
 // Please note that this exporter is currently work in progress and not complete.
-package prometheus
+package prometheus // import "go.opencensus.io/exporter/prometheus"
 
 import (
 	"bytes"
diff --git a/exporter/stackdriver/stackdriver.go b/exporter/stackdriver/stackdriver.go
index 3568a13..dfd6a1d 100644
--- a/exporter/stackdriver/stackdriver.go
+++ b/exporter/stackdriver/stackdriver.go
@@ -56,7 +56,7 @@
 //
 // All outgoing requests from client will include a Stackdriver Trace header.
 // See the httptrace package for how to handle incoming requests.
-package stackdriver
+package stackdriver // import "go.opencensus.io/exporter/stackdriver"
 
 import (
 	"time"
diff --git a/exporter/zipkin/zipkin.go b/exporter/zipkin/zipkin.go
index 77d160e..835d4b9 100644
--- a/exporter/zipkin/zipkin.go
+++ b/exporter/zipkin/zipkin.go
@@ -29,7 +29,7 @@
 // 		reporter := http.NewReporter("http://localhost:9411/api/v2/spans")
 // 		exporter := zipkin.NewExporter(reporter, localEndpoint)
 // 		trace.RegisterExporter(exporter)
-package zipkin
+package zipkin // import "go.opencensus.io/exporter/zipkin"
 
 import (
 	"encoding/binary"
diff --git a/plugin/grpc/grpcstats/grpcstats.go b/plugin/grpc/grpcstats/grpcstats.go
index 9fa7258..d49e991 100644
--- a/plugin/grpc/grpcstats/grpcstats.go
+++ b/plugin/grpc/grpcstats/grpcstats.go
@@ -63,8 +63,8 @@ var (
 	aggDistCounts = istats.DistributionAggregation(rpcCountBucketBoundaries)
 
 	windowCumulative    = istats.Cumulative{}
-	windowSlidingHour   = istats.Interval{Duration: 1 * time.Hour, Intervals: 6}
-	windowSlidingMinute = istats.Interval{Duration: 1 * time.Minute, Intervals: 6}
+	windowSlidingHour   = istats.Interval{Duration: 1 * time.Hour, SubIntervals: 6}
+	windowSlidingMinute = istats.Interval{Duration: 1 * time.Minute, SubIntervals: 6}
 
 	keyMethod tag.Key
 	keyStatus tag.Key
diff --git a/plugin/http/httptrace/httptrace.go b/plugin/http/httptrace/httptrace.go
index abdfb5b..47e0ba7 100644
--- a/plugin/http/httptrace/httptrace.go
+++ b/plugin/http/httptrace/httptrace.go
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 // Package httptrace contains OpenCensus tracing integrations with net/http.
-package httptrace
+package httptrace // import "go.opencensus.io/plugin/http/httptrace"
 
 import (
 	"io"
diff --git a/plugin/http/propagation/google/google.go b/plugin/http/propagation/google/google.go
index c29fb0b..e7ae06d 100644
--- a/plugin/http/propagation/google/google.go
+++ b/plugin/http/propagation/google/google.go
@@ -14,7 +14,7 @@
 
 // Package google contains a propagation.HTTPFormat implementation
 // for Google Cloud Trace and Stackdriver.
-package google
+package google // import "go.opencensus.io/plugin/http/propagation/google"
 
 import (
 	"encoding/binary"
diff --git a/stats/aggregation.go b/stats/aggregation.go
index fa9bf8e..b64adf4 100644
--- a/stats/aggregation.go
+++ b/stats/aggregation.go
@@ -129,8 +129,13 @@ type aggregatorInterval struct {
 	idx             int
 }
 
+const defaultSubIntervals = 5
+
 // newAggregatorInterval creates an aggregatorSlidingTime.
 func newAggregatorInterval(now time.Time, d time.Duration, subIntervalsCount int, newAggregationValue func() AggregationData) *aggregatorInterval {
+	if subIntervalsCount == 0 {
+		subIntervalsCount = defaultSubIntervals
+	}
 	subDuration := d / time.Duration(subIntervalsCount)
 	start := now.Add(-subDuration * time.Duration(subIntervalsCount))
 	var entries []*timeSerieEntry
diff --git a/stats/window.go b/stats/window.go
index 9522944..e51ddc9 100644
--- a/stats/window.go
+++ b/stats/window.go
@@ -44,12 +44,12 @@ func (w Cumulative) newAggregator(now time.Time, newAggregationData func() Aggre
 // Interval is a window that indicates that the aggregation occurs over a sliding
 // window of time: last n seconds, minutes, hours.
 type Interval struct {
-	Duration  time.Duration
-	Intervals int
+	Duration     time.Duration
+	SubIntervals int
 }
 
 func (w Interval) isWindow() {}
 
 func (w Interval) newAggregator(now time.Time, newAggregationData func() AggregationData) aggregator {
-	return newAggregatorInterval(now, w.Duration, w.Intervals, newAggregationData)
+	return newAggregatorInterval(now, w.Duration, w.SubIntervals, newAggregationData)
 }
diff --git a/trace/export.go b/trace/export.go
index a767f61..2a7ee25 100644
--- a/trace/export.go
+++ b/trace/export.go
@@ -60,11 +60,13 @@ type SpanData struct {
 	ParentSpanID SpanID
 	Name         string
 	StartTime    time.Time
-	EndTime      time.Time
+	// The wall clock time of EndTime will be adjusted to always be offset
+	// from StartTime by the duration of the span.
+	EndTime time.Time
 	// The values of Attributes each have type string, bool, or int64.
-	Attributes    map[string]interface{}
-	Annotations   []Annotation
-	MessageEvents []MessageEvent
+	Attributes      map[string]interface{}
+	Annotations     []Annotation
+	MessageEvents   []MessageEvent
 	Status
 	Links           []Link
 	HasRemoteParent bool
diff --git a/trace/trace.go b/trace/trace.go
index b16e84e..26f9ce8 100644
--- a/trace/trace.go
+++ b/trace/trace.go
@@ -223,7 +223,7 @@ func (s *Span) End() {
 	s.exportOnce.Do(func() {
 		// TODO: optimize to avoid this call if sd won't be used.
 		sd := s.makeSpanData()
-		sd.EndTime = time.Now()
+		sd.EndTime = sd.StartTime.Add(time.Since(sd.StartTime))
 		if s.spanStore != nil {
 			s.spanStore.finished(s, sd)
 		}
diff --git a/zpages/zpages.go b/zpages/zpages.go
index a1fd15e..5d4a9bd 100644
--- a/zpages/zpages.go
+++ b/zpages/zpages.go
@@ -24,7 +24,7 @@
 // 	zpages.AddDefaultHTTPHandlers()
 // If your program does not already start an HTTP server, you can use:
 // 	go func() { log.Fatal(http.ListenAndServe(":8080", nil)) }()
-package zpages
+package zpages // import "go.opencensus.io/zpages"
 
 import (
 	"net/http"


Test patch:
diff --git a/stats/worker_test.go b/stats/worker_test.go
index d27a7f6..bcac605 100644
--- a/stats/worker_test.go
+++ b/stats/worker_test.go
@@ -622,7 +622,7 @@ func TestReportUsage(t *testing.T) {
 
 	cum1, _ := NewView("cum1", "", nil, m, CountAggregation{}, Cumulative{})
 	cum2, _ := NewView("cum1", "", nil, m, CountAggregation{}, &Cumulative{})
-	interval, _ := NewView("cum1", "", nil, m, CountAggregation{}, Interval{Duration: 5 * time.Millisecond, Intervals: 1})
+	interval, _ := NewView("cum1", "", nil, m, CountAggregation{}, Interval{Duration: 5 * time.Millisecond, SubIntervals: 1})
 
 	tests := []struct {
 		name         string