Skip to content

Commit

Permalink
Change timestamp data type to unixnano in Metrics Protobuf definitions (
Browse files Browse the repository at this point in the history
#33)

* Change timestamp data type to unixnano in Metrics Protobuf definitions

This change applies the refinement approach that is already performed on Traces
Protobuf definitions as part of open-telemetry/oteps#59 and
which proved to yield significant performance improvements.

I replaced google.protobuf.Timestamp by int64 time in unix epoch nanoseconds.

Simple benchmark in Go demonstrates the following improvement of encoding and decoding
compared to the current state:

```
===== Encoded sizes
Encoding                       Uncompressed  Improved        Compressed  Improved
Baseline/MetricOne              20000 bytes  [1.000], gziped 1506 bytes  [1.000]
Proposed/MetricOne              18250 bytes  [1.096], gziped 1433 bytes  [1.051]

Encoding                       Uncompressed  Improved        Compressed  Improved
Baseline/MetricSeries           51797 bytes  [1.000], gziped 6455 bytes  [1.000]
Proposed/MetricSeries           43047 bytes  [1.203], gziped 6093 bytes  [1.059]

goos: darwin
goarch: amd64
pkg: github.com/tigrannajaryan/exp-otelproto/encodings
BenchmarkEncode/Baseline/MetricOne-8         	      30	 186998840 ns/op
BenchmarkEncode/Proposed/MetricOne-8         	      36	 166668705 ns/op

BenchmarkEncode/Baseline/MetricSeries-8      	       8	 632391842 ns/op
BenchmarkEncode/Proposed/MetricSeries-8      	      10	 537384515 ns/op

BenchmarkDecode/Baseline/MetricOne-8         	      16	 348156010 ns/op	171896049 B/op	 4974000 allocs/op
BenchmarkDecode/Proposed/MetricOne-8         	      19	 314727259 ns/op	155096036 B/op	 4624000 allocs/op

BenchmarkDecode/Baseline/MetricSeries-8      	       5	1013035422 ns/op	440696048 B/op	11874000 allocs/op
BenchmarkDecode/Proposed/MetricSeries-8      	       6	 846887981 ns/op	356696040 B/op	10124000 allocs/op
```

It is 10-15% faster and is 10-20% smaller on the wire and in memory.

Benchmarks encode and decode 500 batches of 2 metrics: one int64 Gauge with 5 time series
and one Histogram of doubles with 1 time series and single bucket. Each time series for
both metrics contains either 1 data point (MetricOne) or 5 data points (MetricSeries).
Both metrics have 2 labels.

Benchmark source code is available at:
https://github.com/tigrannajaryan/exp-otelproto/blob/master/encodings/encoding_test.go

* Change timestamp from int64 to sfixed64

* Change timestamp interval from closed to open
  • Loading branch information
tigrannajaryan authored and bogdandrutu committed Oct 30, 2019
1 parent 7b88843 commit 608c358
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions opentelemetry/proto/metrics/v1/metrics.proto
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ syntax = "proto3";

package opentelemetry.proto.metrics.v1;

import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
import "opentelemetry/proto/resource/v1/resource.proto";

Expand Down Expand Up @@ -124,15 +123,24 @@ message LabelValue {

// A timestamped measurement.
message Point {
// Must be present for counter/cumulative metrics. The time when the
// cumulative value was reset to zero. The cumulative value is over the time
// interval (start_timestamp, timestamp]. If not specified, the backend can
// use the previous recorded value.
google.protobuf.Timestamp start_timestamp = 1;

// The moment when this point was recorded.
// If not specified, the timestamp will be decided by the backend.
google.protobuf.Timestamp timestamp = 2;
// start_time_unixnano is the time when the cumulative value was reset to zero.
// This is used for Counter type only. For Gauge the value is not specified and
// defaults to 0.
//
// The cumulative value is over the time interval (start_time_unixnano, timestamp_unixnano].
// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.
//
// Value of 0 indicates that the start_time is the same as that of the previous
// data point in this timeseries. When creating timeseries of this type it is recommended
// to omit this value if the start_time does not change, since it results in more
// compact encoding on the wire.
// If the value of 0 occurs for the first data point in the timeseries it means that
// the timestamp is unspecified. In that case the timestamp may be decided by the backend.
sfixed64 start_time_unixnano = 1;

// timestamp_unixnano is the moment when this value was recorded.
// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.
sfixed64 timestamp_unixnano = 2;

// The actual point value.
oneof value {
Expand Down Expand Up @@ -204,8 +212,9 @@ message HistogramValue {
// belongs to.
double value = 1;

// The observation (sampling) time of the above value.
google.protobuf.Timestamp timestamp = 2;
// timestamp_unixnano is the moment when this exemplar was recorded.
// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.
sfixed64 timestamp_unixnano = 2;

// Contextual information about the example value.
map<string, string> attachments = 3;
Expand Down

0 comments on commit 608c358

Please sign in to comment.