blob: b05247c8ac5540ad1d07cebdf602181a8d760fab [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.
library fuchsia.cobalt;
/// The maximum size of a single Event is 100 KB.
const MAX_BYTES_PER_EVENT int64 = 102400;
/// This is intended as a reasonable maximum number of histogram buckets per event.
const MAX_HISTOGRAM_BUCKETS uint32 = 500;
/// Maximum number of Cobalt events that may be logged in a single
/// FIDL call.
const MAX_BATCHED_EVENTS uint32 = 500;
/// Component strings should not be longer than this.
const MAX_COMPONENT_LENGTH uint32 = 64;
/// Timer ids should not be longer than this.
const MAX_TIMER_ID_LENGTH uint32 = 64;
/// We only support up to 5 event_codes
const MAX_EVENT_CODE_COUNT uint32 = 5;
/// Channels should not be longer than this.
const MAX_CHANNEL_NAME_LENGTH uint32 = 256;
/// Realm names should not be longer than this.
const MAX_REALM_NAME_LENGTH uint32 = 256;
/// Response codes for Logger operations.
type Status = strict enum : int32 {
OK = 0;
/// For example the supplied metric id is invalid.
INVALID_ARGUMENTS = 1;
/// An attempt was made to log an Event whose serialized size exceeds
/// MAX_BYTES_PER_EVENT.
EVENT_TOO_BIG = 2;
/// Cobalt's local buffer is temporarily full and cannot handle any more
/// Events at this time. Try again later. This condition should be rare
BUFFER_FULL = 3;
// Cobalt has received a ShutDown signal and will not accept any more
// events.
SHUT_DOWN = 4;
/// Catch-all for unexpected errors.
INTERNAL_ERROR = -1;
};
/// LoggerFactory creates Loggers.
@discoverable
@for_deprecated_c_bindings
protocol LoggerFactory {
/// Creates a Logger for the project with the given ID, using the state of
/// the metrics registry that is bundled with Cobalt. The project must be in
/// the "fuchsia" customer.
///
/// `project_id` The ID of the client's Cobalt project.
///
/// `status` Returns OK on success, SHUT_DOWN if the factory is no longer
/// creating new loggers, or INVALID_ARGUMENTS if there is no project with
/// the given ID in the version of the metrics registry that is bundled
/// with Cobalt.
CreateLoggerFromProjectId(resource struct {
project_id uint32;
logger server_end:Logger;
}) -> (struct {
status Status;
});
/// Creates a LoggerSimple for the project with the given ID, using the
/// state of the metrics registry that is bundled with Cobalt. The project
/// must be in the "fuchsia" customer.
///
/// `project_id` The ID of the client's Cobalt project.
///
/// `status` Returns OK on success or INVALID_ARGUMENTS if there is no
/// project with the given ID in the version of the metrics registry that
/// is bundled with Cobalt.
CreateLoggerSimpleFromProjectId(resource struct {
project_id uint32;
logger server_end:LoggerSimple;
}) -> (struct {
status Status;
});
/// Creates a Logger for the project specified, using the state of the
/// metrics registry that is bundled with Cobalt.
///
/// `customer_id` The ID of the client's Cobalt customer.
///
/// `project_id` The ID of the client's Cobalt project.
///
/// `status` Returns OK on success or INVALID_ARGUMENTS if there is no
/// project with the given IDs in the version of the metrics registry that
/// is bundled with Cobalt.
CreateLoggerFromProjectSpec(resource struct {
customer_id uint32;
project_id uint32;
logger server_end:Logger;
}) -> (struct {
status Status;
});
};
/////////////////////////////////////////////////////////////////////
// LoggerBase Interface
/////////////////////////////////////////////////////////////////////
/// LoggerBase and its extensions are used to log Events to the Cobalt system.
/// The Cobalt FIDL service stores the Events locally for some period of time,
/// processes the Events to form Observations, and periodically uploads batches
/// of Observations to the Cobalt server. The Cobalt server processes the
/// Observations and generates Reports. See [TODO(rudominer)] for more
/// description of the Cobalt server and Reports.
///
/// LoggerBase or one of its extensions is associated with a single Cobalt
/// project.
///
/// This interface conforms to the Simple layout so that Simple bindings
/// may be generated for it. For the full interfaces, see Logger and LoggerSimple
/// below.
@for_deprecated_c_bindings
protocol LoggerBase {
/// Logs the fact that an event has occurred.
///
/// `metric_id` ID of the metric to use. It must be one of the Metrics
/// from the ProjectProfile used to obtain this Logger, and it must be of
/// type EVENT_OCCURRED.
///
/// `event_code` The index of the event that occurred. The indexed set of all
/// event codes and their labels is specified in the metric definition.
LogEvent(struct {
metric_id uint32;
event_code uint32;
}) -> (struct {
status Status;
});
/// Logs that an event has occurred a given number of times.
///
/// `metric_id` ID of the metric to use. It must be one of the Metrics
/// from the ProjectProfile used to obtain this Logger, and it must be of
/// type EVENT_COUNT.
///
/// `event_code` The index of the event that occurred. The indexed set of all
/// event codes and their labels is specified in the metric definition.
///
/// `component` Optionally, a component associated with the event may also be
/// logged. Any notion of component that makes sense may be used or use the
/// empty string if there is no natural notion of component.
///
/// `period_duration_micros` Optionally, the period of time over which the
/// `count` events occurred may be logged. If this is not relevant the value
/// may be set to 0. Otherwise specify the period duration as a number of
/// microseconds.
///
/// `count` The number of times the event occurred. One may choose to always
/// set this value to 1 and always set
///
/// `period_duration_micros` to 0 in order to achieve a semantics similar to
/// the LogEventOccurred() method, but with a `component`.
LogEventCount(struct {
metric_id uint32;
event_code uint32;
component string:MAX_COMPONENT_LENGTH;
period_duration_micros int64;
count int64;
}) -> (struct {
status Status;
});
/// Logs that an event lasted a given amount of time.
///
/// `metric_id` ID of the metric to use. It must be one of the Metrics
/// from the ProjectProfile used to obtain this Logger, and it must be of
/// type ELAPSED_TIME.
///
/// `event_code` The index of the event that occurred. The indexed set of all
/// event codes and their labels is specified in the metric definition.
///
/// `component` Optionally, a component associated with the event may also be
/// logged. Any notion of component that makes sense may be used or use the
/// empty string if there is no natural notion of component.
///
/// `elapsed_micros` The elapsed time of the event, specified as a number of
/// microseconds.
LogElapsedTime(struct {
metric_id uint32;
event_code uint32;
component string:MAX_COMPONENT_LENGTH;
elapsed_micros int64;
}) -> (struct {
status Status;
});
/// Logs a measured average frame rate.
///
/// `metric_id` ID of the metric to use. It must be one of the Metrics
/// from the ProjectProfile used to obtain this Logger, and it must be of
/// type FRAME_RATE.
///
/// `event_code` The index of the event that associated with the frame-rate
/// measurement. The indexed set of all event codes and their labels is
/// specified in the metric definition.
///
/// `component` Optionally, a component associated with the frame-rate
/// measurement may also be logged. Any notion of component that makes sense
/// may be used or use the empty string if there is no natural notion of
/// component.
///
/// `fps` The average-frame rate in frames-per-second.
LogFrameRate(struct {
metric_id uint32;
event_code uint32;
component string:MAX_COMPONENT_LENGTH;
fps float32;
}) -> (struct {
status Status;
});
/// Logs a measured memory usage.
///
/// `metric_id` ID of the metric to use. It must be one of the Metrics
/// from the ProjectProfile used to obtain this Logger, and it must be of
/// type MEMORY_USAGE.
///
/// `event_code` The index of the event type associated with the memory
/// usage. The indexed set of all event codes and their labels is specified
/// in the metric definition.
///
/// `component` Optionally, a component associated with the memory usage may
/// also be logged. Any notion of component that makes sense may be used or
/// use the empty string if there is no natural notion of component.
///
/// `bytes` The memory used, in bytes.
LogMemoryUsage(struct {
metric_id uint32;
event_code uint32;
component string:MAX_COMPONENT_LENGTH;
bytes int64;
}) -> (struct {
status Status;
});
/// This method is part of Cobalt's helper service for measuring the time
/// delta between two events that occur in different processes. This starts
/// the timer. A corresponding invocation of EndTimer() with the same
/// `timer_id` ends the timer. After both StartTimer() and EnvdTimer() have
/// been invoked, LogElapsedTime() will be invoked with the difference
/// between the end timestamp and the start timestamp as the value of
/// `duration_microseconds`. It is OK if Cobalt receives the EndTimer()
/// call before the StartTimer() call.
///
/// `metric_id` ID of the metric to use. It must be one of the Metrics
/// from the ProjectProfile used to obtain this Logger, and it must be of
/// type ELAPSED_TIME.
///
/// `event_code` The index of the event type to associate with the elapsed
/// time. This is passed to LogElapsedTime()
///
/// `component` Optionally, a component associated with the event may also be
/// logged. See the description at LogElapsedTime().
///
/// `timer_id` The ID of the timer being started. This is an arbitrary
/// non-empty string provided by the caller and it is the caller's
/// responsibility to ensure that Cobalt receives a pair of StartTimer(),
/// EndTimer() calls with this id before the timeout and without any
/// intervening additional calls to StartTimer() or EndTimer() using the same
/// id. Once such a pair is received Cobalt will delete the timer with this
/// ID and after that the ID may be re-used.
///
/// `timestamp` The timestamp to set as the start of the timer. The units
/// must be microseconds. The absolute value does not matter, only the
/// difference between the end and start timestamps will be used.
///
/// `timeout_s` The number of seconds Cobalt should wait to receive the
/// corresponding EndTimer() call with the same `timer_id`. If Cobalt has
/// already received the corresponding EndTimer() call before receiving this
/// StartTimer() call then this value is ignored as the timeout has already
/// been set by the EndTimer() call. If Cobalt does not receive the
/// corresponding EndTimer() call before the timeout then the timer will be
/// deleted and this invocation of StartTimer() will be forgotten. Must be a
/// positive value less than 300.
///
/// `status` Returns OK on success. There are two success cases:
/// (i) Cobalt does not currently have any timers with the given
/// timer_id. In that case this call creates a new timer with
/// the given ID and start timestamp.
/// (ii) Cobalt currently has a timer with the given timer_id for
/// which it has received exactly one EndTimer() call and no
/// StartTimer() calls. In this case Cobalt will delete the
/// timer and invoke LogElapsedTime() using the difference
/// between the end timestamp and the start timestamp as the
/// value of `duration_micros`. It is ok if this value is
/// negative.
/// Returns INVALID_ARGUMENTS if `timer_id` is empty, the timeout
/// is not positive and less than 5 minutes or Cobalt currently
/// has a timer with the given timer_ID and it already has a start
/// timestamp. In the last case Cobalt will delete the timer with
/// the given `timer_id` and this invocation of StartTimer()
/// will be forgotten.
/// Any error returned by LogElapsedTime() may also be returned by this
/// method.
StartTimer(struct {
metric_id uint32;
event_code uint32;
component string:MAX_COMPONENT_LENGTH;
timer_id string:MAX_TIMER_ID_LENGTH;
timestamp uint64;
timeout_s uint32;
}) -> (struct {
status Status;
});
/// This method is part of Cobalt's helper service for measuring the time
/// delta between two events that occur in different processes. This ends
/// the timer. A corresponding invocation of StartTimer() with the same
/// `timer_id` starts the timer. After both StartTimer() and EndTimer() have
/// been invoked, LogElapsedTime() will be invoked with the difference
/// between the end timestamp and the start timestamp as the value of
/// `duration_microseconds`. It is OK if Cobalt receives the EndTimer()
/// call before the StartTimer() call.
///
/// `timer_id` The ID of the timer being ended. This is an arbitrary
/// non-empty string provided by the caller and it is the caller's
/// responsibility to ensure that Cobalt receives a pair of StartTimer(),
/// EndTimer() calls with this id before the timeout and without any
/// intervening additional calls to StartTimer() or EndTimer() using the same
/// id. Once such a pair is received Cobalt will delete the timer with this
/// ID and after that the ID may be re-used.
///
/// `timestamp` The timestamp to set as the end of the timer. The units must
/// be microseconds. The absolute value does not matter, only the difference
/// between the end and start timestamps will be used.
///
/// `timeout_s` The number of seconds Cobalt should wait to receive the
/// corresponding EndTimer() call with the same `timer_id`. If Cobalt has
/// already received the corresponding EndTimer() call before receiving this
/// StartTimer() call then this value is ignored as the timeout has already
/// been set by the EndTimer() call. If Cobalt does not receive the
/// corresponding EndTimer() call before the timeout then the timer will be
/// deleted and this invocation of StartTimer() will be forgotten. Must be a
/// positive value less than 300.
///
/// `status` Returns OK on success. There are two success cases:
/// (i) Cobalt does not currently have any timers with the given
/// timer_id. In that case this call creates a new timer with
/// the given ID and end timestamp.
/// (ii) Cobalt currently has a timer with the given timer_id for
/// which it has received exactly one StartTimer() call and no
/// EndTimer() calls. In this case Cobalt will delete the
/// timer and invoke LogElapsedTime() using the difference
/// between the end timestamp and the start timestamp as the
/// value of `duration_micros`. It is ok if this value is
/// negative.
/// Returns INVALID_ARGUMENTS if `timer_id` is empty, the timeout
/// is not positive and less than 5 minutes or Cobalt currently
/// has a timer with the given timer_ID and it already has an end
/// timestamp. In the last case Cobalt will delete the timer with
/// the given `timer_id` and this invocation of EndTimer()
/// will be forgotten.
/// Any error returned by LogElapsedTime() may also be returned by this
/// method.
EndTimer(struct {
timer_id string:MAX_TIMER_ID_LENGTH;
timestamp uint64;
timeout_s uint32;
}) -> (struct {
status Status;
});
// Method ordinals >= 100 are reserved for sub-interfaces.
};
/////////////////////////////////////////////////////////////////////
// Logger Interface
/////////////////////////////////////////////////////////////////////
/// A value for a custom Event. This is used by the method LogCustomEvent().
type CustomEventValue = struct {
/// The name of the Metric dimension this value is for.
dimension_name string:MAX;
/// The value for that dimension.
value Value;
};
/// A value that may be a string, int, double, or index.
type Value = strict union {
1: string_value string:MAX;
2: int_value int64;
3: double_value float64;
4: index_value uint32;
};
/// One bucket of histogram. This is used by the methods LogIntHistogram() from
/// Cobalt 1.0 and LogIntegerHistogram from Cobalt 1.1.
type HistogramBucket = struct {
/// The index of the bucket. The MetricDefinition includes a specification
/// of a sequence of N+1 integer-range buckets that are indexed from
/// 0, the underflow bucket, to N, the overflow bucket.
index uint32;
/// The number of values in that bucket.
count uint64;
};
/// Used to log that an event has occurred a given number of times. Using this
/// struct with LogCobaltEvent() is equivalent to invoking LogEventCount().
type CountEvent = struct {
/// The number of microseconds over which this count was observed.
period_duration_micros int64;
/// The number of times the event occurred
count int64;
};
/// Used to log an event that has no extra fields. Using this struct with
/// LogCobaltEvent() is equivalent to invoking LogEvent().
type Event = struct {};
/// The variadic part of a CobaltEvent.
type EventPayload = strict union {
/// This maps to a call to LogEvent().
1: event Event;
/// This maps to a call to LogEventCount().
2: event_count CountEvent;
/// This maps to a call to LogElapsedTime().
3: elapsed_micros int64;
/// This maps to a call to LogFrameRate().
4: fps float32;
/// This maps to a call to LogMemoryUsage().
5: memory_bytes_used int64;
// Previously mapped to a call to LogString() (deprecated).
6: reserved;
/// This maps to a call to LogIntHistogram().
7: int_histogram vector<HistogramBucket>:MAX_HISTOGRAM_BUCKETS;
};
/// A specification of an event that occurred to be passed to LogCobaltEvent().
/// This is part of an alternative API to cobalt that uses a single method with a
/// variadic parameter instead of the multiple methods above. This technique
/// allows multiple event codes to be passed whereas the methods above support
/// only a single event code.
type CobaltEvent = struct {
/// ID of the metric to use. It must be one of the Metrics from the
/// ProjectProfile used to obtain this Logger, and its type must match the
/// `payload` type.
metric_id uint32;
/// The event codes for the event that occurred. There must be one event code
/// given for each dimension specified in the metric definition.
event_codes vector<uint32>:MAX_EVENT_CODE_COUNT;
/// Optionally, a component associated with the event that occurred may also
/// be logged also be logged. Any notion of component that makes sense may be
/// used or use the empty string if there is no natural notion of component.
component string:<MAX_COMPONENT_LENGTH, optional>;
/// The event-specific information for the event to be logged.
payload EventPayload;
};
/// Logger is an extension of the LoggerBase interface that adds some additional
/// methods that do not naturally conform to the Simple layout. We opt for
/// a natural easy-to-understand interface at the cost of not being "Simple".
/// See the interface LoggerSimple below for versions of some of these methods
/// that do conform to the Simple layout.
protocol Logger {
compose LoggerBase;
/// Logs a histogram over a set of integer buckets. The meaning of the
/// Metric and the buckets is specified in the Metric definition.
///
/// This method is intended to be used in situations where the client
/// wishes to aggregate a large number of integer-valued measurements
/// *in-process*, prior to submitting the data to Cobalt.
/// One reason a client may wish to do this is that the measurements occur
/// with very high frequency and it is not practical to make a FIDL call
/// for each individual measurement.
///
/// `metric_id` ID of the metric to use. It must be one of the Metrics
/// from the ProjectProfile used to obtain this Logger, and it must be of
/// type INT_HISTOGRAM.
///
/// `event_code` The index of the event type associated with the
/// integer-valued measurement. The indexed set of all event codes and their
/// labels is specified in the metric definition.
///
/// `component` Optionally, a component associated with integer-valued
/// measurements may also be logged. Any notion of component that makes sense
/// may be used or use the empty string if there is no natural notion of
/// component.
///
/// `histogram` The histogram to log. Each HistogramBucket gives the count
/// for one bucket of the histogram. The definitions of the buckets is given
/// in the Metric definition.
LogIntHistogram(struct {
metric_id uint32;
event_code uint32;
component string:MAX_COMPONENT_LENGTH;
histogram vector<HistogramBucket>:MAX_HISTOGRAM_BUCKETS;
}) -> (struct {
status Status;
});
/// Logs a custom Event. The semantics of the Metric are specified in the
/// Metric definition.
///
/// `metric_id` ID of the metric to use. It must be one of the Metrics
/// from the ProjectProfile used to obtain this Logger, and it must be of
/// type CUSTOM.
///
/// `event_values` The values for the custom Event. There is one value for
/// each dimension of the Metric. The number and types of the values must
/// be consistent with the dimensions declared in the Metric definition.
LogCustomEvent(struct {
metric_id uint32;
event_values vector<CustomEventValue>:MAX;
}) -> (struct {
status Status;
});
/// Logs a CobaltEvent. This method offers an alternative API to Cobalt that
/// uses a single method with a variadic parameter instead of the multiple
/// methods defined above. The reason to use this method is that a
/// CobaltEvent allows multiple event codes to be specified whereas the
/// methods above allow only a single event code.
LogCobaltEvent(struct {
event CobaltEvent;
}) -> (struct {
status Status;
});
/// Logs a list of CobaltEvents. This method is equivalent to invoking
/// LogCobaltEvent() multiple times but is more efficient as it requires only
/// a single FIDL call.
LogCobaltEvents(struct {
events vector<CobaltEvent>:MAX_BATCHED_EVENTS;
}) -> (struct {
status Status;
});
};
/////////////////////////////////////////////////////////////////////
// LoggerSimple Interface
/////////////////////////////////////////////////////////////////////
/// LoggerSimple is an extension of the LoggerBase interface that adds some
/// additional methods intended to be used by lower-levels of the Fuchsia system.
///
/// This interface conforms to the Simple layout so that Simple bindings
/// may be generated for it.
@for_deprecated_c_bindings
protocol LoggerSimple {
compose LoggerBase;
/// Logs a histogram over a set of integer buckets. The meaning of the
/// Metric and the buckets is specified in the Metric definition.
///
/// See the method LogIntHistogram() in the Logger interface for more
/// information. This method is similar except that it adheres to the
/// requirements of Simple layout. Instead of a vector of HistogramBucekts
/// this version takes two parallel vectors of bucket indices and the
/// corresponding bucket counts.
LogIntHistogram(struct {
metric_id uint32;
event_code uint32;
component string:MAX_COMPONENT_LENGTH;
bucket_indices vector<uint32>:MAX_HISTOGRAM_BUCKETS;
bucket_counts vector<uint64>:MAX_HISTOGRAM_BUCKETS;
}) -> (struct {
status Status;
});
};
/////////////////////////////////////////////////////////////////////
// SystemProfileUpdater Interface
/////////////////////////////////////////////////////////////////////
/// A collection of fields describing a system's software distribution.
type SoftwareDistributionInfo = table {
/// The channel that the device last used as an update source. This value
/// may be empty to indicate that the device is not currently associated
/// with any channel.
1: current_channel string:MAX_CHANNEL_NAME_LENGTH;
/// The realm of the device represented by the Omaha App ID. This value
/// may be empty to indicate that the device is not currently associated
/// with any realm.
2: current_realm string:MAX_REALM_NAME_LENGTH;
};
/// The SystemDataUpdater interface allows callers to update the state of
/// the SystemProfile in Cobalt. The changes are global and affect all loggers
/// running on the device.
@discoverable
protocol SystemDataUpdater {
/// Sets Cobalt's view of the system-wide distribution information replacing the
/// existing values.
///
/// `info` The specifications of the current system's software distribution.
SetSoftwareDistributionInfo(struct {
info SoftwareDistributionInfo;
}) -> (struct {
status Status;
});
};