#[non_exhaustive]pub struct TelemetryConfig { /* private fields */ }Expand description
Runtime configuration for the telemetry subsystem.
Constructed via TelemetryConfig::default (which locks in the
privacy-preserving defaults) and refined with the with_* builder
methods. enable_telemetry additionally needs an api_key and an
app_id, both issued by the developer portal; see
TelemetryConfig::validate for what it refuses. Fields are crate-private; read them through the accessor
methods and mutate them through the builder methods — this keeps a
single idiom for configuration and prevents mid-run mutation of
identity-correlation parameters like the scrub secret (which would
invalidate every previously emitted opaque identifier).
The struct is #[non_exhaustive] to preserve room for future knobs.
Implementations§
Source§impl TelemetryConfig
impl TelemetryConfig
Sourcepub fn with_scrub_ids(self, scrub_ids: bool) -> Self
pub fn with_scrub_ids(self, scrub_ids: bool) -> Self
Sets the identifier-scrubbing flag.
When true (the default), the engine hashes the peer and group ids it
stamps on MLS lifecycle records with the scrub secret (see
Self::with_scrub_secret). The telemetry pipe reads the peer id only
to pair a handshake’s start with its end, and no identifier has a wire
field, so the flag changes what the pipe holds in memory and never what
is uploaded. It does not apply to on_event, which delivers every
event with its identifiers as they are.
Sourcepub fn with_mls_verbosity(self, mls_verbosity: MlsVerbosity) -> Self
pub fn with_mls_verbosity(self, mls_verbosity: MlsVerbosity) -> Self
Sets the MLS lifecycle verbosity tier.
Sourcepub fn with_metrics_cadence(self, cadence: Option<Duration>) -> Self
pub fn with_metrics_cadence(self, cadence: Option<Duration>) -> Self
Sets the cadence for periodic MetricsSnapshot emission. None
disables periodic emission entirely (apps fall back to pull-based
access via TransportManager::metrics()).
Sourcepub fn with_scrub_secret(self, secret: Option<[u8; 16]>) -> Self
pub fn with_scrub_secret(self, secret: Option<[u8; 16]>) -> Self
Sets the opaque-identifier hashing secret.
Supplying Some(secret) pins an explicit, caller-owned secret and
always takes precedence over the SDK-managed fallback below.
Supplying None (the default) leaves the secret unset in the config.
In that case the SDK manages the fallback for you: the first time
secure storage is provided via OfflineProtocol::initialize_mls, the
SDK loads — or, on first run, generates and persists — a stable
per-install secret. This makes
opaque identifiers survive process restarts, so backend telemetry can
count distinct devices across sessions. Until storage is available (or
if storage is never provided), the SDK uses a random per-instance
secret derived at protocol construction.
Precedence: explicit config secret > SDK-managed persistent secret > random per-instance secret.
Do not share the secret across tenants, and do not rotate it
mid-run — rotation invalidates every previously emitted opaque
identifier and breaks correlation on the receiving side. For the
SDK-managed fallback this means: do not back two tenants with the same
storage, and do not clear the scrub_secret storage entry within a
measurement window.
Sourcepub fn mls_verbosity(&self) -> MlsVerbosity
pub fn mls_verbosity(&self) -> MlsVerbosity
Returns the configured MLS lifecycle verbosity tier.
Sourcepub fn metrics_cadence(&self) -> Option<Duration>
pub fn metrics_cadence(&self) -> Option<Duration>
Returns the configured periodic metrics-snapshot cadence.
Sourcepub fn with_routing_diagnostic(self, routing_diagnostic: bool) -> Self
pub fn with_routing_diagnostic(self, routing_diagnostic: bool) -> Self
Sets whether RoutingDecision records should carry the full
per-transport score breakdown.
When true, every emitted
crate::telemetry::RoutingDecision::scores is populated with the
seven-factor offline_protocol_router::TransportScore for each
ranked transport. When false (the default), scores is empty —
the hot path avoids the per-emission vector allocation and
Diagnostic-tier consumers simply see an empty vector.
Leaf identifiers are not affected: this knob only gates the scoring-factor detail, not identity fields.
Sourcepub fn routing_diagnostic(&self) -> bool
pub fn routing_diagnostic(&self) -> bool
Returns whether routing records should carry diagnostic score detail.
Sourcepub fn with_mls_sampling_bypass(self, mls_sampling_bypass: bool) -> Self
pub fn with_mls_sampling_bypass(self, mls_sampling_bypass: bool) -> Self
Opts MLS lifecycle telemetry out of rate limiting.
By default (false), high-volume MLS lifecycle events
(mls.decryption_failed, mls.session_missing) pass through a
best-effort fixed-window limiter that caps emission per peer+kind. The
cap bounds what an event flood costs, but it also clips genuine
failure spikes to the per-window ceiling — an aggregating backend
cannot tell a real burst of N failures apart from the cap.
Setting this to true disables that limiter, so every MLS lifecycle
event reaches the telemetry pipe un-sampled and aggregate counts
reflect reality, at the cost of everything an un-capped failure spike
puts through it. Leave it off unless exact failure counts are needed.
This knob only affects MLS-event rate limiting; it does not change identifier scrubbing, verbosity, or any other field.
Sourcepub fn mls_sampling_bypass(&self) -> bool
pub fn mls_sampling_bypass(&self) -> bool
Returns whether MLS lifecycle event rate limiting is bypassed.
Sourcepub fn with_api_key(self, api_key: impl Into<String>) -> Self
pub fn with_api_key(self, api_key: impl Into<String>) -> Self
Sets the API key the developer portal issued. Sent as a bearer token
on every upload; redacted from Debug output.
Sourcepub fn with_app_id(self, app_id: impl Into<String>) -> Self
pub fn with_app_id(self, app_id: impl Into<String>) -> Self
Sets the app id the key was issued against. The ingest cross-checks the two and refuses a mismatch, which stops a key pasted into the wrong app from misattributing its data.
Sourcepub fn with_app_version(self, app_version: impl Into<String>) -> Self
pub fn with_app_version(self, app_version: impl Into<String>) -> Self
Sets the application’s own version string, stamped on every batch.
Sourcepub fn with_debug(self, debug: bool) -> Self
pub fn with_debug(self, debug: bool) -> Self
Logs every wire event at debug under the pipe’s tracing target,
so an adopter can see exactly what leaves the device.
Sourcepub fn with_flush_interval(self, flush_interval: Duration) -> Self
pub fn with_flush_interval(self, flush_interval: Duration) -> Self
Sets the background flush cadence. Not below MIN_FLUSH_INTERVAL.
Sourcepub fn with_max_batch_bytes(self, max_batch_bytes: usize) -> Self
pub fn with_max_batch_bytes(self, max_batch_bytes: usize) -> Self
Sets the size trigger for an early flush and the largest batch cut.
Sourcepub fn with_max_buffered_records(self, max_buffered_records: usize) -> Self
pub fn with_max_buffered_records(self, max_buffered_records: usize) -> Self
Sets the ring-buffer capacity.
Sourcepub fn with_include_device_id(self, include_device_id: bool) -> Self
pub fn with_include_device_id(self, include_device_id: bool) -> Self
Stamps the stable per-install id on every batch, so the ingest counts distinct devices rather than distinct sessions.
Off by default because it is a disclosure decision: a stable
per-install identifier is a “device or other ID” under Google Play’s
definition and a NSPrivacyCollectedDataTypeDeviceID under Apple’s.
See docs/privacy.md.
Sourcepub fn app_version(&self) -> &str
pub fn app_version(&self) -> &str
Returns the application version stamped on batches.
Sourcepub fn flush_interval(&self) -> Duration
pub fn flush_interval(&self) -> Duration
Returns the background flush cadence.
Sourcepub fn max_batch_bytes(&self) -> usize
pub fn max_batch_bytes(&self) -> usize
Returns the size trigger and batch ceiling.
Sourcepub fn max_buffered_records(&self) -> usize
pub fn max_buffered_records(&self) -> usize
Returns the ring-buffer capacity.
Sourcepub fn include_device_id(&self) -> bool
pub fn include_device_id(&self) -> bool
Returns whether the per-install id is stamped on batches.
Sourcepub fn validate(&self) -> Result<(), &'static str>
pub fn validate(&self) -> Result<(), &'static str>
Checks the fields enable_telemetry depends on, naming the first one
that fails.
Refused: a missing or empty api_key or app_id, or one that is not
printable ASCII (a header value the ingest could never read, which
would otherwise be retried forever as a network error); an empty
app_version; a max_batch_bytes of zero or above
MAX_BATCH_BYTES_LIMIT; a max_buffered_records of zero; a
flush_interval below MIN_FLUSH_INTERVAL, which is reported under
the name every binding gives it, flush_interval_ms.
Trait Implementations§
Source§impl Clone for TelemetryConfig
impl Clone for TelemetryConfig
Source§fn clone(&self) -> TelemetryConfig
fn clone(&self) -> TelemetryConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for TelemetryConfig
impl Debug for TelemetryConfig
Auto Trait Implementations§
impl Freeze for TelemetryConfig
impl RefUnwindSafe for TelemetryConfig
impl Send for TelemetryConfig
impl Sync for TelemetryConfig
impl Unpin for TelemetryConfig
impl UnsafeUnpin for TelemetryConfig
impl UnwindSafe for TelemetryConfig
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Declassify for T
impl<T> Declassify for T
type Declassified = T
fn declassify(self) -> T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);