Add optional calculated_channel_metrics table with configurable KPIs - #73
Open
tombonfert wants to merge 9 commits into
Open
Add optional calculated_channel_metrics table with configurable KPIs#73tombonfert wants to merge 9 commits into
tombonfert wants to merge 9 commits into
Conversation
…l_metrics - Add `CalculatedChannel.determine_channel_metrics` to derive a dynamic-schema metrics DataFrame from narrow fact rows, with duration-weighted min/max/mean and configurable identity/attribute columns. - Add `CalculatedChannels` config to opt in via `emit_channel_metrics` and select attribute columns surfaced on the metrics table. - Persist the metrics table in full and incremental modes, upserting on `(container_id, channel_id)` and scoping incremental deletes to updated containers. - Extend `ChannelType` and `SinkConfig` with metrics table name/URI support.
- Introduce `calculated_channel_kpis.KPI_BUILDERS`, a registry of named aggregation builders for `duration`, `min`, `max`, and `mean`. - Refactor `CalculatedChannel.determine_channel_metrics` to accept a `kpis` list and build aggregation columns from the registry, making the output schema dynamic over the selected KPIs. - Add `kpis` config to `CalculatedChannels` with validation and deduplication; default remains `["duration", "min", "max", "mean"]`. - Use `F.try_divide` for the duration-weighted mean so zero total duration yields null instead of failing under ANSI mode. - Wire the configured KPIs through `Report` and add unit/integration tests for custom selections, ordering, defaults, unknown KPI rejection, and zero-duration handling.
…API updates - Document the optional `calculated_channel_metrics` gold table and the `calculated_channels` config block (`emit_channel_metrics`, `attribute_columns`, `kpis`) across the data model, configuration reference, channel reference, and skills. - Add `START` and `END` to the `StatisticType` API reference. - Update `StatsAggregator` definition-hash docs to include `channel_names` and cross-channel descriptor `channel_name`.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #73 +/- ##
==========================================
+ Coverage 88.67% 88.83% +0.16%
==========================================
Files 60 61 +1
Lines 5008 5170 +162
Branches 596 621 +25
==========================================
+ Hits 4441 4593 +152
- Misses 461 466 +5
- Partials 106 111 +5
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
- Add `dispatch_calculated_channel_metrics` in `report_utils` to route `determine_channel_metrics` calls per channel type using the solved fact df. - Replace the duplicated dispatch loops in `Report` with calls to the new helper for both changed and unchanged buckets. - Add unit tests covering empty inputs, missing fact dfs, and correct routing of channels, fact df, attribute columns, and KPIs.
- Add `group_dfs_by_table` in `report_utils` to flatten per-type
`{"changed", "unchanged"}` dicts or bare DataFrames and bucket them by
output table name, skipping types that contribute no DataFrame.
- Replace the inline grouping logic in `persist_facts_full` with the new
helper.
- Reuse the helper in `Report` for calculated-channel metrics persistence
and replace the ad-hoc `reduce` + `unionByName` with
`ReportEntityTransformer.concat_dataframes`.
- Add unit tests covering empty inputs, bare DataFrames, changed/unchanged
dicts, shared tables, and skipped null/empty values.
- Add `persist_channel_metrics` in `report_utils` to persist optional calculated-channel metrics tables with dynamic schema, supporting both full overwrite and incremental upsert with delete-by-source scoping. - Replace the private `_persist_channel_metrics` method in `Report` with calls to the new helper for full and incremental persistence. - Add unit tests covering empty inputs, full-mode overwrite, incremental merge keys, and delete-condition scoping.
- Enable metrics emission in `test_incremental_changed_definition_replaces` and assert the metrics row is recomputed with the updated factor when the channel definition changes. - Add hand-computed, duration-weighted min/max/mean assertions in `test_channel_metrics_emitted_and_usable_as_impulse_source` to independently verify KPI math end to end.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in
calculated_channel_metricstable for calculated channels.Because
calculated_channel_factalready matches the silverchannelsshape,this companion table (silver
channel_metricsshape) lets the fact + metricspair serve as an Impulse silver source in its own right.
Changes
CalculatedChannelsconfig section:emit_channel_metrics(defaultfalse),attribute_columns(default[]), andkpis(defaultduration, min, max, mean). Unknown KPI names are rejected at config validation.CalculatedChannel.determine_channel_metricsderives the table directly fromthe fact rows, grouped by
(container_id, channel_id), with duration-weightedsemantics matching
SampleSeries.calculated_channel_kpis.KPI_BUILDERS), soadding a new KPI is a one-line change and is then selectable via config.
container_id, channel_id, type, data_type, onecolumn per configured KPI, one per identity key (union across the report's
channels), and one per configured attribute key. An identity key wins over an
attribute key of the same name.
container_id, channel_id, pruning stale rows from updated containers). Off by default, soexisting reports are unchanged.
Tests
guard via
try_divide), dynamic identity/attribute columns, KPI subset andordering, config default/dedupe/unknown-rejection.
and a round-trip feeding the fact + metrics pair back through
DefaultSolver.Test Plan
Docs
plus the impulse-config, impulse-channels, and impulse-data-model skills.
Checklist