Skip to main content

Telemetry

Struct Telemetry 

Source
pub struct Telemetry { /* private fields */ }
Expand description

Aggregate usage telemetry with a consent model built in (issue #413).

Compose it for the vocabularies a venture wants counted; everything else — routes, grammar, storage, retention — is fixed by the module.

Implementations§

Source§

impl Telemetry

Source

pub fn new() -> Self

Empty vocabularies (fail closed: every batch naming an event or a module is rejected until the venture declares them), the 64-event batch ceiling, 180-day retention, and the fz telemetry commands.

Source

pub fn events(self, events: impl IntoIterator<Item = impl Into<String>>) -> Self

Declares the whole event vocabulary. Exactly these names may be counted; anything else is a rejection, never a new series (issue #413). Replaces any previous list.

Source

pub fn modules( self, modules: impl IntoIterator<Item = impl Into<String>>, ) -> Self

Declares the whole composed-module vocabulary a client may report. Replaces any previous list.

Source

pub fn retention_days(self, days: u32) -> Self

How long buckets live before the scheduled purge deletes them (default 180). Clamped to 1..=[MAX_RETENTION_DAYS]: a builder cannot return an error, and zero would delete every bucket the day it is written while a value past the ceiling would walk the purge’s date arithmetic off the calendar — so an impossible value is narrowed to the nearest workable one rather than honoured (issue #413).

Source

pub fn max_events_per_batch(self, max: u32) -> Self

The largest batch the collector parses (default 64). Clamped to 1..=[payload::MAX_EVENTS_PER_BATCH]: “at most this many” is part of the closed grammar, so a venture may tighten it and never widen it, and zero — which the clamp also removes — would leave a collector that rejects every batch with a message about exceeding a ceiling of nothing (issue #413).

Source

pub fn opt_out_command(self, command: impl Into<String>) -> Self

The command a client prints as the one-line way to switch reporting off (default fz telemetry off).

Source

pub fn status_command(self, command: impl Into<String>) -> Self

The command a client prints as the way to see exactly what would be sent (default fz telemetry status).

Trait Implementations§

Source§

impl Default for Telemetry

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Module for Telemetry

Source§

fn requires(&self) -> &'static [Port]

The database is where the aggregates live; there is no mode of this module without it.

Source§

fn optional(&self) -> &'static [Port]

The Clock port decides “now” — the day buckets and the retention cutoff — and is what makes time deterministic under test. The RateLimiter port is the abuse control the public ingest route actually has.

Source§

fn personal_data(&self) -> &'static [PersonalDataSet]

Two aggregate tables, both keyed on the install id, both erased on request (issue #413).

The tension, and the decided answer. The payload carries no identifier the venture can tie to a person, so the harness cannot look a subject up from anything else it stores — and a reader might conclude these tables hold nobody. They do not hold a person, but they do hold a key: the install id is pseudonymous, with no stored link to a person, and the person’s own client prints it in telemetry status. So an erasure request that supplies the id deletes exactly their rows — the same person can act on their own data without the venture ever learning who they are. That makes the subject the install id and the disposition plain Erase; declaring none here would be the lie that breaks the first erasure request that names a real id.

The honest consequence, written down rather than buried. The id rotates every consent::ROTATION_DAYS days and nothing anywhere stores the link between one id and the next — that is the point of rotating it — so rows under an id that has already rotated away are not reachable from a later one. Rotation bounds what an erasure can reach, and that is the price of not keeping a link between rotations; the retention purge bounds how long the unreachable tail outlives the request.

Source§

fn emits(&self) -> &'static [&'static str]

The event a composed venture can subscribe to: an accepted batch.

Source§

fn public_writes(&self) -> bool

The ingest route is public by design and still not an open write path: it accepts one thing only — a batch whose every value already passed a closed grammar, capped by the batch ceiling and the RateLimiter port — and it is how a CLI reports, with no browser and no session (issue #413, after module-linkedin’s reasoning). It stays a false here because public_writes feeds the captcha gate in route_policy.rs, and a captcha on a machine-posted batch is not satisfiable: the honest controls are the ones the route actually has, and they are all mechanical.

Source§

fn scheduled<'a>( &'a self, ctx: &'a ModuleContext, cron: &'a str, ) -> BoxFuture<'a, Result<(), AnyError>>

The retention purge: buckets in either table whose day is older than the window are deleted, mirroring the waitlist’s scheduled purge. Idempotent, so running it more often than the cron fires is harmless.

Source§

fn name(&self) -> &'static str

Kebab-case name; mounted at /v1/<name>.
Source§

fn version(&self) -> &'static str

env!("CARGO_PKG_VERSION"), surfaced by /__health.
Source§

fn tables(&self) -> &'static [&'static str]

Table names this module owns; duplicates across modules are a build error.
Source§

fn migrations(&self) -> Migrations

The module’s migrations, embedded per dialect.
Source§

fn validate_config(&self, cfg: &dyn Config) -> Result<(), ConfigError>

Rejects invalid configuration: missing required keys or malformed values, reported together with the module name. Read more
Source§

fn router(&self, ctx: ModuleContext) -> Router

The module’s router, nested under /v1/<name>.
Source§

fn harness_api(&self) -> u32

Contract version, checked by Harness::build.
Source§

fn depends_on(&self) -> &'static [&'static str]

Modules this one’s schema sits on top of, by name. Read more
Source§

fn public_write_policy(&self) -> RoutePolicy

What actually protects those public writes, for a module with no ADR 0010 surface to hang a per-action RoutePolicy on (issue #143). Read more
Source§

fn signature_verification(&self) -> SignatureVerification

Which verifier proves this module’s RoutePolicy::Signature deliveries (issue #533): how a webhook handler checks a machine signature before acting. Read more
Source§

fn max_body_bytes(&self, _cfg: &dyn Config) -> usize

The largest request body any route of this module accepts, so a runtime can refuse an oversize body before buffering it (issue #440). Read more
Source§

fn streaming_routes(&self) -> &'static [StreamRoute]

Routes this module serves in streaming mode (issue #585), each with its own StreamRoute::max_bytes ceiling. Opt-in: the default is empty, and every existing route keeps the buffered behaviour it always had. Read more
Source§

fn self_check(&self) -> Vec<String>

Problems the module can find in itself, with no configuration and no environment: its own embedded data, checked against its own declarations. Read more
Source§

fn well_known(&self) -> Option<Router>

Routes this module serves at the root under /.well-known, for spec-mandated discovery documents (OIDC openid-configuration, jwks.json) that must live outside /v1 (issue #46). Paths are relative to the prefix: register /jwks.json, not /.well-known/jwks.json. Read more
Source§

fn surface(&self) -> Surface

The module’s UI surface (ADR 0010): the actions a renderer may offer and the views that compose them. Input schemas come from the handler’s own body types (Action::input::<Body>()), so the declaration cannot drift from the route. Harness::build validates it; GET /__surface serves the composition. Default: nothing, and a module that declares nothing renders nothing.
Source§

fn events( &self, ) -> Vec<(String, Arc<dyn Fn(&Scope, Value) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn Error + Sync + Send>>> + Send>> + Sync + Send>)>

Handlers for events other modules emit; registered at Harness::build.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more