| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| syntax = "proto3"; |
| |
| package cobalt; |
| |
| import "observation.proto"; |
| |
| // An Observation is a piece of data sent from a Cobalt client to the Cobalt |
| // server as input to a Report. |
| // |
| // Observations are associated with a specific Metric. They are built on a |
| // Fuchsia client based on the Events logged for that Metric. Observations are |
| // associated with a specific Report. They are built for the purpose of |
| // generating that Report. They are transmitted from the Fuchsia client to |
| // the Cobalt server where they are aggregated and analyzed in order to generate |
| // the Report. |
| // |
| // Observations may store their data using special privacy-preserving encodings. |
| // The specification of how to do this is part of the definition of a Report. |
| // Observations are built for a particular Report and so use an encoding |
| // appropriate for that Report. |
| // |
| // There are different types of Observations that are appropriate for different |
| // types of Metrics and different types of Reports. |
| // |
| // An Observation is always transmitted and stored along with |
| // some ObservationMetadata that describes, among other things, which Metric |
| // and which Report it is for and on which day the Observation was formed. |
| // |
| // Observations are transmitted from the client to the server encrypted, inside |
| // the |ciphertext| field of an EncryptedMessage. Many encrypted Observations |
| // are transmitted together inside of an ObservationBatch. |
| message Observation2 { |
| // Next observation_type ID: 8 |
| // Next general ID: 1002; |
| |
| // An Observation has one of the following types. |
| oneof observation_type { |
| IntegerEventObservation numeric_event = 1; |
| HistogramObservation histogram = 2; |
| BasicRapporObservation basic_rappor = 3; |
| RapporObservation string_rappor = 4; |
| ForculusObservation forculus = 5; |
| UniqueActivesObservation unique_actives = 6; |
| PerDeviceNumericObservation per_device_numeric = 7; |
| CustomObservation custom = 1000; |
| ReportParticipationObservation report_participation = 10000; |
| } |
| |
| // A quasi-unique identifier for this observation. This is randomly generated |
| // on the client and used on the server as part of a fully-unique identifier. |
| // This field allows the operation of sending an Observation to the Cobalt |
| // server to be idempotent: If the same Observation is transmitted twice then |
| // the server will store the observation only once. |
| bytes random_id = 1001; |
| } |
| |
| // Observations of type IntegerEventObservation contain an event type specified |
| // by its index, a component specified by its hash, and an integer value. |
| // This type of Observation is used in the following cases: |
| // |
| // (a) A Metric of type EVENT_COUNT and a Report of type |
| // EVENT_COMPONENT_OCCURRENCE_COUNT. |
| // In this case the Observation is *immediate* meaning it is generated |
| // directly from a single Event as soon as the Event is logged. The |value| |
| // field contains the count. Note that the |period_duration_micros| from the |
| // Event is not used. It's purpose is to compute event *rates* which are not |
| // relevant to the EVENT_COMPONENT_OCCURRENCE_COUNT Report type. |
| // |
| // (b) A Metric of type ELAPSED_TIME and a Report of type |
| // NUMERIC_AGGREGATION , INT_RANGE_HISTOGRAM or |
| // NUMERIC_PERF_RAW_DUMP. In this case the Observation again is |
| // immediate. The |value| field contains the duration in microseconds. |
| // |
| // (c) A Metric of type FrameRateMetric and a Report of type |
| // NUMERIC_AGGREGATION, INT_RANGE_HISTOGRAM or |
| // NUMERIC_PERF_RAW_DUMP. In this case the Observation again is |
| // immediate. The |value| field contains round(fps * 1000). |
| // |
| // (d) A Metric of type MemoryUseMetric and a Report of type |
| // NUMERIC_AGGREGATION , INT_RANGE_HISTOGRAM or |
| // NUMERIC_PERF_RAW_DUMP. In this case the Observation again is |
| // immediate. The |value| field contains the number of bytes. |
| message IntegerEventObservation { |
| // The event codes for each of the metric_dimensions of this observation. |
| // Multiple event codes are packed together into the bits of this value. |
| // |
| // See config/packed_event_codes.h for a description of the bit layout. |
| uint64 event_code = 1; |
| |
| // A hash of the component name. If component_name is empty then this field |
| // will be empty. Otherwise this field will contain the 32-byte SHA256 |
| // hash of component_name. |
| bytes component_name_hash = 2; |
| |
| int64 value = 3; |
| } |
| |
| // A pair consisting of a bucket index and a count. Each bucket is |
| // an integer range. The definition of the buckets and their indices |
| // is given in the MetricDefinition. |
| message HistogramBucket { |
| // The index of one of the buckets. |
| uint32 index = 1; |
| // The count for that bucket. |
| uint64 count = 2; |
| }; |
| |
| // Observations of type HistogramObservation contain an event type specified |
| // by its index, a component specified by its hash, and a histogram of |
| // integer-range buckets. This type of Observation is used in the |
| // following case: |
| // |
| // A MetricDefinition of type INT_HISTOGRAM and a Report of type |
| // INT_RANGE_HISTOGRAM. In this case the Observation is *immediate* meaning |
| // it is generated directly from a single INT_HISTOGRAM Event as soon as |
| // the Event is logged. |
| message HistogramObservation { |
| // The event codes for each of the metric_dimensions of this observation. |
| // Multiple event codes are packed together into the bits of this value. |
| uint64 event_code = 1; |
| |
| // A hash of the component name. If component_name is empty then this field |
| // will be empty. Otherwise this field will contain the 32-byte SHA256 |
| // hash of component_name. |
| bytes component_name_hash = 2; |
| |
| // The set of bucket indices and their corresponding counts. |
| repeated HistogramBucket buckets = 3; |
| }; |
| |
| // Observations of type UniqueActivesObservation are used when a |
| // MetricDefinition of type EVENT_OCCURRED is reported with a |
| // ReportDefinition of type UNIQUE_N_DAY_ACTIVES. An Observation |
| // of this type is created by aggregating Events on-device over |
| // a rolling window of 1, 7, or 30 days. |
| // |
| // A UniqueActivesObservation is generated each day for each event code of the |
| // associated MetricDefinition, for each window size in the associated |
| // ReportDefinition. A UniqueActivesObservation generated for a given day, event |
| // code, and window size encodes the occurrence or non-occurrence of at least |
| // one Event with that event code during the window of that size ending on that |
| // day. |
| message UniqueActivesObservation { |
| // A BasicRapporObservation encoding a single bit representing the occurrence |
| // or non-occurrence of |event_code| during the window associated with this |
| // Observation. |
| BasicRapporObservation basic_rappor_obs = 1; |
| // The size in days of the rolling window associated with this Observation. |
| uint32 window_size = 2; |
| // The event codes for each of the metric_dimensions of this observation. |
| // Multiple event codes are packed together into the bits of this value. |
| uint64 event_code = 3; |
| }; |
| |
| // Observations of type PerDeviceNumericObservation are used when a |
| // MetricDefinition of type EVENT_COUNT, ELAPSED_TIME, MEMORY_USAGE, or |
| // FRAME_RATE is reported with a ReportDefinition of type |
| // PER_DEVICE_NUMERIC_STATS. An Observation of this type is created by |
| // aggregating Events on-device over a rolling window of 1, 7, or 30 days. |
| // |
| // A PerDeviceNumericObservation is generated each day, for each aggregation |
| // window size of the ReportDefinition, for each pair (component, event code) |
| // for which an event was logged during the window. In addition, each day and |
| // for each window size, each device generates one |
| // ReportParticipationObservation for that report. The number |
| // of those Observations is used by the ReportGenerator to compute the number of |
| // devices on which each pair (component, event code) was *not* logged during |
| // the window. |
| message PerDeviceNumericObservation { |
| // An IntegerEventObservation containing the event code, component, |
| // and occurrence count associated with this Observation. |
| IntegerEventObservation integer_event_obs = 1; |
| // The size in days of the rolling window associated with this Observation. |
| uint32 window_size = 2; |
| }; |
| |
| // A value for a single dimension of a Cobalt custom metric. Both CustomEvent |
| // (the object logged to the Cobalt client on the device) and CustomObservation |
| // (transmitted from the Cobalt client device to the server) contain a |
| // CustomDimension values. |
| message CustomDimensionValue { |
| oneof data { |
| // A human-readable, UTF8 string. Maps to a proto string. |
| string string_value = 1; |
| |
| // An integer. Maps to a proto int64. |
| int64 int_value = 2; |
| |
| // An uninterpreted sequence of bytes. Maps to proto bytes. |
| bytes blob_value = 3; |
| |
| // The index of an enumerated value, specified in the metric configuration. |
| // Usually used for the index of an enum value defined in the associated |
| // .proto file. |
| uint32 index_value = 4; |
| |
| // A double-precision floating point value. Maps to a proto double. |
| double double_value = 5; |
| } |
| } |
| |
| // Observations of this type contain a custom number of parts each with a |
| // custom name and a custom type. |
| // |
| // This type of Observation is used in the following case: |
| // |
| // A MetricDefinition of type CUSTOM and Report of type |
| // CUSTOM_RAW_DUMP. In this case the Observation is *immediate* meaning it is |
| // generated directly from a single CUSTOM Event as soon as the Event is |
| // logged. The Event contains a list of (name, value) pairs where the names |
| // are the names of the CUSTOM parts and the values are of the appropriate |
| // type defined in the CUSTOM. A CustomObservation directly stores those |
| // pairs. |
| message CustomObservation { |
| // The keys are the names of the metric dimensions to which each |
| // CustomDimensionValue is associated. |
| map<string, CustomDimensionValue> values = 1; |
| } |
| |
| // Observations of this type are used to signal that a given device was |
| // collecting data for a given report, over some window of time. This |
| // Observation type has no required fields, although the size of an |
| // aggregation window may be provided. Observations are generated and |
| // rate-limited by the EventAggregator. |
| // |
| // Current usage: |
| // ReportParticipationObservations are produced by the EventAggregator and |
| // consumed by the ReportGenerator for reports of type PER_DEVICE_COUNT_STATS. |
| // For each report of that type, each device sends one Observation of this type |
| // per day, along with a PerDeviceCountObservation for tuple (component, event |
| // code, window size) for which at least one event with that code occurred |
| // during the window of that size, with that component. The ReportGenerator |
| // uses the number of each of the two kinds of Observations to compute the |
| // number of devices in the fleet on which a given pair (component, event |
| // code) did *not* occur during the aggregation window. |
| message ReportParticipationObservation {} |