1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// This package describes the Metrics data model. It is currently experimental
16// but may eventually become the wire format for metrics. Please see
17// https://github.com/census-instrumentation/opencensus-specs/blob/master/stats/Metrics.md
18// for more details.
19
20syntax = "proto3";
21
22package opencensus.proto.metrics.v1;
23
24import "google/protobuf/timestamp.proto";
25import "google/protobuf/wrappers.proto";
26import "opencensus/proto/resource/v1/resource.proto";
27
28option go_package = "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1";
29
30option java_multiple_files = true;
31option java_package = "io.opencensus.proto.metrics.v1";
32option java_outer_classname = "MetricsProto";
33
34option ruby_package = "OpenCensus.Proto.Metrics.V1";
35
36// Defines a Metric which has one or more timeseries.
37message Metric {
38  // The descriptor of the Metric.
39  // TODO(issue #152): consider only sending the name of descriptor for
40  // optimization.
41  MetricDescriptor metric_descriptor = 1;
42
43  // One or more timeseries for a single metric, where each timeseries has
44  // one or more points.
45  repeated TimeSeries timeseries = 2;
46
47  // The resource for the metric. If unset, it may be set to a default value
48  // provided for a sequence of messages in an RPC stream.
49  opencensus.proto.resource.v1.Resource resource = 3;
50}
51
52// Defines a metric type and its schema.
53message MetricDescriptor {
54  // The metric type, including its DNS name prefix. It must be unique.
55  string name = 1;
56
57  // A detailed description of the metric, which can be used in documentation.
58  string description = 2;
59
60  // The unit in which the metric value is reported. Follows the format
61  // described by http://unitsofmeasure.org/ucum.html.
62  string unit = 3;
63
64  // The kind of metric. It describes how the data is reported.
65  //
66  // A gauge is an instantaneous measurement of a value.
67  //
68  // A cumulative measurement is a value accumulated over a time interval. In
69  // a time series, cumulative measurements should have the same start time,
70  // increasing values and increasing end times, until an event resets the
71  // cumulative value to zero and sets a new start time for the following
72  // points.
73  enum Type {
74    // Do not use this default value.
75    UNSPECIFIED = 0;
76
77    // Integer gauge. The value can go both up and down.
78    GAUGE_INT64 = 1;
79
80    // Floating point gauge. The value can go both up and down.
81    GAUGE_DOUBLE = 2;
82
83    // Distribution gauge measurement. The count and sum can go both up and
84    // down. Recorded values are always >= 0.
85    // Used in scenarios like a snapshot of time the current items in a queue
86    // have spent there.
87    GAUGE_DISTRIBUTION = 3;
88
89    // Integer cumulative measurement. The value cannot decrease, if resets
90    // then the start_time should also be reset.
91    CUMULATIVE_INT64 = 4;
92
93    // Floating point cumulative measurement. The value cannot decrease, if
94    // resets then the start_time should also be reset. Recorded values are
95    // always >= 0.
96    CUMULATIVE_DOUBLE = 5;
97
98    // Distribution cumulative measurement. The count and sum cannot decrease,
99    // if resets then the start_time should also be reset.
100    CUMULATIVE_DISTRIBUTION = 6;
101
102    // Some frameworks implemented Histograms as a summary of observations
103    // (usually things like request durations and response sizes). While it
104    // also provides a total count of observations and a sum of all observed
105    // values, it calculates configurable percentiles over a sliding time
106    // window. This is not recommended, since it cannot be aggregated.
107    SUMMARY = 7;
108  }
109  Type type = 4;
110
111  // The label keys associated with the metric descriptor.
112  repeated LabelKey label_keys = 5;
113}
114
115// Defines a label key associated with a metric descriptor.
116message LabelKey {
117  // The key for the label.
118  string key = 1;
119
120  // A human-readable description of what this label key represents.
121  string description = 2;
122}
123
124// A collection of data points that describes the time-varying values
125// of a metric.
126message TimeSeries {
127  // Must be present for cumulative metrics. The time when the cumulative value
128  // was reset to zero. Exclusive. The cumulative value is over the time interval
129  // (start_timestamp, timestamp]. If not specified, the backend can use the
130  // previous recorded value.
131  google.protobuf.Timestamp start_timestamp = 1;
132
133  // The set of label values that uniquely identify this timeseries. Applies to
134  // all points. The order of label values must match that of label keys in the
135  // metric descriptor.
136  repeated LabelValue label_values = 2;
137
138  // The data points of this timeseries. Point.value type MUST match the
139  // MetricDescriptor.type.
140  repeated Point points = 3;
141}
142
143message LabelValue {
144  // The value for the label.
145  string value = 1;
146  // If false the value field is ignored and considered not set.
147  // This is used to differentiate a missing label from an empty string.
148  bool has_value = 2;
149}
150
151// A timestamped measurement.
152message Point {
153  // The moment when this point was recorded. Inclusive.
154  // If not specified, the timestamp will be decided by the backend.
155  google.protobuf.Timestamp timestamp = 1;
156
157  // The actual point value.
158  oneof value {
159    // A 64-bit integer.
160    int64 int64_value = 2;
161
162    // A 64-bit double-precision floating-point number.
163    double double_value = 3;
164
165    // A distribution value.
166    DistributionValue distribution_value = 4;
167
168    // A summary value. This is not recommended, since it cannot be aggregated.
169    SummaryValue summary_value = 5;
170  }
171}
172
173// Distribution contains summary statistics for a population of values. It
174// optionally contains a histogram representing the distribution of those
175// values across a set of buckets.
176message DistributionValue {
177  // The number of values in the population. Must be non-negative. This value
178  // must equal the sum of the values in bucket_counts if a histogram is
179  // provided.
180  int64 count = 1;
181
182  // The sum of the values in the population. If count is zero then this field
183  // must be zero.
184  double sum = 2;
185
186  // The sum of squared deviations from the mean of the values in the
187  // population. For values x_i this is:
188  //
189  //     Sum[i=1..n]((x_i - mean)^2)
190  //
191  // Knuth, "The Art of Computer Programming", Vol. 2, page 323, 3rd edition
192  // describes Welford's method for accumulating this sum in one pass.
193  //
194  // If count is zero then this field must be zero.
195  double sum_of_squared_deviation = 3;
196
197  // A Distribution may optionally contain a histogram of the values in the
198  // population. The bucket boundaries for that histogram are described by
199  // BucketOptions.
200  //
201  // If bucket_options has no type, then there is no histogram associated with
202  // the Distribution.
203  message BucketOptions {
204    oneof type {
205      // Bucket with explicit bounds.
206      Explicit explicit = 1;
207    }
208
209    // Specifies a set of buckets with arbitrary upper-bounds.
210    // This defines size(bounds) + 1 (= N) buckets. The boundaries for bucket
211    // index i are:
212    //
213    // [0, bucket_bounds[i]) for i == 0
214    // [bucket_bounds[i-1], bucket_bounds[i]) for 0 < i < N-1
215    // [bucket_bounds[i], +infinity) for i == N-1
216    message Explicit {
217      // The values must be strictly increasing and > 0.
218      repeated double bounds = 1;
219    }
220
221    // TODO: If OpenMetrics decides to support (a, b] intervals we should add
222    // support for these by defining a boolean value here which decides what
223    // type of intervals to use.
224  }
225
226  // Don't change bucket boundaries within a TimeSeries if your backend doesn't
227  // support this.
228  // TODO(issue #152): consider not required to send bucket options for
229  // optimization.
230  BucketOptions bucket_options = 4;
231
232  message Bucket {
233    // The number of values in each bucket of the histogram, as described in
234    // bucket_bounds.
235    int64 count = 1;
236
237    // If the distribution does not have a histogram, then omit this field.
238    Exemplar exemplar = 2;
239  }
240
241  // If the distribution does not have a histogram, then omit this field.
242  // If there is a histogram, then the sum of the values in the Bucket counts
243  // must equal the value in the count field of the distribution.
244  repeated Bucket buckets = 5;
245
246  // Exemplars are example points that may be used to annotate aggregated
247  // Distribution values. They are metadata that gives information about a
248  // particular value added to a Distribution bucket.
249  message Exemplar {
250    // Value of the exemplar point. It determines which bucket the exemplar
251    // belongs to.
252    double value = 1;
253
254    // The observation (sampling) time of the above value.
255    google.protobuf.Timestamp timestamp = 2;
256
257    // Contextual information about the example value.
258    map<string, string> attachments = 3;
259  }
260}
261
262// The start_timestamp only applies to the count and sum in the SummaryValue.
263message SummaryValue {
264  // The total number of recorded values since start_time. Optional since
265  // some systems don't expose this.
266  google.protobuf.Int64Value count = 1;
267
268  // The total sum of recorded values since start_time. Optional since some
269  // systems don't expose this. If count is zero then this field must be zero.
270  // This field must be unset if the sum is not available.
271  google.protobuf.DoubleValue sum = 2;
272
273  // The values in this message can be reset at arbitrary unknown times, with
274  // the requirement that all of them are reset at the same time.
275  message Snapshot {
276    // The number of values in the snapshot. Optional since some systems don't
277    // expose this.
278    google.protobuf.Int64Value count = 1;
279
280    // The sum of values in the snapshot. Optional since some systems don't
281    // expose this. If count is zero then this field must be zero or not set
282    // (if not supported).
283    google.protobuf.DoubleValue sum = 2;
284
285    // Represents the value at a given percentile of a distribution.
286    message ValueAtPercentile {
287      // The percentile of a distribution. Must be in the interval
288      // (0.0, 100.0].
289      double percentile = 1;
290
291      // The value at the given percentile of a distribution.
292      double value = 2;
293    }
294
295    // A list of values at different percentiles of the distribution calculated
296    // from the current snapshot. The percentiles must be strictly increasing.
297    repeated ValueAtPercentile percentile_values = 3;
298  }
299
300  // Values calculated over an arbitrary time window.
301  Snapshot snapshot = 3;
302}
303
304