Skip to main content

Config

Struct Config 

Source
pub struct Config {
    pub node: String,
    pub grpc: SocketAddr,
    pub http: SocketAddr,
    pub data_dir: PathBuf,
    pub retention: Duration,
    pub max_request_bytes: usize,
    pub queue: usize,
    pub shards: usize,
    pub wal: bool,
    pub self_telemetry: bool,
    pub telemetry_interval: Duration,
    pub alerts: Option<PathBuf>,
}

Fields§

§node: String

This replica’s name. Hashed into the block directory name so that replicas sharing a volume cannot collide (see mira_core::block).

§grpc: SocketAddr

Where OTLP/gRPC listens.

§http: SocketAddr

Where OTLP/HTTP, the query API, the MCP endpoint and the web UI listen — one port, because they are one surface over one set of blocks.

§data_dir: PathBuf

The block directory. It is the whole manifest: no catalogue, no index file, nothing outside it to keep in sync.

§retention: Duration

How long a block is kept. Retention is a delete of whole blocks, so the oldest data disappears in block-sized steps rather than row by row.

§max_request_bytes: usize

The largest export either listener will decode. See receiver::Receivers::max_request_bytes for why it is one number.

§queue: usize

How many exports may be queued for one signal’s flusher before the next one has to wait for a slot — and is shed with a 503 only if none frees up within pipeline::ADMIT_WAIT.

The concurrency limit Mira did not used to have. It was a fixed 128 and a full queue meant an immediate 503, so a wide collector fleet spent most of its time being told to retry: that sweep shed 93% of exports at 96 connections and landed at a third of the two-connection rate. Waiting briefly for a slot instead (ADMIT_WAIT, pipeline.rs) took the same row to nothing shed and double the throughput, and twenty-one consecutive runs of the whole sweep have refused nothing since. This knob is the other half — an operator whose fleet is wide can buy queue depth with memory they have spare.

It buys queueing, not throughput: the flusher drains at the rate it drains, and a queue deep enough to hide a permanently overloaded node just moves the shed into a latency tail. Size it to absorb a burst, not to avoid a 503. Each slot can hold a decoded export, so the worst case is this times Config::max_request_bytes times three signals resident.

§shards: usize

How many flushers a signal runs, or 0 for “one per two cores”.

One shard per core is the sanctioned unit (architecture.md section 4); this is only here so the number can be pinned when the machine lies about its core count. available_parallelism honours cgroup v1 and v2 CPU quotas, so a container with a quota set needs no help here — but cpu.shares/cpu.weight is a relative weight rather than a quota and reads as the whole machine, a shared host often sets no quota at all, a non-Linux container runtime leaves nothing to read, and hyperthreads count as cores. A 96-core host running Mira on two cores’ worth of any of those would otherwise start the capped sixteen flushers per signal and publish sixteen files per seal window. Set it to the cores the process actually gets, or to 1 to get the pre-0.0.3 behaviour.

Shards split queue, they do not multiply it: the resident worst case is the same whatever this is. Capped at pipeline::MAX_SHARDS.

§wal: bool

Acknowledge an export once it is a frame in the write-ahead log, rather than once the block holding it has been published.

The one durability decision Mira does not make for the operator, and it is not the tuning knob the module docs above rule out: both settings are correct, they promise different things, and nothing the engine can measure says which promise a deployment wants. On, the default, is the log’s: the export survives the process dying, panic = "abort", SIGKILL and the OOM killer, but not power loss in the last WAL_SYNC_PERIOD, at a p99 in the microseconds. Off is the block’s — acknowledged means fsynced and renamed, which survives power loss too, at a p99 of 2.6 s because that is how long a lightly-loaded block takes to fill.

Read-your-writes holds either way: the open block is queryable (section 4), so a record is visible from the acknowledgement whether or not it has been published yet.

§self_telemetry: bool

Store this node’s own telemetry in this node, as ordinary metrics.

Mira already knows everything in /api/v1/stats; what it does not do by default is remember it. On, a task samples those counters every Config::telemetry_interval and submits them through the metrics ingest path like any other exporter would — so mira.ingest.rows, mira.query.latency_ms and the rest become series a chart, an alert rule or an agent can read with no exporter, no scrape target and no second system to stand up.

Off by default, because it is not free and the operator should choose to spend it: the samples are rows, they are subject to Config::retention like everything else, and a node storing its own telemetry is a node whose disk usage no longer goes to zero when nothing is being sent to it.

Self-import is the only destination. Shipping these somewhere else is what an OTLP exporter is for, and Mira is not going to grow a second one pointed at itself.

§telemetry_interval: Duration

How often Config::self_telemetry samples this node’s counters.

A sample is one point per series, so this is the resolution of every chart drawn from it and also its cost. The default matches what a collector’s own scrape interval usually is; below a second it is measuring the sampler.

§alerts: Option<PathBuf>

A KYAML file of alerting rules (crate::alert), or none.

Deployment description rather than a knob, and the same argument as the data directory: what to page on is a thing the engine cannot know. It is a path rather than an inline section for two reasons — a rules list is a list of maps, which this file’s closed-scalar shape refuses on purpose, and rules change on a different cadence to addresses, so they belong in a different file and a different review.

Absent means alerting is off, which is also the coordination mechanism: N replicas over one block directory would each page, so exactly one replica gets this key. See crate::alert.

Implementations§

Source§

impl Config

Source

pub fn load(path: &Path) -> Result<Self, String>

Source

pub fn parse(text: &str) -> Result<Self, String>

Source

fn parse_with( text: &str, env: &'_ dyn Fn(&str) -> Option<String>, ) -> Result<Self, String>

Config::parse against a supplied environment. See Env.

Trait Implementations§

Source§

impl Clone for Config

Source§

fn clone(&self) -> Config

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Config

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Config

Source§

fn default() -> Self

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

Auto Trait Implementations§

Blanket Implementations§

§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

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
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FromRef<T> for T
where T: Clone,

§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
§

impl<T> Instrument for T

§

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

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

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.

§

impl<T> IntoRequest<T> for T

§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
§

impl<L> LayerExt<L> for L

§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in [Layered].
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.
§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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