mirror of
https://github.com/hanzoai/o11y.git
synced 2026-11-03 02:04:48 +00:00
* add maintenanceMuteStage to move planned maintenance to alertmanager Rules previously skipped rule.Eval() entirely during maintenance windows. This change moves suppression to MaintenanceMuter, injected as a Stage in the alertmanager notification pipeline. Now rules always evaluate and everys suppression is handled by alertmanager. Co-authored-by: Hanzo Dev <[email protected]> * refactor: wrap routing pipeline once instead of per-route injection Replace the per-route-entry loop with a single MultiStage wrap so maintenance suppression runs once per dispatch group before routing. * refactor: move maintenance mute stage into custom pipelineBuilder Copy notify.PipelineBuilder locally so we can inject mms between the silence stage and the receiver stage (GossipSettle → Inhibit → TimeActive → TimeMute → Silence → mms → Receiver), matching the correct suppression order the team requires. Co-authored-by: Hanzo Dev <[email protected]> * chore: add license header to pipeline_builder.go Copied code originates from Apache-2.0 licensed Prometheus Alertmanager; add dual copyright + SPDX identifier following the repo's convention. Co-authored-by: Hanzo Dev <[email protected]> * chore: replace SPDX tag with full Apache 2.0 license boilerplate The full license text is unambiguously compliant with Apache 2.0 Section 4(a), which requires giving recipients "a copy of this License". Co-authored-by: Hanzo Dev <[email protected]> * refactor: pass MaintenanceMuter directly to pipelineBuilder Co-authored-by: Hanzo Dev <[email protected]> * refactor: remove dead orgID param from task constructors Co-authored-by: Hanzo Dev <[email protected]> * rename buildReceiverStage -> createReceiverStage * refactor: replace maintenanceMuteStage with notify.NewMuteStage MaintenanceMuter already satisfies types.Muter, and pipelineBuilder has its own pb.metrics, so the hand-rolled maintenanceMuteStage wrapper is redundant. Use notify.NewMuteStage(pb.muter, pb.metrics) directly. Co-authored-by: Hanzo Dev <[email protected]> * refactor: hoist MuteStage construction out of the receiver loop MuteStage holds no per-receiver state, so one instance shared across all receivers is sufficient — matching how is/ss are handled upstream. Co-authored-by: Hanzo Dev <[email protected]> * refactor: always initialize maintenanceStore; remove nil guards Tests now use a real sqlrulestore-backed MaintenanceMuter instead of passing nil. With nil no longer a valid input, remove the nil guards in server.go and pipeline_builder.go. Co-authored-by: Hanzo Dev <[email protected]> * refactor: move MaintenanceMuter to Server and pass it to pipelineBuilder.New - Remove muter from pipelineBuilder struct and newPipelineBuilder(); pass it as a parameter to New() instead, consistent with inhibitor/silencer - Store muter on Server so GetAlerts can call Mutes() alongside the inhibitor and silencer, ensuring maintenance-suppressed alerts show the correct muted status in API responses Co-authored-by: Hanzo Dev <[email protected]> * remove redundant MemMarker wrapper * feat: surface maintenance-suppressed alerts via mutedBy in GetAlerts Alerts suppressed by an active maintenance window were being correctly muted in the notification pipeline but appeared as state=active in the v2 GetAlerts response, since MaintenanceMuter.Mutes had no marker side-effect (unlike inhibitor/silencer). Add MaintenanceMuter.MutedBy returning the matching window IDs, and plumb a mutedByFunc callback through NewGettableAlertsFromAlertProvider into AlertToOpenAPIAlert. The upstream v2 API forces state=suppressed when mutedBy is non-empty, so the frontend's existing state-based rendering picks it up without further changes. Use the dedicated mutedBy field rather than SilencedBy to avoid violating the "complete set of silence IDs" contract that anything querying silences by ID would rely on. Co-authored-by: Hanzo Dev <[email protected]> * code cleanup * refactor: move maintenance (planned downtime) to alertmanager packages Types move from pkg/types/ruletypes/ to pkg/types/alertmanagertypes/: - maintenance.go, recurrence.go, schedule.go (+ tests) Store impl moves from pkg/ruler/rulestore/sqlrulestore/ to pkg/alertmanager/alertmanagerstore/sqlalertmanagerstore/. Maintenance windows mute alerts, so they belong with alertmanager rather than the rule types. Co-authored-by: Hanzo Dev <[email protected]> * test: add unit tests for MaintenanceMuter Covers Mutes/MutedBy semantics (empty label, rule match, empty-RuleIDs matches-all, future windows, multi-window) and the result cache (single-fetch within TTL, stale-cache fallback on store error, re-fetch after expiry, concurrency safety). Co-authored-by: Hanzo Dev <[email protected]> * Update schema changes * Re-add marker * fix NewMaintenanceStore in tests * Go lint fixes * test: use mockery-generated mock for MaintenanceStore in muter tests Replace hand-written fakeMaintenanceStore with a mockery-generated MockMaintenanceStore, consistent with the alertmanagertest pattern. Also adds MaintenanceStore to .mockery.yml so the mock stays in sync. Co-authored-by: Hanzo Dev <[email protected]> * chore: regenerate mocks via make gen-mocks Picks up new MockHandler for the Handler interface in pkg/alertmanager and regenerates MockMaintenanceStore with canonical mockery formatting. Co-authored-by: Hanzo Dev <[email protected]> * cleanup test * test: add e2e muting tests for maintenance window behaviour * fix updates: omit empty endTime from serialization --------- Co-authored-by: Hanzo Dev <[email protected]>
18 lines
605 B
YAML
18 lines
605 B
YAML
# Link to template variables: https://pkg.go.dev/github.com/vektra/mockery/v3/config#TemplateData
|
|
template: testify
|
|
packages:
|
|
github.com/Hanzo O11y/observe/pkg/alertmanager:
|
|
config:
|
|
all: true
|
|
dir: '{{.InterfaceDir}}/alertmanagertest'
|
|
filename: "alertmanager.go"
|
|
structname: 'Mock{{.InterfaceName}}'
|
|
pkgname: '{{.SrcPackageName}}test'
|
|
github.com/Hanzo O11y/observe/pkg/tokenizer:
|
|
config:
|
|
all: true
|
|
dir: '{{.InterfaceDir}}/tokenizertest'
|
|
filename: "tokenizer.go"
|
|
structname: 'Mock{{.InterfaceName}}'
|
|
pkgname: '{{.SrcPackageName}}test'
|