Trace Cache¶
zelos_sdk.trace holds TraceSourceCache, a TraceSource that keeps the last value of every field.
zelos_sdk.trace.conditions holds the log conditions that decide which rows the cache sends.
TraceSourceCache(name, namespace=None)
¶
A TraceSource wrapper that caches the last value of each field.
Uses a Rust core for cache storage, condition evaluation, and emit decisions. Python layer provides Pythonic attribute navigation.
Examples:
source = TraceSourceCache("motor_controller") source.add_event("motor_stats", [ TraceEventFieldMetadata("rpm", DataType.Float64), TraceEventFieldMetadata("torque", DataType.Float64, "Nm") ]) source.log("motor_stats", {"rpm": 3500.0, "torque": 42.8}) assert source.motor_stats.rpm.get() == 3500.0
add_event(name, schema, conditions=None, event_type=None)
¶
Register schema (a field list or a class with FIELDS), as
TraceSource.add_event. conditions maps field name to its own
log condition; unlisted fields take the default.
add_value_table(name, field_name, data)
¶
Register a value table (enum mapping).
Register the event and field with add_event first: a key is typed
by the field it labels, so there is nothing to type it against
otherwise.
flush()
¶
Flush buffered rows to the router.
get_source()
¶
Not supported — use the cache API directly.
log(name, data)
¶
Log data and update cache. Auto-registers event if not yet registered.
log_at(time_ns, name, data)
¶
Log data at a specific timestamp. Raises ValueError when the
emit fails, as TraceSource.log_at does.
log_batch(event_name, data)
¶
Log a pyarrow.RecordBatch or Table, as TraceSource.log_batch.
Each column's last non-null value is cached.
log_many(events)
¶
Log (time_ns, name, data) rows in order, as TraceSource.log_many.
set_default_log_condition(condition=_DEFAULT)
¶
Default condition for fields without their own; each field takes a
copy. With no argument it is DefaultLogCondition(); None
removes it, so those fields log every row.
TraceSourceCacheLastEvent(name, cache, source, conditions=None)
¶
A cached event with attribute access to fields and submessages.
Examples:
event = source.motor_stats event.rpm.get() # field access event.thermal.temp.get() # submessage access event.log(rpm=3500) # log via event
time_ns
property
¶
Wall-clock timestamp of the last log call for this event, in
nanoseconds since the Unix epoch. None if the event hasn't
been logged yet. Symmetric with TraceSourceCacheLastField.get.
TraceSourceCacheLastField(name, full_path, data_type, cache, event_name, condition=None, uses_default=False)
¶
A cached field that stores the last logged value.
Examples:
field = event.rpm field.get() # Get cached value field.name # Full path: "motor_stats.rpm"
Log conditions¶
CompositeLogCondition(conditions)
¶
DefaultLogCondition(time_threshold_s=DEFAULT_LOGGING_TIME_PERIOD, epsilon=DEFAULT_LOGGING_EPSILON)
¶
Bases: LogCondition
Default logging condition: time-based at 1Hz + (value change for non-floats OR epsilon for floats).
DeltaLogCondition(delta)
¶
Bases: LogCondition
Log when the numeric value changes by more than the specified delta from the last logged value.
DeltaOrTimeLogCondition(delta, time_threshold_s=DEFAULT_LOGGING_TIME_PERIOD)
¶
EpsilonLogCondition(epsilon=sys.float_info.epsilon)
¶
EpsilonOrTimeLogCondition(epsilon, time_threshold_s=DEFAULT_LOGGING_TIME_PERIOD)
¶
LogCondition()
¶
Bases: ABC
Base class for logging conditions that determine when a field should be logged.
on_logged(current_value, current_time_ns)
¶
Called when the field is actually logged to update internal state.
should_log(current_value, current_time_ns)
abstractmethod
¶
Determine if the field should be logged based on current and last logged values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
current_value
|
Any
|
The current value to potentially log |
required |
current_time_ns
|
int
|
Current time in nanoseconds |
required |
The last logged value and time are on self.last_logged_value and
self.last_log_time_ns.
Returns:
| Type | Description |
|---|---|
bool
|
True if the field should be logged, False otherwise |
time_elapsed(current_time_ns, last_time_ns, threshold_s)
staticmethod
¶
Check if enough time has elapsed based on threshold.