blob: 479b546e6dc408bb31db921a442cb216e3429051 [file] [log] [blame]
// 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;
PerDeviceCountObservation per_device_count = 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.
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 PerDeviceCountObservation are used when a
// MetricDefinition of type EVENT_COUNT is reported with a ReportDefinition
// of type PER_DEVICE_COUNT_STATS. An Observation of this type is created by
// aggregating CountEvents on-device over a rolling window of 1, 7, or 30 days.
//
// A PerDeviceCountObservation is generated each day, for each aggregation
// window size of the ReportDefinition, for each pair (component, event code)
// for which an event occurrence was logged during the window. In addition, each
// day and for each window size, each device generates one
// ReportDeviceCountObservation containing that window size. 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 PerDeviceCountObservation {
// 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 {}