mirror of
https://github.com/SigNoz/signoz.git
synced 2026-03-04 21:03:21 +00:00
Compare commits
21 Commits
rule-state
...
nv/4102
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cd1a14d02 | ||
|
|
7011d60999 | ||
|
|
aa124a3a56 | ||
|
|
bdef3660a5 | ||
|
|
c22a81ba3b | ||
|
|
5b40ae3477 | ||
|
|
196036988e | ||
|
|
0cbcc63cbe | ||
|
|
f3b2cb245f | ||
|
|
3be3727dc2 | ||
|
|
438bc0a014 | ||
|
|
7c809d7d54 | ||
|
|
cd9fd910bf | ||
|
|
ec4d55e796 | ||
|
|
59a43cb1ef | ||
|
|
50ed7e99cc | ||
|
|
87455bd014 | ||
|
|
f5b9c55408 | ||
|
|
cb1ab0024f | ||
|
|
0bbf1a3bee | ||
|
|
2595ee0b53 |
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.24-bullseye
|
||||
FROM golang:1.25-bookworm
|
||||
|
||||
ARG OS="linux"
|
||||
ARG TARGETARCH
|
||||
|
||||
@@ -6,7 +6,7 @@ ENV NODE_OPTIONS=--max-old-space-size=8192
|
||||
RUN CI=1 yarn install
|
||||
RUN CI=1 yarn build
|
||||
|
||||
FROM golang:1.24-bullseye
|
||||
FROM golang:1.25-bookworm
|
||||
|
||||
ARG OS="linux"
|
||||
ARG TARGETARCH
|
||||
|
||||
@@ -1763,140 +1763,6 @@ components:
|
||||
- type
|
||||
- orgId
|
||||
type: object
|
||||
RulestatehistorytypesAlertState:
|
||||
enum:
|
||||
- inactive
|
||||
- pending
|
||||
- recovering
|
||||
- firing
|
||||
- nodata
|
||||
- disabled
|
||||
type: string
|
||||
RulestatehistorytypesRuleStateHistoryContributorResponse:
|
||||
properties:
|
||||
count:
|
||||
minimum: 0
|
||||
type: integer
|
||||
fingerprint:
|
||||
minimum: 0
|
||||
type: integer
|
||||
labels:
|
||||
items:
|
||||
$ref: '#/components/schemas/Querybuildertypesv5Label'
|
||||
nullable: true
|
||||
type: array
|
||||
relatedLogsLink:
|
||||
type: string
|
||||
relatedTracesLink:
|
||||
type: string
|
||||
required:
|
||||
- fingerprint
|
||||
- labels
|
||||
- count
|
||||
type: object
|
||||
RulestatehistorytypesRuleStateHistoryResponseItem:
|
||||
properties:
|
||||
fingerprint:
|
||||
minimum: 0
|
||||
type: integer
|
||||
labels:
|
||||
items:
|
||||
$ref: '#/components/schemas/Querybuildertypesv5Label'
|
||||
nullable: true
|
||||
type: array
|
||||
overallState:
|
||||
$ref: '#/components/schemas/RulestatehistorytypesAlertState'
|
||||
overallStateChanged:
|
||||
type: boolean
|
||||
ruleID:
|
||||
type: string
|
||||
ruleName:
|
||||
type: string
|
||||
state:
|
||||
$ref: '#/components/schemas/RulestatehistorytypesAlertState'
|
||||
stateChanged:
|
||||
type: boolean
|
||||
unixMilli:
|
||||
format: int64
|
||||
type: integer
|
||||
value:
|
||||
format: double
|
||||
type: number
|
||||
required:
|
||||
- ruleID
|
||||
- ruleName
|
||||
- overallState
|
||||
- overallStateChanged
|
||||
- state
|
||||
- stateChanged
|
||||
- unixMilli
|
||||
- labels
|
||||
- fingerprint
|
||||
- value
|
||||
type: object
|
||||
RulestatehistorytypesRuleStateTimelineResponse:
|
||||
properties:
|
||||
items:
|
||||
items:
|
||||
$ref: '#/components/schemas/RulestatehistorytypesRuleStateHistoryResponseItem'
|
||||
nullable: true
|
||||
type: array
|
||||
nextCursor:
|
||||
type: string
|
||||
total:
|
||||
minimum: 0
|
||||
type: integer
|
||||
required:
|
||||
- items
|
||||
- total
|
||||
type: object
|
||||
RulestatehistorytypesRuleStateWindow:
|
||||
properties:
|
||||
end:
|
||||
format: int64
|
||||
type: integer
|
||||
start:
|
||||
format: int64
|
||||
type: integer
|
||||
state:
|
||||
$ref: '#/components/schemas/RulestatehistorytypesAlertState'
|
||||
required:
|
||||
- state
|
||||
- start
|
||||
- end
|
||||
type: object
|
||||
RulestatehistorytypesStats:
|
||||
properties:
|
||||
currentAvgResolutionTime:
|
||||
format: double
|
||||
type: number
|
||||
currentAvgResolutionTimeSeries:
|
||||
$ref: '#/components/schemas/Querybuildertypesv5TimeSeries'
|
||||
currentTriggersSeries:
|
||||
$ref: '#/components/schemas/Querybuildertypesv5TimeSeries'
|
||||
pastAvgResolutionTime:
|
||||
format: double
|
||||
type: number
|
||||
pastAvgResolutionTimeSeries:
|
||||
$ref: '#/components/schemas/Querybuildertypesv5TimeSeries'
|
||||
pastTriggersSeries:
|
||||
$ref: '#/components/schemas/Querybuildertypesv5TimeSeries'
|
||||
totalCurrentTriggers:
|
||||
minimum: 0
|
||||
type: integer
|
||||
totalPastTriggers:
|
||||
minimum: 0
|
||||
type: integer
|
||||
required:
|
||||
- totalCurrentTriggers
|
||||
- totalPastTriggers
|
||||
- currentTriggersSeries
|
||||
- pastTriggersSeries
|
||||
- currentAvgResolutionTime
|
||||
- pastAvgResolutionTime
|
||||
- currentAvgResolutionTimeSeries
|
||||
- pastAvgResolutionTimeSeries
|
||||
type: object
|
||||
ServiceaccounttypesFactorAPIKey:
|
||||
properties:
|
||||
createdAt:
|
||||
@@ -6952,518 +6818,6 @@ paths:
|
||||
summary: Update my organization
|
||||
tags:
|
||||
- orgs
|
||||
/api/v2/rules/{id}/history/filter_keys:
|
||||
get:
|
||||
deprecated: false
|
||||
description: Returns distinct label keys from rule history entries for the selected
|
||||
range.
|
||||
operationId: GetRuleHistoryFilterKeys
|
||||
parameters:
|
||||
- in: query
|
||||
name: signal
|
||||
schema:
|
||||
$ref: '#/components/schemas/TelemetrytypesSignal'
|
||||
- in: query
|
||||
name: source
|
||||
schema:
|
||||
$ref: '#/components/schemas/TelemetrytypesSource'
|
||||
- in: query
|
||||
name: limit
|
||||
schema:
|
||||
type: integer
|
||||
- in: query
|
||||
name: startUnixMilli
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: endUnixMilli
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: fieldContext
|
||||
schema:
|
||||
$ref: '#/components/schemas/TelemetrytypesFieldContext'
|
||||
- in: query
|
||||
name: fieldDataType
|
||||
schema:
|
||||
$ref: '#/components/schemas/TelemetrytypesFieldDataType'
|
||||
- in: query
|
||||
name: metricName
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: searchText
|
||||
schema:
|
||||
type: string
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/TelemetrytypesGettableFieldKeys'
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- data
|
||||
type: object
|
||||
description: OK
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- VIEWER
|
||||
- tokenizer:
|
||||
- VIEWER
|
||||
summary: Get rule history filter keys
|
||||
tags:
|
||||
- rules
|
||||
/api/v2/rules/{id}/history/filter_values:
|
||||
get:
|
||||
deprecated: false
|
||||
description: Returns distinct label values for a given key from rule history
|
||||
entries.
|
||||
operationId: GetRuleHistoryFilterValues
|
||||
parameters:
|
||||
- in: query
|
||||
name: signal
|
||||
schema:
|
||||
$ref: '#/components/schemas/TelemetrytypesSignal'
|
||||
- in: query
|
||||
name: source
|
||||
schema:
|
||||
$ref: '#/components/schemas/TelemetrytypesSource'
|
||||
- in: query
|
||||
name: limit
|
||||
schema:
|
||||
type: integer
|
||||
- in: query
|
||||
name: startUnixMilli
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: endUnixMilli
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: fieldContext
|
||||
schema:
|
||||
$ref: '#/components/schemas/TelemetrytypesFieldContext'
|
||||
- in: query
|
||||
name: fieldDataType
|
||||
schema:
|
||||
$ref: '#/components/schemas/TelemetrytypesFieldDataType'
|
||||
- in: query
|
||||
name: metricName
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: searchText
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: name
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: existingQuery
|
||||
schema:
|
||||
type: string
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/TelemetrytypesGettableFieldValues'
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- data
|
||||
type: object
|
||||
description: OK
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- VIEWER
|
||||
- tokenizer:
|
||||
- VIEWER
|
||||
summary: Get rule history filter values
|
||||
tags:
|
||||
- rules
|
||||
/api/v2/rules/{id}/history/overall_status:
|
||||
get:
|
||||
deprecated: false
|
||||
description: Returns overall firing/inactive intervals for a rule in the selected
|
||||
time range.
|
||||
operationId: GetRuleHistoryOverallStatus
|
||||
parameters:
|
||||
- in: query
|
||||
name: start
|
||||
required: true
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: end
|
||||
required: true
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
items:
|
||||
$ref: '#/components/schemas/RulestatehistorytypesRuleStateWindow'
|
||||
nullable: true
|
||||
type: array
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- data
|
||||
type: object
|
||||
description: OK
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- VIEWER
|
||||
- tokenizer:
|
||||
- VIEWER
|
||||
summary: Get rule overall status timeline
|
||||
tags:
|
||||
- rules
|
||||
/api/v2/rules/{id}/history/stats:
|
||||
get:
|
||||
deprecated: false
|
||||
description: Returns trigger and resolution statistics for a rule in the selected
|
||||
time range.
|
||||
operationId: GetRuleHistoryStats
|
||||
parameters:
|
||||
- in: query
|
||||
name: start
|
||||
required: true
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: end
|
||||
required: true
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/RulestatehistorytypesStats'
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- data
|
||||
type: object
|
||||
description: OK
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- VIEWER
|
||||
- tokenizer:
|
||||
- VIEWER
|
||||
summary: Get rule history stats
|
||||
tags:
|
||||
- rules
|
||||
/api/v2/rules/{id}/history/timeline:
|
||||
get:
|
||||
deprecated: false
|
||||
description: Returns paginated timeline entries for rule state transitions.
|
||||
operationId: GetRuleHistoryTimeline
|
||||
parameters:
|
||||
- in: query
|
||||
name: start
|
||||
required: true
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: end
|
||||
required: true
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: state
|
||||
schema:
|
||||
$ref: '#/components/schemas/RulestatehistorytypesAlertState'
|
||||
- in: query
|
||||
name: filterExpression
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: limit
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: order
|
||||
schema:
|
||||
$ref: '#/components/schemas/Querybuildertypesv5OrderDirection'
|
||||
- in: query
|
||||
name: cursor
|
||||
schema:
|
||||
type: string
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/RulestatehistorytypesRuleStateTimelineResponse'
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- data
|
||||
type: object
|
||||
description: OK
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- VIEWER
|
||||
- tokenizer:
|
||||
- VIEWER
|
||||
summary: Get rule history timeline
|
||||
tags:
|
||||
- rules
|
||||
/api/v2/rules/{id}/history/top_contributors:
|
||||
get:
|
||||
deprecated: false
|
||||
description: Returns top label combinations contributing to rule firing in the
|
||||
selected time range.
|
||||
operationId: GetRuleHistoryTopContributors
|
||||
parameters:
|
||||
- in: query
|
||||
name: start
|
||||
required: true
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: end
|
||||
required: true
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
items:
|
||||
$ref: '#/components/schemas/RulestatehistorytypesRuleStateHistoryContributorResponse'
|
||||
nullable: true
|
||||
type: array
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- data
|
||||
type: object
|
||||
description: OK
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- VIEWER
|
||||
- tokenizer:
|
||||
- VIEWER
|
||||
summary: Get top contributors to rule firing
|
||||
tags:
|
||||
- rules
|
||||
/api/v2/sessions:
|
||||
delete:
|
||||
deprecated: false
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/cache"
|
||||
"github.com/SigNoz/signoz/pkg/http/middleware"
|
||||
"github.com/SigNoz/signoz/pkg/modules/organization"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rulestatehistory"
|
||||
"github.com/SigNoz/signoz/pkg/prometheus"
|
||||
"github.com/SigNoz/signoz/pkg/querier"
|
||||
"github.com/SigNoz/signoz/pkg/signoz"
|
||||
@@ -103,7 +102,6 @@ func NewServer(config signoz.Config, signoz *signoz.SigNoz) (*Server, error) {
|
||||
signoz.TelemetryMetadataStore,
|
||||
signoz.Prometheus,
|
||||
signoz.Modules.OrgGetter,
|
||||
signoz.Modules.RuleStateHistory,
|
||||
signoz.Querier,
|
||||
signoz.Instrumentation.ToProviderSettings(),
|
||||
signoz.QueryParser,
|
||||
@@ -351,30 +349,29 @@ func (s *Server) Stop(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeRulesManager(ch baseint.Reader, cache cache.Cache, alertmanager alertmanager.Alertmanager, sqlstore sqlstore.SQLStore, telemetryStore telemetrystore.TelemetryStore, metadataStore telemetrytypes.MetadataStore, prometheus prometheus.Prometheus, orgGetter organization.Getter, ruleStateHistoryModule rulestatehistory.Module, querier querier.Querier, providerSettings factory.ProviderSettings, queryParser queryparser.QueryParser) (*baserules.Manager, error) {
|
||||
func makeRulesManager(ch baseint.Reader, cache cache.Cache, alertmanager alertmanager.Alertmanager, sqlstore sqlstore.SQLStore, telemetryStore telemetrystore.TelemetryStore, metadataStore telemetrytypes.MetadataStore, prometheus prometheus.Prometheus, orgGetter organization.Getter, querier querier.Querier, providerSettings factory.ProviderSettings, queryParser queryparser.QueryParser) (*baserules.Manager, error) {
|
||||
ruleStore := sqlrulestore.NewRuleStore(sqlstore, queryParser, providerSettings)
|
||||
maintenanceStore := sqlrulestore.NewMaintenanceStore(sqlstore)
|
||||
// create manager opts
|
||||
managerOpts := &baserules.ManagerOptions{
|
||||
TelemetryStore: telemetryStore,
|
||||
MetadataStore: metadataStore,
|
||||
Prometheus: prometheus,
|
||||
Context: context.Background(),
|
||||
Logger: zap.L(),
|
||||
Reader: ch,
|
||||
Querier: querier,
|
||||
SLogger: providerSettings.Logger,
|
||||
Cache: cache,
|
||||
EvalDelay: baseconst.GetEvalDelay(),
|
||||
PrepareTaskFunc: rules.PrepareTaskFunc,
|
||||
PrepareTestRuleFunc: rules.TestNotification,
|
||||
Alertmanager: alertmanager,
|
||||
OrgGetter: orgGetter,
|
||||
RuleStore: ruleStore,
|
||||
MaintenanceStore: maintenanceStore,
|
||||
SqlStore: sqlstore,
|
||||
QueryParser: queryParser,
|
||||
RuleStateHistoryModule: ruleStateHistoryModule,
|
||||
TelemetryStore: telemetryStore,
|
||||
MetadataStore: metadataStore,
|
||||
Prometheus: prometheus,
|
||||
Context: context.Background(),
|
||||
Logger: zap.L(),
|
||||
Reader: ch,
|
||||
Querier: querier,
|
||||
SLogger: providerSettings.Logger,
|
||||
Cache: cache,
|
||||
EvalDelay: baseconst.GetEvalDelay(),
|
||||
PrepareTaskFunc: rules.PrepareTaskFunc,
|
||||
PrepareTestRuleFunc: rules.TestNotification,
|
||||
Alertmanager: alertmanager,
|
||||
OrgGetter: orgGetter,
|
||||
RuleStore: ruleStore,
|
||||
MaintenanceStore: maintenanceStore,
|
||||
SqlStore: sqlstore,
|
||||
QueryParser: queryParser,
|
||||
}
|
||||
|
||||
// create Manager
|
||||
|
||||
@@ -26,7 +26,6 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
|
||||
if err != nil {
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "evaluation is invalid: %v", err)
|
||||
}
|
||||
|
||||
if opts.Rule.RuleType == ruletypes.RuleTypeThreshold {
|
||||
// create a threshold rule
|
||||
tr, err := baserules.NewThresholdRule(
|
||||
@@ -40,7 +39,6 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
|
||||
baserules.WithSQLStore(opts.SQLStore),
|
||||
baserules.WithQueryParser(opts.ManagerOpts.QueryParser),
|
||||
baserules.WithMetadataStore(opts.ManagerOpts.MetadataStore),
|
||||
baserules.WithRuleStateHistoryModule(opts.ManagerOpts.RuleStateHistoryModule),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@@ -65,7 +63,6 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
|
||||
baserules.WithSQLStore(opts.SQLStore),
|
||||
baserules.WithQueryParser(opts.ManagerOpts.QueryParser),
|
||||
baserules.WithMetadataStore(opts.ManagerOpts.MetadataStore),
|
||||
baserules.WithRuleStateHistoryModule(opts.ManagerOpts.RuleStateHistoryModule),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@@ -91,7 +88,6 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
|
||||
baserules.WithSQLStore(opts.SQLStore),
|
||||
baserules.WithQueryParser(opts.ManagerOpts.QueryParser),
|
||||
baserules.WithMetadataStore(opts.ManagerOpts.MetadataStore),
|
||||
baserules.WithRuleStateHistoryModule(opts.ManagerOpts.RuleStateHistoryModule),
|
||||
)
|
||||
if err != nil {
|
||||
return task, err
|
||||
|
||||
@@ -1,744 +0,0 @@
|
||||
/**
|
||||
* ! Do not edit manually
|
||||
* * The file has been auto-generated using Orval for SigNoz
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
QueryClient,
|
||||
QueryFunction,
|
||||
QueryKey,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useQuery } from 'react-query';
|
||||
|
||||
import type { ErrorType } from '../../../generatedAPIInstance';
|
||||
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
|
||||
import type {
|
||||
GetRuleHistoryFilterKeys200,
|
||||
GetRuleHistoryFilterKeysParams,
|
||||
GetRuleHistoryFilterKeysPathParameters,
|
||||
GetRuleHistoryFilterValues200,
|
||||
GetRuleHistoryFilterValuesParams,
|
||||
GetRuleHistoryFilterValuesPathParameters,
|
||||
GetRuleHistoryOverallStatus200,
|
||||
GetRuleHistoryOverallStatusParams,
|
||||
GetRuleHistoryOverallStatusPathParameters,
|
||||
GetRuleHistoryStats200,
|
||||
GetRuleHistoryStatsParams,
|
||||
GetRuleHistoryStatsPathParameters,
|
||||
GetRuleHistoryTimeline200,
|
||||
GetRuleHistoryTimelineParams,
|
||||
GetRuleHistoryTimelinePathParameters,
|
||||
GetRuleHistoryTopContributors200,
|
||||
GetRuleHistoryTopContributorsParams,
|
||||
GetRuleHistoryTopContributorsPathParameters,
|
||||
RenderErrorResponseDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
/**
|
||||
* Returns distinct label keys from rule history entries for the selected range.
|
||||
* @summary Get rule history filter keys
|
||||
*/
|
||||
export const getRuleHistoryFilterKeys = (
|
||||
{ id }: GetRuleHistoryFilterKeysPathParameters,
|
||||
params?: GetRuleHistoryFilterKeysParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetRuleHistoryFilterKeys200>({
|
||||
url: `/api/v2/rules/${id}/history/filter_keys`,
|
||||
method: 'GET',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetRuleHistoryFilterKeysQueryKey = (
|
||||
{ id }: GetRuleHistoryFilterKeysPathParameters,
|
||||
params?: GetRuleHistoryFilterKeysParams,
|
||||
) => {
|
||||
return [
|
||||
`/api/v2/rules/${id}/history/filter_keys`,
|
||||
...(params ? [params] : []),
|
||||
] as const;
|
||||
};
|
||||
|
||||
export const getGetRuleHistoryFilterKeysQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getRuleHistoryFilterKeys>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>
|
||||
>(
|
||||
{ id }: GetRuleHistoryFilterKeysPathParameters,
|
||||
params?: GetRuleHistoryFilterKeysParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryFilterKeys>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getGetRuleHistoryFilterKeysQueryKey({ id }, params);
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof getRuleHistoryFilterKeys>>
|
||||
> = ({ signal }) => getRuleHistoryFilterKeys({ id }, params, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!id,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryFilterKeys>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetRuleHistoryFilterKeysQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getRuleHistoryFilterKeys>>
|
||||
>;
|
||||
export type GetRuleHistoryFilterKeysQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get rule history filter keys
|
||||
*/
|
||||
|
||||
export function useGetRuleHistoryFilterKeys<
|
||||
TData = Awaited<ReturnType<typeof getRuleHistoryFilterKeys>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>
|
||||
>(
|
||||
{ id }: GetRuleHistoryFilterKeysPathParameters,
|
||||
params?: GetRuleHistoryFilterKeysParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryFilterKeys>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetRuleHistoryFilterKeysQueryOptions(
|
||||
{ id },
|
||||
params,
|
||||
options,
|
||||
);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get rule history filter keys
|
||||
*/
|
||||
export const invalidateGetRuleHistoryFilterKeys = async (
|
||||
queryClient: QueryClient,
|
||||
{ id }: GetRuleHistoryFilterKeysPathParameters,
|
||||
params?: GetRuleHistoryFilterKeysParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetRuleHistoryFilterKeysQueryKey({ id }, params) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns distinct label values for a given key from rule history entries.
|
||||
* @summary Get rule history filter values
|
||||
*/
|
||||
export const getRuleHistoryFilterValues = (
|
||||
{ id }: GetRuleHistoryFilterValuesPathParameters,
|
||||
params?: GetRuleHistoryFilterValuesParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetRuleHistoryFilterValues200>({
|
||||
url: `/api/v2/rules/${id}/history/filter_values`,
|
||||
method: 'GET',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetRuleHistoryFilterValuesQueryKey = (
|
||||
{ id }: GetRuleHistoryFilterValuesPathParameters,
|
||||
params?: GetRuleHistoryFilterValuesParams,
|
||||
) => {
|
||||
return [
|
||||
`/api/v2/rules/${id}/history/filter_values`,
|
||||
...(params ? [params] : []),
|
||||
] as const;
|
||||
};
|
||||
|
||||
export const getGetRuleHistoryFilterValuesQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getRuleHistoryFilterValues>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>
|
||||
>(
|
||||
{ id }: GetRuleHistoryFilterValuesPathParameters,
|
||||
params?: GetRuleHistoryFilterValuesParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryFilterValues>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ??
|
||||
getGetRuleHistoryFilterValuesQueryKey({ id }, params);
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof getRuleHistoryFilterValues>>
|
||||
> = ({ signal }) => getRuleHistoryFilterValues({ id }, params, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!id,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryFilterValues>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetRuleHistoryFilterValuesQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getRuleHistoryFilterValues>>
|
||||
>;
|
||||
export type GetRuleHistoryFilterValuesQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get rule history filter values
|
||||
*/
|
||||
|
||||
export function useGetRuleHistoryFilterValues<
|
||||
TData = Awaited<ReturnType<typeof getRuleHistoryFilterValues>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>
|
||||
>(
|
||||
{ id }: GetRuleHistoryFilterValuesPathParameters,
|
||||
params?: GetRuleHistoryFilterValuesParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryFilterValues>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetRuleHistoryFilterValuesQueryOptions(
|
||||
{ id },
|
||||
params,
|
||||
options,
|
||||
);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get rule history filter values
|
||||
*/
|
||||
export const invalidateGetRuleHistoryFilterValues = async (
|
||||
queryClient: QueryClient,
|
||||
{ id }: GetRuleHistoryFilterValuesPathParameters,
|
||||
params?: GetRuleHistoryFilterValuesParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetRuleHistoryFilterValuesQueryKey({ id }, params) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns overall firing/inactive intervals for a rule in the selected time range.
|
||||
* @summary Get rule overall status timeline
|
||||
*/
|
||||
export const getRuleHistoryOverallStatus = (
|
||||
{ id }: GetRuleHistoryOverallStatusPathParameters,
|
||||
params: GetRuleHistoryOverallStatusParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetRuleHistoryOverallStatus200>({
|
||||
url: `/api/v2/rules/${id}/history/overall_status`,
|
||||
method: 'GET',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetRuleHistoryOverallStatusQueryKey = (
|
||||
{ id }: GetRuleHistoryOverallStatusPathParameters,
|
||||
params?: GetRuleHistoryOverallStatusParams,
|
||||
) => {
|
||||
return [
|
||||
`/api/v2/rules/${id}/history/overall_status`,
|
||||
...(params ? [params] : []),
|
||||
] as const;
|
||||
};
|
||||
|
||||
export const getGetRuleHistoryOverallStatusQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getRuleHistoryOverallStatus>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>
|
||||
>(
|
||||
{ id }: GetRuleHistoryOverallStatusPathParameters,
|
||||
params: GetRuleHistoryOverallStatusParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryOverallStatus>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ??
|
||||
getGetRuleHistoryOverallStatusQueryKey({ id }, params);
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof getRuleHistoryOverallStatus>>
|
||||
> = ({ signal }) => getRuleHistoryOverallStatus({ id }, params, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!id,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryOverallStatus>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetRuleHistoryOverallStatusQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getRuleHistoryOverallStatus>>
|
||||
>;
|
||||
export type GetRuleHistoryOverallStatusQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get rule overall status timeline
|
||||
*/
|
||||
|
||||
export function useGetRuleHistoryOverallStatus<
|
||||
TData = Awaited<ReturnType<typeof getRuleHistoryOverallStatus>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>
|
||||
>(
|
||||
{ id }: GetRuleHistoryOverallStatusPathParameters,
|
||||
params: GetRuleHistoryOverallStatusParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryOverallStatus>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetRuleHistoryOverallStatusQueryOptions(
|
||||
{ id },
|
||||
params,
|
||||
options,
|
||||
);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get rule overall status timeline
|
||||
*/
|
||||
export const invalidateGetRuleHistoryOverallStatus = async (
|
||||
queryClient: QueryClient,
|
||||
{ id }: GetRuleHistoryOverallStatusPathParameters,
|
||||
params: GetRuleHistoryOverallStatusParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetRuleHistoryOverallStatusQueryKey({ id }, params) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns trigger and resolution statistics for a rule in the selected time range.
|
||||
* @summary Get rule history stats
|
||||
*/
|
||||
export const getRuleHistoryStats = (
|
||||
{ id }: GetRuleHistoryStatsPathParameters,
|
||||
params: GetRuleHistoryStatsParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetRuleHistoryStats200>({
|
||||
url: `/api/v2/rules/${id}/history/stats`,
|
||||
method: 'GET',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetRuleHistoryStatsQueryKey = (
|
||||
{ id }: GetRuleHistoryStatsPathParameters,
|
||||
params?: GetRuleHistoryStatsParams,
|
||||
) => {
|
||||
return [
|
||||
`/api/v2/rules/${id}/history/stats`,
|
||||
...(params ? [params] : []),
|
||||
] as const;
|
||||
};
|
||||
|
||||
export const getGetRuleHistoryStatsQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getRuleHistoryStats>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>
|
||||
>(
|
||||
{ id }: GetRuleHistoryStatsPathParameters,
|
||||
params: GetRuleHistoryStatsParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryStats>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getGetRuleHistoryStatsQueryKey({ id }, params);
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof getRuleHistoryStats>>
|
||||
> = ({ signal }) => getRuleHistoryStats({ id }, params, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!id,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryStats>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetRuleHistoryStatsQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getRuleHistoryStats>>
|
||||
>;
|
||||
export type GetRuleHistoryStatsQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get rule history stats
|
||||
*/
|
||||
|
||||
export function useGetRuleHistoryStats<
|
||||
TData = Awaited<ReturnType<typeof getRuleHistoryStats>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>
|
||||
>(
|
||||
{ id }: GetRuleHistoryStatsPathParameters,
|
||||
params: GetRuleHistoryStatsParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryStats>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetRuleHistoryStatsQueryOptions(
|
||||
{ id },
|
||||
params,
|
||||
options,
|
||||
);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get rule history stats
|
||||
*/
|
||||
export const invalidateGetRuleHistoryStats = async (
|
||||
queryClient: QueryClient,
|
||||
{ id }: GetRuleHistoryStatsPathParameters,
|
||||
params: GetRuleHistoryStatsParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetRuleHistoryStatsQueryKey({ id }, params) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns paginated timeline entries for rule state transitions.
|
||||
* @summary Get rule history timeline
|
||||
*/
|
||||
export const getRuleHistoryTimeline = (
|
||||
{ id }: GetRuleHistoryTimelinePathParameters,
|
||||
params: GetRuleHistoryTimelineParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetRuleHistoryTimeline200>({
|
||||
url: `/api/v2/rules/${id}/history/timeline`,
|
||||
method: 'GET',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetRuleHistoryTimelineQueryKey = (
|
||||
{ id }: GetRuleHistoryTimelinePathParameters,
|
||||
params?: GetRuleHistoryTimelineParams,
|
||||
) => {
|
||||
return [
|
||||
`/api/v2/rules/${id}/history/timeline`,
|
||||
...(params ? [params] : []),
|
||||
] as const;
|
||||
};
|
||||
|
||||
export const getGetRuleHistoryTimelineQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getRuleHistoryTimeline>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>
|
||||
>(
|
||||
{ id }: GetRuleHistoryTimelinePathParameters,
|
||||
params: GetRuleHistoryTimelineParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryTimeline>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getGetRuleHistoryTimelineQueryKey({ id }, params);
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof getRuleHistoryTimeline>>
|
||||
> = ({ signal }) => getRuleHistoryTimeline({ id }, params, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!id,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryTimeline>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetRuleHistoryTimelineQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getRuleHistoryTimeline>>
|
||||
>;
|
||||
export type GetRuleHistoryTimelineQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get rule history timeline
|
||||
*/
|
||||
|
||||
export function useGetRuleHistoryTimeline<
|
||||
TData = Awaited<ReturnType<typeof getRuleHistoryTimeline>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>
|
||||
>(
|
||||
{ id }: GetRuleHistoryTimelinePathParameters,
|
||||
params: GetRuleHistoryTimelineParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryTimeline>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetRuleHistoryTimelineQueryOptions(
|
||||
{ id },
|
||||
params,
|
||||
options,
|
||||
);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get rule history timeline
|
||||
*/
|
||||
export const invalidateGetRuleHistoryTimeline = async (
|
||||
queryClient: QueryClient,
|
||||
{ id }: GetRuleHistoryTimelinePathParameters,
|
||||
params: GetRuleHistoryTimelineParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetRuleHistoryTimelineQueryKey({ id }, params) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns top label combinations contributing to rule firing in the selected time range.
|
||||
* @summary Get top contributors to rule firing
|
||||
*/
|
||||
export const getRuleHistoryTopContributors = (
|
||||
{ id }: GetRuleHistoryTopContributorsPathParameters,
|
||||
params: GetRuleHistoryTopContributorsParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetRuleHistoryTopContributors200>({
|
||||
url: `/api/v2/rules/${id}/history/top_contributors`,
|
||||
method: 'GET',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetRuleHistoryTopContributorsQueryKey = (
|
||||
{ id }: GetRuleHistoryTopContributorsPathParameters,
|
||||
params?: GetRuleHistoryTopContributorsParams,
|
||||
) => {
|
||||
return [
|
||||
`/api/v2/rules/${id}/history/top_contributors`,
|
||||
...(params ? [params] : []),
|
||||
] as const;
|
||||
};
|
||||
|
||||
export const getGetRuleHistoryTopContributorsQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getRuleHistoryTopContributors>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>
|
||||
>(
|
||||
{ id }: GetRuleHistoryTopContributorsPathParameters,
|
||||
params: GetRuleHistoryTopContributorsParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryTopContributors>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ??
|
||||
getGetRuleHistoryTopContributorsQueryKey({ id }, params);
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof getRuleHistoryTopContributors>>
|
||||
> = ({ signal }) => getRuleHistoryTopContributors({ id }, params, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!id,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryTopContributors>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetRuleHistoryTopContributorsQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getRuleHistoryTopContributors>>
|
||||
>;
|
||||
export type GetRuleHistoryTopContributorsQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get top contributors to rule firing
|
||||
*/
|
||||
|
||||
export function useGetRuleHistoryTopContributors<
|
||||
TData = Awaited<ReturnType<typeof getRuleHistoryTopContributors>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>
|
||||
>(
|
||||
{ id }: GetRuleHistoryTopContributorsPathParameters,
|
||||
params: GetRuleHistoryTopContributorsParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getRuleHistoryTopContributors>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetRuleHistoryTopContributorsQueryOptions(
|
||||
{ id },
|
||||
params,
|
||||
options,
|
||||
);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get top contributors to rule firing
|
||||
*/
|
||||
export const invalidateGetRuleHistoryTopContributors = async (
|
||||
queryClient: QueryClient,
|
||||
{ id }: GetRuleHistoryTopContributorsPathParameters,
|
||||
params: GetRuleHistoryTopContributorsParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetRuleHistoryTopContributorsQueryKey({ id }, params) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
@@ -2090,139 +2090,6 @@ export interface RoletypesRoleDTO {
|
||||
updatedAt?: Date;
|
||||
}
|
||||
|
||||
export enum RulestatehistorytypesAlertStateDTO {
|
||||
inactive = 'inactive',
|
||||
pending = 'pending',
|
||||
recovering = 'recovering',
|
||||
firing = 'firing',
|
||||
nodata = 'nodata',
|
||||
disabled = 'disabled',
|
||||
}
|
||||
export interface RulestatehistorytypesRuleStateHistoryContributorResponseDTO {
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
count: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
fingerprint: number;
|
||||
/**
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
labels: Querybuildertypesv5LabelDTO[] | null;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
relatedLogsLink?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
relatedTracesLink?: string;
|
||||
}
|
||||
|
||||
export interface RulestatehistorytypesRuleStateHistoryResponseItemDTO {
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
fingerprint: number;
|
||||
/**
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
labels: Querybuildertypesv5LabelDTO[] | null;
|
||||
overallState: RulestatehistorytypesAlertStateDTO;
|
||||
/**
|
||||
* @type boolean
|
||||
*/
|
||||
overallStateChanged: boolean;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
ruleID: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
ruleName: string;
|
||||
state: RulestatehistorytypesAlertStateDTO;
|
||||
/**
|
||||
* @type boolean
|
||||
*/
|
||||
stateChanged: boolean;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
*/
|
||||
unixMilli: number;
|
||||
/**
|
||||
* @type number
|
||||
* @format double
|
||||
*/
|
||||
value: number;
|
||||
}
|
||||
|
||||
export interface RulestatehistorytypesRuleStateTimelineResponseDTO {
|
||||
/**
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
items: RulestatehistorytypesRuleStateHistoryResponseItemDTO[] | null;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
nextCursor?: string;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface RulestatehistorytypesRuleStateWindowDTO {
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
*/
|
||||
end: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
*/
|
||||
start: number;
|
||||
state: RulestatehistorytypesAlertStateDTO;
|
||||
}
|
||||
|
||||
export interface RulestatehistorytypesStatsDTO {
|
||||
/**
|
||||
* @type number
|
||||
* @format double
|
||||
*/
|
||||
currentAvgResolutionTime: number;
|
||||
currentAvgResolutionTimeSeries: Querybuildertypesv5TimeSeriesDTO;
|
||||
currentTriggersSeries: Querybuildertypesv5TimeSeriesDTO;
|
||||
/**
|
||||
* @type number
|
||||
* @format double
|
||||
*/
|
||||
pastAvgResolutionTime: number;
|
||||
pastAvgResolutionTimeSeries: Querybuildertypesv5TimeSeriesDTO;
|
||||
pastTriggersSeries: Querybuildertypesv5TimeSeriesDTO;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
totalCurrentTriggers: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
totalPastTriggers: number;
|
||||
}
|
||||
|
||||
export interface ServiceaccounttypesFactorAPIKeyDTO {
|
||||
/**
|
||||
* @type string
|
||||
@@ -3696,266 +3563,6 @@ export type GetMyOrganization200 = {
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type GetRuleHistoryFilterKeysPathParameters = {
|
||||
id: string;
|
||||
};
|
||||
export type GetRuleHistoryFilterKeysParams = {
|
||||
/**
|
||||
* @description undefined
|
||||
*/
|
||||
signal?: TelemetrytypesSignalDTO;
|
||||
/**
|
||||
* @description undefined
|
||||
*/
|
||||
source?: TelemetrytypesSourceDTO;
|
||||
/**
|
||||
* @type integer
|
||||
* @description undefined
|
||||
*/
|
||||
limit?: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
startUnixMilli?: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
endUnixMilli?: number;
|
||||
/**
|
||||
* @description undefined
|
||||
*/
|
||||
fieldContext?: TelemetrytypesFieldContextDTO;
|
||||
/**
|
||||
* @description undefined
|
||||
*/
|
||||
fieldDataType?: TelemetrytypesFieldDataTypeDTO;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
metricName?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
searchText?: string;
|
||||
};
|
||||
|
||||
export type GetRuleHistoryFilterKeys200 = {
|
||||
data: TelemetrytypesGettableFieldKeysDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type GetRuleHistoryFilterValuesPathParameters = {
|
||||
id: string;
|
||||
};
|
||||
export type GetRuleHistoryFilterValuesParams = {
|
||||
/**
|
||||
* @description undefined
|
||||
*/
|
||||
signal?: TelemetrytypesSignalDTO;
|
||||
/**
|
||||
* @description undefined
|
||||
*/
|
||||
source?: TelemetrytypesSourceDTO;
|
||||
/**
|
||||
* @type integer
|
||||
* @description undefined
|
||||
*/
|
||||
limit?: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
startUnixMilli?: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
endUnixMilli?: number;
|
||||
/**
|
||||
* @description undefined
|
||||
*/
|
||||
fieldContext?: TelemetrytypesFieldContextDTO;
|
||||
/**
|
||||
* @description undefined
|
||||
*/
|
||||
fieldDataType?: TelemetrytypesFieldDataTypeDTO;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
metricName?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
searchText?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
existingQuery?: string;
|
||||
};
|
||||
|
||||
export type GetRuleHistoryFilterValues200 = {
|
||||
data: TelemetrytypesGettableFieldValuesDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type GetRuleHistoryOverallStatusPathParameters = {
|
||||
id: string;
|
||||
};
|
||||
export type GetRuleHistoryOverallStatusParams = {
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
start: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
end: number;
|
||||
};
|
||||
|
||||
export type GetRuleHistoryOverallStatus200 = {
|
||||
/**
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
data: RulestatehistorytypesRuleStateWindowDTO[] | null;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type GetRuleHistoryStatsPathParameters = {
|
||||
id: string;
|
||||
};
|
||||
export type GetRuleHistoryStatsParams = {
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
start: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
end: number;
|
||||
};
|
||||
|
||||
export type GetRuleHistoryStats200 = {
|
||||
data: RulestatehistorytypesStatsDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type GetRuleHistoryTimelinePathParameters = {
|
||||
id: string;
|
||||
};
|
||||
export type GetRuleHistoryTimelineParams = {
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
start: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
end: number;
|
||||
/**
|
||||
* @description undefined
|
||||
*/
|
||||
state?: RulestatehistorytypesAlertStateDTO;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
filterExpression?: string;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
limit?: number;
|
||||
/**
|
||||
* @description undefined
|
||||
*/
|
||||
order?: Querybuildertypesv5OrderDirectionDTO;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
cursor?: string;
|
||||
};
|
||||
|
||||
export type GetRuleHistoryTimeline200 = {
|
||||
data: RulestatehistorytypesRuleStateTimelineResponseDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type GetRuleHistoryTopContributorsPathParameters = {
|
||||
id: string;
|
||||
};
|
||||
export type GetRuleHistoryTopContributorsParams = {
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
start: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
end: number;
|
||||
};
|
||||
|
||||
export type GetRuleHistoryTopContributors200 = {
|
||||
/**
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
data: RulestatehistorytypesRuleStateHistoryContributorResponseDTO[] | null;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type GetSessionContext200 = {
|
||||
data: AuthtypesSessionContextDTO;
|
||||
/**
|
||||
|
||||
354
go.mod
354
go.mod
@@ -1,51 +1,51 @@
|
||||
module github.com/SigNoz/signoz
|
||||
|
||||
go 1.24.0
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.1
|
||||
dario.cat/mergo v1.0.2
|
||||
github.com/AfterShip/clickhouse-sql-parser v0.4.16
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.40.1
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2
|
||||
github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd
|
||||
github.com/SigNoz/signoz-otel-collector v0.129.10-rc.9
|
||||
github.com/SigNoz/signoz-otel-collector v0.144.2
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1
|
||||
github.com/antonmedv/expr v1.15.3
|
||||
github.com/bytedance/sonic v1.14.1
|
||||
github.com/cespare/xxhash/v2 v2.3.0
|
||||
github.com/coreos/go-oidc/v3 v3.14.1
|
||||
github.com/coreos/go-oidc/v3 v3.17.0
|
||||
github.com/dgraph-io/ristretto/v2 v2.3.0
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
github.com/gin-gonic/gin v1.11.0
|
||||
github.com/go-co-op/gocron v1.30.1
|
||||
github.com/go-openapi/runtime v0.28.0
|
||||
github.com/go-openapi/strfmt v0.23.0
|
||||
github.com/go-openapi/runtime v0.29.2
|
||||
github.com/go-openapi/strfmt v0.25.0
|
||||
github.com/go-redis/redismock/v9 v9.2.0
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0
|
||||
github.com/gojek/heimdall/v7 v7.0.3
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gorilla/handlers v1.5.1
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674
|
||||
github.com/huandu/go-sqlbuilder v1.35.0
|
||||
github.com/jackc/pgx/v5 v5.7.6
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12
|
||||
github.com/knadh/koanf v1.5.0
|
||||
github.com/knadh/koanf/v2 v2.2.0
|
||||
github.com/mailru/easyjson v0.7.7
|
||||
github.com/open-telemetry/opamp-go v0.19.0
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza v0.128.0
|
||||
github.com/knadh/koanf/v2 v2.3.2
|
||||
github.com/mailru/easyjson v0.9.0
|
||||
github.com/open-telemetry/opamp-go v0.22.0
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza v0.144.0
|
||||
github.com/openfga/api/proto v0.0.0-20250909172242-b4b2a12f5c67
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20250428093642-7aeebe78bbfe
|
||||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/alertmanager v0.28.1
|
||||
github.com/prometheus/alertmanager v0.31.0
|
||||
github.com/prometheus/client_golang v1.23.2
|
||||
github.com/prometheus/common v0.66.1
|
||||
github.com/prometheus/prometheus v0.304.1
|
||||
github.com/prometheus/common v0.67.5
|
||||
github.com/prometheus/prometheus v0.310.0
|
||||
github.com/redis/go-redis/extra/redisotel/v9 v9.15.1
|
||||
github.com/redis/go-redis/v9 v9.15.1
|
||||
github.com/redis/go-redis/v9 v9.17.2
|
||||
github.com/rs/cors v1.11.1
|
||||
github.com/russellhaering/gosaml2 v0.9.0
|
||||
github.com/russellhaering/goxmldsig v1.2.0
|
||||
@@ -54,7 +54,7 @@ require (
|
||||
github.com/sethvargo/go-password v0.2.0
|
||||
github.com/smartystreets/goconvey v1.8.1
|
||||
github.com/soheilhy/cmux v0.1.5
|
||||
github.com/spf13/cobra v1.10.1
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/srikanthccv/ClickHouse-go-mock v0.13.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/swaggest/jsonschema-go v0.3.78
|
||||
@@ -64,43 +64,71 @@ require (
|
||||
github.com/uptrace/bun/dialect/pgdialect v1.2.9
|
||||
github.com/uptrace/bun/dialect/sqlitedialect v1.2.9
|
||||
github.com/uptrace/bun/extra/bunotel v1.2.9
|
||||
go.opentelemetry.io/collector/confmap v1.34.0
|
||||
go.opentelemetry.io/collector/otelcol v0.128.0
|
||||
go.opentelemetry.io/collector/pdata v1.34.0
|
||||
go.opentelemetry.io/collector/confmap v1.51.0
|
||||
go.opentelemetry.io/collector/otelcol v0.144.0
|
||||
go.opentelemetry.io/collector/pdata v1.51.0
|
||||
go.opentelemetry.io/contrib/config v0.10.0
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.63.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0
|
||||
go.opentelemetry.io/otel v1.38.0
|
||||
go.opentelemetry.io/otel/metric v1.38.0
|
||||
go.opentelemetry.io/otel/sdk v1.38.0
|
||||
go.opentelemetry.io/otel/trace v1.38.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0
|
||||
go.opentelemetry.io/otel v1.40.0
|
||||
go.opentelemetry.io/otel/metric v1.40.0
|
||||
go.opentelemetry.io/otel/sdk v1.40.0
|
||||
go.opentelemetry.io/otel/trace v1.40.0
|
||||
go.uber.org/multierr v1.11.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b
|
||||
golang.org/x/net v0.47.0
|
||||
golang.org/x/oauth2 v0.30.0
|
||||
go.uber.org/zap v1.27.1
|
||||
golang.org/x/crypto v0.47.0
|
||||
golang.org/x/exp v0.0.0-20260112195511-716be5621a96
|
||||
golang.org/x/net v0.49.0
|
||||
golang.org/x/oauth2 v0.34.0
|
||||
golang.org/x/sync v0.19.0
|
||||
golang.org/x/text v0.32.0
|
||||
google.golang.org/protobuf v1.36.9
|
||||
golang.org/x/text v0.33.0
|
||||
google.golang.org/protobuf v1.36.11
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/apimachinery v0.34.0
|
||||
k8s.io/apimachinery v0.35.0
|
||||
modernc.org/sqlite v1.39.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sns v1.39.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 // indirect
|
||||
github.com/aws/smithy-go v1.24.0 // indirect
|
||||
github.com/bytedance/gopkg v0.1.3 // indirect
|
||||
github.com/bytedance/sonic/loader v0.3.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||
github.com/go-openapi/swag/cmdutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/conv v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/fileutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/jsonname v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/jsonutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/loading v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/mangling v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/netutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/stringutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/typeutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/yamlutils v0.25.4 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.27.0 // indirect
|
||||
github.com/goccy/go-yaml v1.18.0 // indirect
|
||||
github.com/goccy/go-yaml v1.19.2 // indirect
|
||||
github.com/hashicorp/go-metrics v0.5.4 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/prometheus/client_golang/exp v0.0.0-20260108101519-fb0838f53562 // indirect
|
||||
github.com/redis/go-redis/extra/rediscmd/v9 v9.15.1 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/swaggest/refl v1.4.0 // indirect
|
||||
@@ -108,69 +136,70 @@ require (
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.3.0 // indirect
|
||||
github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2 // indirect
|
||||
go.opentelemetry.io/collector/config/configretry v1.34.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go.opentelemetry.io/collector/client v1.50.0 // indirect
|
||||
go.opentelemetry.io/collector/config/configoptional v1.50.0 // indirect
|
||||
go.opentelemetry.io/collector/config/configretry v1.50.0 // indirect
|
||||
go.opentelemetry.io/collector/exporter/exporterhelper v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/internal/componentalias v0.145.0 // indirect
|
||||
go.opentelemetry.io/collector/pdata/xpdata v0.144.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||
golang.org/x/arch v0.20.0 // indirect
|
||||
golang.org/x/tools/godoc v0.1.0-deprecated // indirect
|
||||
modernc.org/libc v1.66.10 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
cel.dev/expr v0.24.0 // indirect
|
||||
cloud.google.com/go/auth v0.16.1 // indirect
|
||||
cel.dev/expr v0.25.1 // indirect
|
||||
cloud.google.com/go/auth v0.18.1 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.8.2 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect
|
||||
github.com/ClickHouse/ch-go v0.67.0 // indirect
|
||||
github.com/Masterminds/squirrel v1.5.4 // indirect
|
||||
github.com/Yiling-J/theine-go v0.6.2 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
|
||||
github.com/andybalholm/brotli v1.2.0 // indirect
|
||||
github.com/armon/go-metrics v0.4.1 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/aws/aws-sdk-go v1.55.7 // indirect
|
||||
github.com/beevik/etree v1.1.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||
github.com/coder/quartz v0.1.2 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/coder/quartz v0.3.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.6.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dennwc/varint v1.0.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/ebitengine/purego v0.8.4 // indirect
|
||||
github.com/ebitengine/purego v0.9.1 // indirect
|
||||
github.com/edsrzf/mmap-go v1.2.0 // indirect
|
||||
github.com/elastic/lunes v0.1.0 // indirect
|
||||
github.com/elastic/lunes v0.2.0 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
|
||||
github.com/expr-lang/expr v1.17.5
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect
|
||||
github.com/expr-lang/expr v1.17.7
|
||||
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/go-faster/city v1.0.1 // indirect
|
||||
github.com/go-faster/errors v0.7.1 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.3 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-openapi/analysis v0.23.0 // indirect
|
||||
github.com/go-openapi/errors v0.22.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/loads v0.22.0 // indirect
|
||||
github.com/go-openapi/spec v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-openapi/validate v0.24.0 // indirect
|
||||
github.com/go-openapi/analysis v0.24.2 // indirect
|
||||
github.com/go-openapi/errors v0.22.6 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.22.4 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.4 // indirect
|
||||
github.com/go-openapi/loads v0.23.2 // indirect
|
||||
github.com/go-openapi/spec v0.22.3 // indirect
|
||||
github.com/go-openapi/swag v0.25.4 // indirect
|
||||
github.com/go-openapi/validate v0.25.1 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/gofrs/uuid v4.4.0+incompatible // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/gojek/valkyrie v0.0.0-20180215180059-6aee720afcdf // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
@@ -178,22 +207,22 @@ require (
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/cel-go v0.26.1 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.2 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.16.0 // indirect
|
||||
github.com/gopherjs/gopherjs v1.17.2 // indirect
|
||||
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
|
||||
github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-msgpack/v2 v2.1.1 // indirect
|
||||
github.com/hashicorp/go-msgpack/v2 v2.1.5 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-sockaddr v1.0.7 // indirect
|
||||
github.com/hashicorp/go-version v1.7.0 // indirect
|
||||
github.com/hashicorp/go-version v1.8.0 // indirect
|
||||
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/hashicorp/memberlist v0.5.1 // indirect
|
||||
github.com/hashicorp/memberlist v0.5.4 // indirect
|
||||
github.com/huandu/xstrings v1.4.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
@@ -201,26 +230,25 @@ require (
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/jessevdk/go-flags v1.6.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/jonboulle/clockwork v0.5.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/jpillora/backoff v1.0.0 // indirect
|
||||
github.com/jtolds/gls v4.20.0+incompatible // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/compress v1.18.3 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/leodido/go-syslog/v4 v4.2.0 // indirect
|
||||
github.com/leodido/go-syslog/v4 v4.3.0 // indirect
|
||||
github.com/leodido/ragel-machinery v0.0.0-20190525184631-5f46317e436b // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect
|
||||
github.com/magefile/mage v1.15.0 // indirect
|
||||
github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mdlayher/socket v0.4.1 // indirect
|
||||
github.com/mdlayher/socket v0.5.1 // indirect
|
||||
github.com/mdlayher/vsock v1.2.1 // indirect
|
||||
github.com/mfridman/interpolate v0.0.2 // indirect
|
||||
github.com/miekg/dns v1.1.65 // indirect
|
||||
github.com/miekg/dns v1.1.72 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
@@ -229,27 +257,27 @@ require (
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||
github.com/natefinch/wrap v0.2.0 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/oklog/run v1.2.0 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/oklog/ulid/v2 v2.1.1
|
||||
github.com/open-feature/go-sdk v1.17.0
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.128.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.128.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.128.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.128.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.144.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.145.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.145.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.145.0 // indirect
|
||||
github.com/openfga/openfga v1.10.1
|
||||
github.com/paulmach/orb v0.11.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.22 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.23 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||
github.com/pressly/goose/v3 v3.25.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/exporter-toolkit v0.14.0 // indirect
|
||||
github.com/prometheus/otlptranslator v0.0.0-20250320144820-d800c8b0eb07 // indirect
|
||||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/prometheus/sigv4 v0.1.2 // indirect
|
||||
github.com/prometheus/exporter-toolkit v0.15.1 // indirect
|
||||
github.com/prometheus/otlptranslator v1.0.0 // indirect
|
||||
github.com/prometheus/procfs v0.19.2 // indirect
|
||||
github.com/prometheus/sigv4 v0.4.1 // indirect
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
|
||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||
github.com/sagikazarmark/locafero v0.9.0 // indirect
|
||||
@@ -257,7 +285,7 @@ require (
|
||||
github.com/segmentio/asm v1.2.0 // indirect
|
||||
github.com/segmentio/backo-go v1.0.1 // indirect
|
||||
github.com/sethvargo/go-retry v0.3.0 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.25.5 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.25.12 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
|
||||
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 // indirect
|
||||
@@ -272,94 +300,92 @@ require (
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/swaggest/openapi-go v0.2.60
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.15 // indirect
|
||||
github.com/tklauser/numcpus v0.10.0 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.16 // indirect
|
||||
github.com/tklauser/numcpus v0.11.0 // indirect
|
||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
|
||||
github.com/trivago/tgo v1.0.7 // indirect
|
||||
github.com/valyala/fastjson v1.6.4 // indirect
|
||||
github.com/valyala/fastjson v1.6.7 // indirect
|
||||
github.com/vjeantet/grok v1.0.1 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
github.com/zeebo/xxh3 v1.0.2 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.1 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/collector/component v1.34.0 // indirect
|
||||
go.opentelemetry.io/collector/component/componentstatus v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/component/componenttest v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/config/configtelemetry v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap/provider/envprovider v1.34.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap/provider/fileprovider v1.34.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/connector v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/connector/connectortest v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/connector/xconnector v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/consumer v1.34.0 // indirect
|
||||
go.opentelemetry.io/collector/consumer/consumererror v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/consumer/consumertest v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/consumer/xconsumer v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/exporter v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/exporter/exportertest v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/exporter/xexporter v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/extension v1.34.0 // indirect
|
||||
go.opentelemetry.io/collector/extension/extensioncapabilities v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/extension/extensiontest v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/extension/xextension v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/featuregate v1.34.0 // indirect
|
||||
go.opentelemetry.io/collector/internal/fanoutconsumer v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/internal/telemetry v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/pdata/testdata v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/pipeline v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/pipeline/xpipeline v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/processor v1.34.0 // indirect
|
||||
go.opentelemetry.io/collector/processor/processorhelper v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/processor/processortest v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/processor/xprocessor v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/receiver v1.34.0 // indirect
|
||||
go.opentelemetry.io/collector/receiver/receiverhelper v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/receiver/receivertest v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/receiver/xreceiver v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/semconv v0.128.0
|
||||
go.opentelemetry.io/collector/service v0.128.0 // indirect
|
||||
go.opentelemetry.io/collector/service/hostcapabilities v0.128.0 // indirect
|
||||
go.opentelemetry.io/contrib/bridges/otelzap v0.11.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0 // indirect
|
||||
go.opentelemetry.io/contrib/otelconf v0.16.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.58.0
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect
|
||||
go.opentelemetry.io/otel/log v0.12.2 // indirect
|
||||
go.opentelemetry.io/otel/sdk/log v0.12.2 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.38.0
|
||||
go.opentelemetry.io/proto/otlp v1.8.0 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.6 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/collector/component v1.51.0 // indirect
|
||||
go.opentelemetry.io/collector/component/componentstatus v0.145.0 // indirect
|
||||
go.opentelemetry.io/collector/component/componenttest v0.145.0 // indirect
|
||||
go.opentelemetry.io/collector/config/configtelemetry v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap/provider/envprovider v1.50.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap/provider/fileprovider v1.50.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.145.0 // indirect
|
||||
go.opentelemetry.io/collector/connector v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/connector/connectortest v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/connector/xconnector v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/consumer v1.51.0 // indirect
|
||||
go.opentelemetry.io/collector/consumer/consumererror v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/consumer/consumertest v0.145.0 // indirect
|
||||
go.opentelemetry.io/collector/consumer/xconsumer v0.145.0 // indirect
|
||||
go.opentelemetry.io/collector/exporter v1.50.0 // indirect
|
||||
go.opentelemetry.io/collector/exporter/exportertest v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/exporter/xexporter v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/extension v1.50.0 // indirect
|
||||
go.opentelemetry.io/collector/extension/extensioncapabilities v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/extension/extensiontest v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/extension/xextension v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/featuregate v1.51.0 // indirect
|
||||
go.opentelemetry.io/collector/internal/fanoutconsumer v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/internal/telemetry v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.145.0 // indirect
|
||||
go.opentelemetry.io/collector/pdata/testdata v0.145.0 // indirect
|
||||
go.opentelemetry.io/collector/pipeline v1.51.0 // indirect
|
||||
go.opentelemetry.io/collector/pipeline/xpipeline v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/processor v1.51.0 // indirect
|
||||
go.opentelemetry.io/collector/processor/processorhelper v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/processor/processortest v0.145.0 // indirect
|
||||
go.opentelemetry.io/collector/processor/xprocessor v0.145.0 // indirect
|
||||
go.opentelemetry.io/collector/receiver v1.50.0 // indirect
|
||||
go.opentelemetry.io/collector/receiver/receiverhelper v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/receiver/receivertest v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/receiver/xreceiver v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/semconv v0.128.1-0.20250610090210-188191247685
|
||||
go.opentelemetry.io/collector/service v0.144.0 // indirect
|
||||
go.opentelemetry.io/collector/service/hostcapabilities v0.144.0 // indirect
|
||||
go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.65.0 // indirect
|
||||
go.opentelemetry.io/contrib/otelconf v0.18.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.60.0
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/log v0.15.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/log v0.14.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.40.0
|
||||
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/mock v0.6.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/mod v0.30.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
golang.org/x/tools v0.39.0 // indirect
|
||||
gonum.org/v1/gonum v0.16.0 // indirect
|
||||
google.golang.org/api v0.236.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect
|
||||
google.golang.org/grpc v1.75.1 // indirect
|
||||
golang.org/x/mod v0.32.0 // indirect
|
||||
golang.org/x/sys v0.40.0 // indirect
|
||||
golang.org/x/time v0.14.0 // indirect
|
||||
golang.org/x/tools v0.41.0 // indirect
|
||||
gonum.org/v1/gonum v0.17.0 // indirect
|
||||
google.golang.org/api v0.265.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260203192932-546029d2fa20 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect
|
||||
google.golang.org/grpc v1.78.0 // indirect
|
||||
gopkg.in/telebot.v3 v3.3.8 // indirect
|
||||
k8s.io/client-go v0.34.0 // indirect
|
||||
k8s.io/client-go v0.35.0 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
|
||||
sigs.k8s.io/yaml v1.6.0 // indirect
|
||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect
|
||||
)
|
||||
|
||||
replace github.com/expr-lang/expr => github.com/SigNoz/expr v1.17.7-beta
|
||||
|
||||
@@ -95,7 +95,7 @@ func (d *Dispatcher) Run() {
|
||||
d.ctx, d.cancel = context.WithCancel(context.Background())
|
||||
d.mtx.Unlock()
|
||||
|
||||
d.run(d.alerts.Subscribe())
|
||||
d.run(d.alerts.Subscribe(fmt.Sprintf("dispatcher-%s", d.orgID)))
|
||||
close(d.done)
|
||||
}
|
||||
|
||||
@@ -107,14 +107,15 @@ func (d *Dispatcher) run(it provider.AlertIterator) {
|
||||
|
||||
for {
|
||||
select {
|
||||
case alert, ok := <-it.Next():
|
||||
if !ok {
|
||||
case alertWrapper, ok := <-it.Next():
|
||||
if !ok || alertWrapper == nil {
|
||||
// Iterator exhausted for some reason.
|
||||
if err := it.Err(); err != nil {
|
||||
d.logger.ErrorContext(d.ctx, "Error on alert update", "err", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
alert := alertWrapper.Data
|
||||
|
||||
d.logger.DebugContext(d.ctx, "SigNoz Custom Dispatcher: Received alert", "alert", alert)
|
||||
|
||||
|
||||
@@ -365,7 +365,7 @@ route:
|
||||
logger := providerSettings.Logger
|
||||
route := dispatch.NewRoute(conf.Route, nil)
|
||||
marker := alertmanagertypes.NewMarker(prometheus.NewRegistry())
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Hour, nil, logger, nil)
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Hour, 0, nil, logger, prometheus.NewRegistry(), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -496,7 +496,7 @@ route:
|
||||
err := nfManager.SetNotificationConfig(orgId, ruleID, &config)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
err = alerts.Put(inputAlerts...)
|
||||
err = alerts.Put(ctx, inputAlerts...)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -638,7 +638,7 @@ route:
|
||||
logger := providerSettings.Logger
|
||||
route := dispatch.NewRoute(conf.Route, nil)
|
||||
marker := alertmanagertypes.NewMarker(prometheus.NewRegistry())
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Hour, nil, logger, nil)
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Hour, 0, nil, logger, prometheus.NewRegistry(), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -798,7 +798,7 @@ route:
|
||||
err := nfManager.SetNotificationConfig(orgId, ruleID, &config)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
err = alerts.Put(inputAlerts...)
|
||||
err = alerts.Put(ctx, inputAlerts...)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -897,7 +897,7 @@ route:
|
||||
logger := providerSettings.Logger
|
||||
route := dispatch.NewRoute(conf.Route, nil)
|
||||
marker := alertmanagertypes.NewMarker(prometheus.NewRegistry())
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Hour, nil, logger, nil)
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Hour, 0, nil, logger, prometheus.NewRegistry(), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1028,7 +1028,7 @@ route:
|
||||
err := nfManager.SetNotificationConfig(orgId, ruleID, &config)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
err = alerts.Put(inputAlerts...)
|
||||
err = alerts.Put(ctx, inputAlerts...)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1159,7 +1159,7 @@ func newAlert(labels model.LabelSet) *alertmanagertypes.Alert {
|
||||
func TestDispatcherRace(t *testing.T) {
|
||||
logger := promslog.NewNopLogger()
|
||||
marker := alertmanagertypes.NewMarker(prometheus.NewRegistry())
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Hour, nil, logger, nil)
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Hour, 0, nil, logger, prometheus.NewRegistry(), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1175,6 +1175,7 @@ func TestDispatcherRace(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDispatcherRaceOnFirstAlertNotDeliveredWhenGroupWaitIsZero(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
const numAlerts = 5000
|
||||
confData := `receivers:
|
||||
- name: 'slack'
|
||||
@@ -1194,7 +1195,7 @@ route:
|
||||
providerSettings := createTestProviderSettings()
|
||||
logger := providerSettings.Logger
|
||||
marker := alertmanagertypes.NewMarker(prometheus.NewRegistry())
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Hour, nil, logger, nil)
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Hour, 0, nil, logger, prometheus.NewRegistry(), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1247,7 +1248,7 @@ route:
|
||||
for i := 0; i < numAlerts; i++ {
|
||||
ruleId := fmt.Sprintf("Alert_%d", i)
|
||||
alert := newAlert(model.LabelSet{"ruleId": model.LabelValue(ruleId)})
|
||||
require.NoError(t, alerts.Put(alert))
|
||||
require.NoError(t, alerts.Put(ctx, alert))
|
||||
}
|
||||
|
||||
for deadline := time.Now().Add(5 * time.Second); time.Now().Before(deadline); {
|
||||
@@ -1265,7 +1266,7 @@ func TestDispatcher_DoMaintenance(t *testing.T) {
|
||||
r := prometheus.NewRegistry()
|
||||
marker := alertmanagertypes.NewMarker(r)
|
||||
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Minute, nil, promslog.NewNopLogger(), nil)
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Minute, 0, nil, promslog.NewNopLogger(), prometheus.NewRegistry(), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1370,7 +1371,7 @@ route:
|
||||
logger := providerSettings.Logger
|
||||
route := dispatch.NewRoute(conf.Route, nil)
|
||||
marker := alertmanagertypes.NewMarker(prometheus.NewRegistry())
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Hour, nil, logger, nil)
|
||||
alerts, err := mem.NewAlerts(context.Background(), marker, time.Hour, 0, nil, logger, prometheus.NewRegistry(), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ func New(ctx context.Context, logger *slog.Logger, registry prometheus.Registere
|
||||
})
|
||||
}()
|
||||
|
||||
server.alerts, err = mem.NewAlerts(ctx, server.marker, server.srvConfig.Alerts.GCInterval, nil, server.logger, signozRegisterer)
|
||||
server.alerts, err = mem.NewAlerts(ctx, server.marker, server.srvConfig.Alerts.GCInterval, 0, nil, server.logger, signozRegisterer, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -203,15 +203,15 @@ func New(ctx context.Context, logger *slog.Logger, registry prometheus.Registere
|
||||
|
||||
func (server *Server) GetAlerts(ctx context.Context, params alertmanagertypes.GettableAlertsParams) (alertmanagertypes.GettableAlerts, error) {
|
||||
return alertmanagertypes.NewGettableAlertsFromAlertProvider(server.alerts, server.alertmanagerConfig, server.marker.Status, func(labels model.LabelSet) {
|
||||
server.inhibitor.Mutes(labels)
|
||||
server.silencer.Mutes(labels)
|
||||
server.inhibitor.Mutes(ctx, labels)
|
||||
server.silencer.Mutes(ctx, labels)
|
||||
}, params)
|
||||
}
|
||||
|
||||
func (server *Server) PutAlerts(ctx context.Context, postableAlerts alertmanagertypes.PostableAlerts) error {
|
||||
alerts, err := alertmanagertypes.NewAlertsFromPostableAlerts(postableAlerts, time.Duration(server.srvConfig.Global.ResolveTimeout), time.Now())
|
||||
alerts, err := alertmanagertypes.NewAlertsFromPostableAlerts(postableAlerts, time.Duration(server.srvConfig.Global.ResolveTimeout), time.Now(), ctx)
|
||||
// Notification sending alert takes precedence over validation errors.
|
||||
if err := server.alerts.Put(alerts...); err != nil {
|
||||
if err := server.alerts.Put(ctx, alerts...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -343,6 +343,7 @@ func (server *Server) TestAlert(ctx context.Context, receiversMap map[*alertmana
|
||||
postableAlerts,
|
||||
time.Duration(server.srvConfig.Global.ResolveTimeout),
|
||||
time.Now(),
|
||||
ctx,
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput,
|
||||
|
||||
@@ -70,7 +70,7 @@ func TestServerTestReceiverTypeWebhook(t *testing.T) {
|
||||
WebhookConfigs: []*config.WebhookConfig{
|
||||
{
|
||||
HTTPConfig: &commoncfg.HTTPClientConfig{},
|
||||
URL: &config.SecretURL{URL: webhookURL},
|
||||
URL: config.SecretTemplateURL(webhookURL.String()),
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -96,7 +96,7 @@ func TestServerPutAlerts(t *testing.T) {
|
||||
WebhookConfigs: []*config.WebhookConfig{
|
||||
{
|
||||
HTTPConfig: &commoncfg.HTTPClientConfig{},
|
||||
URL: &config.SecretURL{URL: &url.URL{Host: "localhost", Path: "/test-receiver"}},
|
||||
URL: config.SecretTemplateURL("http://localhost/test-receiver"),
|
||||
},
|
||||
},
|
||||
}))
|
||||
@@ -176,7 +176,7 @@ func TestServerTestAlert(t *testing.T) {
|
||||
WebhookConfigs: []*config.WebhookConfig{
|
||||
{
|
||||
HTTPConfig: &commoncfg.HTTPClientConfig{},
|
||||
URL: &config.SecretURL{URL: webhook1URL},
|
||||
URL: config.SecretTemplateURL(webhook1URL.String()),
|
||||
},
|
||||
},
|
||||
}))
|
||||
@@ -186,7 +186,7 @@ func TestServerTestAlert(t *testing.T) {
|
||||
WebhookConfigs: []*config.WebhookConfig{
|
||||
{
|
||||
HTTPConfig: &commoncfg.HTTPClientConfig{},
|
||||
URL: &config.SecretURL{URL: webhook2URL},
|
||||
URL: config.SecretTemplateURL(webhook2URL.String()),
|
||||
},
|
||||
},
|
||||
}))
|
||||
@@ -268,7 +268,7 @@ func TestServerTestAlertContinuesOnFailure(t *testing.T) {
|
||||
WebhookConfigs: []*config.WebhookConfig{
|
||||
{
|
||||
HTTPConfig: &commoncfg.HTTPClientConfig{},
|
||||
URL: &config.SecretURL{URL: webhookURL},
|
||||
URL: config.SecretTemplateURL(webhookURL.String()),
|
||||
},
|
||||
},
|
||||
}))
|
||||
@@ -278,7 +278,7 @@ func TestServerTestAlertContinuesOnFailure(t *testing.T) {
|
||||
WebhookConfigs: []*config.WebhookConfig{
|
||||
{
|
||||
HTTPConfig: &commoncfg.HTTPClientConfig{},
|
||||
URL: &config.SecretURL{URL: &url.URL{Scheme: "http", Host: "localhost:1", Path: "/webhook"}},
|
||||
URL: config.SecretTemplateURL("http://localhost:1/webhook"),
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/modules/organization"
|
||||
"github.com/SigNoz/signoz/pkg/modules/preference"
|
||||
"github.com/SigNoz/signoz/pkg/modules/promote"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rulestatehistory"
|
||||
"github.com/SigNoz/signoz/pkg/modules/serviceaccount"
|
||||
"github.com/SigNoz/signoz/pkg/modules/session"
|
||||
"github.com/SigNoz/signoz/pkg/modules/user"
|
||||
@@ -30,28 +29,27 @@ import (
|
||||
)
|
||||
|
||||
type provider struct {
|
||||
config apiserver.Config
|
||||
settings factory.ScopedProviderSettings
|
||||
router *mux.Router
|
||||
authZ *middleware.AuthZ
|
||||
orgHandler organization.Handler
|
||||
userHandler user.Handler
|
||||
sessionHandler session.Handler
|
||||
authDomainHandler authdomain.Handler
|
||||
preferenceHandler preference.Handler
|
||||
globalHandler global.Handler
|
||||
promoteHandler promote.Handler
|
||||
flaggerHandler flagger.Handler
|
||||
dashboardModule dashboard.Module
|
||||
dashboardHandler dashboard.Handler
|
||||
metricsExplorerHandler metricsexplorer.Handler
|
||||
gatewayHandler gateway.Handler
|
||||
fieldsHandler fields.Handler
|
||||
authzHandler authz.Handler
|
||||
zeusHandler zeus.Handler
|
||||
querierHandler querier.Handler
|
||||
serviceAccountHandler serviceaccount.Handler
|
||||
ruleStateHistoryHandler rulestatehistory.Handler
|
||||
config apiserver.Config
|
||||
settings factory.ScopedProviderSettings
|
||||
router *mux.Router
|
||||
authZ *middleware.AuthZ
|
||||
orgHandler organization.Handler
|
||||
userHandler user.Handler
|
||||
sessionHandler session.Handler
|
||||
authDomainHandler authdomain.Handler
|
||||
preferenceHandler preference.Handler
|
||||
globalHandler global.Handler
|
||||
promoteHandler promote.Handler
|
||||
flaggerHandler flagger.Handler
|
||||
dashboardModule dashboard.Module
|
||||
dashboardHandler dashboard.Handler
|
||||
metricsExplorerHandler metricsexplorer.Handler
|
||||
gatewayHandler gateway.Handler
|
||||
fieldsHandler fields.Handler
|
||||
authzHandler authz.Handler
|
||||
zeusHandler zeus.Handler
|
||||
querierHandler querier.Handler
|
||||
serviceAccountHandler serviceaccount.Handler
|
||||
}
|
||||
|
||||
func NewFactory(
|
||||
@@ -74,7 +72,6 @@ func NewFactory(
|
||||
zeusHandler zeus.Handler,
|
||||
querierHandler querier.Handler,
|
||||
serviceAccountHandler serviceaccount.Handler,
|
||||
ruleStateHistoryHandler rulestatehistory.Handler,
|
||||
) factory.ProviderFactory[apiserver.APIServer, apiserver.Config] {
|
||||
return factory.NewProviderFactory(factory.MustNewName("signoz"), func(ctx context.Context, providerSettings factory.ProviderSettings, config apiserver.Config) (apiserver.APIServer, error) {
|
||||
return newProvider(
|
||||
@@ -100,7 +97,6 @@ func NewFactory(
|
||||
zeusHandler,
|
||||
querierHandler,
|
||||
serviceAccountHandler,
|
||||
ruleStateHistoryHandler,
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -128,33 +124,31 @@ func newProvider(
|
||||
zeusHandler zeus.Handler,
|
||||
querierHandler querier.Handler,
|
||||
serviceAccountHandler serviceaccount.Handler,
|
||||
ruleStateHistoryHandler rulestatehistory.Handler,
|
||||
) (apiserver.APIServer, error) {
|
||||
settings := factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/pkg/apiserver/signozapiserver")
|
||||
router := mux.NewRouter().UseEncodedPath()
|
||||
|
||||
provider := &provider{
|
||||
config: config,
|
||||
settings: settings,
|
||||
router: router,
|
||||
orgHandler: orgHandler,
|
||||
userHandler: userHandler,
|
||||
sessionHandler: sessionHandler,
|
||||
authDomainHandler: authDomainHandler,
|
||||
preferenceHandler: preferenceHandler,
|
||||
globalHandler: globalHandler,
|
||||
promoteHandler: promoteHandler,
|
||||
flaggerHandler: flaggerHandler,
|
||||
dashboardModule: dashboardModule,
|
||||
dashboardHandler: dashboardHandler,
|
||||
metricsExplorerHandler: metricsExplorerHandler,
|
||||
gatewayHandler: gatewayHandler,
|
||||
fieldsHandler: fieldsHandler,
|
||||
authzHandler: authzHandler,
|
||||
zeusHandler: zeusHandler,
|
||||
querierHandler: querierHandler,
|
||||
serviceAccountHandler: serviceAccountHandler,
|
||||
ruleStateHistoryHandler: ruleStateHistoryHandler,
|
||||
config: config,
|
||||
settings: settings,
|
||||
router: router,
|
||||
orgHandler: orgHandler,
|
||||
userHandler: userHandler,
|
||||
sessionHandler: sessionHandler,
|
||||
authDomainHandler: authDomainHandler,
|
||||
preferenceHandler: preferenceHandler,
|
||||
globalHandler: globalHandler,
|
||||
promoteHandler: promoteHandler,
|
||||
flaggerHandler: flaggerHandler,
|
||||
dashboardModule: dashboardModule,
|
||||
dashboardHandler: dashboardHandler,
|
||||
metricsExplorerHandler: metricsExplorerHandler,
|
||||
gatewayHandler: gatewayHandler,
|
||||
fieldsHandler: fieldsHandler,
|
||||
authzHandler: authzHandler,
|
||||
zeusHandler: zeusHandler,
|
||||
querierHandler: querierHandler,
|
||||
serviceAccountHandler: serviceAccountHandler,
|
||||
}
|
||||
|
||||
provider.authZ = middleware.NewAuthZ(settings.Logger(), orgGetter, authz)
|
||||
@@ -239,10 +233,6 @@ func (provider *provider) AddToRouter(router *mux.Router) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := provider.addRuleStateHistoryRoutes(router); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
package signozapiserver
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/http/handler"
|
||||
"github.com/SigNoz/signoz/pkg/types"
|
||||
"github.com/SigNoz/signoz/pkg/types/rulestatehistorytypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func (provider *provider) addRuleStateHistoryRoutes(router *mux.Router) error {
|
||||
|
||||
if err := router.Handle("/api/v2/rules/{id}/history/stats", handler.New(
|
||||
provider.authZ.ViewAccess(provider.ruleStateHistoryHandler.GetRuleHistoryStats),
|
||||
handler.OpenAPIDef{
|
||||
ID: "GetRuleHistoryStats",
|
||||
Tags: []string{"rules"},
|
||||
Summary: "Get rule history stats",
|
||||
Description: "Returns trigger and resolution statistics for a rule in the selected time range.",
|
||||
RequestQuery: new(rulestatehistorytypes.V2HistoryBaseQueryParams),
|
||||
Response: new(rulestatehistorytypes.Stats),
|
||||
ResponseContentType: "application/json",
|
||||
SuccessStatusCode: http.StatusOK,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusInternalServerError},
|
||||
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
|
||||
})).Methods(http.MethodGet).GetError(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := router.Handle("/api/v2/rules/{id}/history/timeline", handler.New(
|
||||
provider.authZ.ViewAccess(provider.ruleStateHistoryHandler.GetRuleHistoryTimeline),
|
||||
handler.OpenAPIDef{
|
||||
ID: "GetRuleHistoryTimeline",
|
||||
Tags: []string{"rules"},
|
||||
Summary: "Get rule history timeline",
|
||||
Description: "Returns paginated timeline entries for rule state transitions.",
|
||||
RequestQuery: new(rulestatehistorytypes.V2HistoryTimelineQueryParams),
|
||||
Response: new(rulestatehistorytypes.RuleStateTimelineResponse),
|
||||
ResponseContentType: "application/json",
|
||||
SuccessStatusCode: http.StatusOK,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusInternalServerError},
|
||||
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
|
||||
})).Methods(http.MethodGet).GetError(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := router.Handle("/api/v2/rules/{id}/history/top_contributors", handler.New(
|
||||
provider.authZ.ViewAccess(provider.ruleStateHistoryHandler.GetRuleHistoryContributors),
|
||||
handler.OpenAPIDef{
|
||||
ID: "GetRuleHistoryTopContributors",
|
||||
Tags: []string{"rules"},
|
||||
Summary: "Get top contributors to rule firing",
|
||||
Description: "Returns top label combinations contributing to rule firing in the selected time range.",
|
||||
RequestQuery: new(rulestatehistorytypes.V2HistoryBaseQueryParams),
|
||||
Response: new([]rulestatehistorytypes.RuleStateHistoryContributorResponse),
|
||||
ResponseContentType: "application/json",
|
||||
SuccessStatusCode: http.StatusOK,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusInternalServerError},
|
||||
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
|
||||
})).Methods(http.MethodGet).GetError(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := router.Handle("/api/v2/rules/{id}/history/filter_keys", handler.New(
|
||||
provider.authZ.ViewAccess(provider.ruleStateHistoryHandler.GetRuleHistoryFilterKeys),
|
||||
handler.OpenAPIDef{
|
||||
ID: "GetRuleHistoryFilterKeys",
|
||||
Tags: []string{"rules"},
|
||||
Summary: "Get rule history filter keys",
|
||||
Description: "Returns distinct label keys from rule history entries for the selected range.",
|
||||
RequestQuery: new(telemetrytypes.PostableFieldKeysParams),
|
||||
Response: new(telemetrytypes.GettableFieldKeys),
|
||||
ResponseContentType: "application/json",
|
||||
SuccessStatusCode: http.StatusOK,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusInternalServerError},
|
||||
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
|
||||
})).Methods(http.MethodGet).GetError(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := router.Handle("/api/v2/rules/{id}/history/filter_values", handler.New(
|
||||
provider.authZ.ViewAccess(provider.ruleStateHistoryHandler.GetRuleHistoryFilterValues),
|
||||
handler.OpenAPIDef{
|
||||
ID: "GetRuleHistoryFilterValues",
|
||||
Tags: []string{"rules"},
|
||||
Summary: "Get rule history filter values",
|
||||
Description: "Returns distinct label values for a given key from rule history entries.",
|
||||
RequestQuery: new(telemetrytypes.PostableFieldValueParams),
|
||||
Response: new(telemetrytypes.GettableFieldValues),
|
||||
ResponseContentType: "application/json",
|
||||
SuccessStatusCode: http.StatusOK,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusInternalServerError},
|
||||
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
|
||||
})).Methods(http.MethodGet).GetError(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := router.Handle("/api/v2/rules/{id}/history/overall_status", handler.New(
|
||||
provider.authZ.ViewAccess(provider.ruleStateHistoryHandler.GetRuleHistoryOverallStatus),
|
||||
handler.OpenAPIDef{
|
||||
ID: "GetRuleHistoryOverallStatus",
|
||||
Tags: []string{"rules"},
|
||||
Summary: "Get rule overall status timeline",
|
||||
Description: "Returns overall firing/inactive intervals for a rule in the selected time range.",
|
||||
RequestQuery: new(rulestatehistorytypes.V2HistoryBaseQueryParams),
|
||||
Response: new([]rulestatehistorytypes.RuleStateWindow),
|
||||
ResponseContentType: "application/json",
|
||||
SuccessStatusCode: http.StatusOK,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusInternalServerError},
|
||||
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
|
||||
})).Methods(http.MethodGet).GetError(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
sdkmetric "go.opentelemetry.io/otel/metric"
|
||||
sdkmetricnoop "go.opentelemetry.io/otel/metric/noop"
|
||||
sdkresource "go.opentelemetry.io/otel/sdk/resource"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.39.0"
|
||||
sdktrace "go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
package implrulestatehistory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/querybuilder"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
"github.com/huandu/go-sqlbuilder"
|
||||
)
|
||||
|
||||
type conditionBuilder struct {
|
||||
fm qbtypes.FieldMapper
|
||||
}
|
||||
|
||||
func newConditionBuilder(fm qbtypes.FieldMapper) qbtypes.ConditionBuilder {
|
||||
return &conditionBuilder{fm: fm}
|
||||
}
|
||||
|
||||
func (c *conditionBuilder) ConditionFor(
|
||||
ctx context.Context,
|
||||
key *telemetrytypes.TelemetryFieldKey,
|
||||
operator qbtypes.FilterOperator,
|
||||
value any,
|
||||
sb *sqlbuilder.SelectBuilder,
|
||||
_ uint64,
|
||||
_ uint64,
|
||||
) (string, error) {
|
||||
if operator.IsStringSearchOperator() {
|
||||
value = querybuilder.FormatValueForContains(value)
|
||||
}
|
||||
|
||||
fieldName, err := c.fm.FieldFor(ctx, key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
switch operator {
|
||||
case qbtypes.FilterOperatorEqual:
|
||||
return sb.E(fieldName, value), nil
|
||||
case qbtypes.FilterOperatorNotEqual:
|
||||
return sb.NE(fieldName, value), nil
|
||||
case qbtypes.FilterOperatorGreaterThan:
|
||||
return sb.G(fieldName, value), nil
|
||||
case qbtypes.FilterOperatorGreaterThanOrEq:
|
||||
return sb.GE(fieldName, value), nil
|
||||
case qbtypes.FilterOperatorLessThan:
|
||||
return sb.LT(fieldName, value), nil
|
||||
case qbtypes.FilterOperatorLessThanOrEq:
|
||||
return sb.LE(fieldName, value), nil
|
||||
case qbtypes.FilterOperatorLike:
|
||||
return sb.Like(fieldName, value), nil
|
||||
case qbtypes.FilterOperatorNotLike:
|
||||
return sb.NotLike(fieldName, value), nil
|
||||
case qbtypes.FilterOperatorILike:
|
||||
return sb.ILike(fieldName, value), nil
|
||||
case qbtypes.FilterOperatorNotILike:
|
||||
return sb.NotILike(fieldName, value), nil
|
||||
case qbtypes.FilterOperatorContains:
|
||||
return sb.ILike(fieldName, fmt.Sprintf("%%%s%%", value)), nil
|
||||
case qbtypes.FilterOperatorNotContains:
|
||||
return sb.NotILike(fieldName, fmt.Sprintf("%%%s%%", value)), nil
|
||||
case qbtypes.FilterOperatorRegexp:
|
||||
return fmt.Sprintf(`match(%s, %s)`, sqlbuilder.Escape(fieldName), sb.Var(value)), nil
|
||||
case qbtypes.FilterOperatorNotRegexp:
|
||||
return fmt.Sprintf(`NOT match(%s, %s)`, sqlbuilder.Escape(fieldName), sb.Var(value)), nil
|
||||
case qbtypes.FilterOperatorBetween:
|
||||
values, ok := value.([]any)
|
||||
if !ok || len(values) != 2 {
|
||||
return "", qbtypes.ErrBetweenValues
|
||||
}
|
||||
return sb.Between(fieldName, values[0], values[1]), nil
|
||||
case qbtypes.FilterOperatorNotBetween:
|
||||
values, ok := value.([]any)
|
||||
if !ok || len(values) != 2 {
|
||||
return "", qbtypes.ErrBetweenValues
|
||||
}
|
||||
return sb.NotBetween(fieldName, values[0], values[1]), nil
|
||||
case qbtypes.FilterOperatorIn:
|
||||
values, ok := value.([]any)
|
||||
if !ok {
|
||||
return "", qbtypes.ErrInValues
|
||||
}
|
||||
return sb.In(fieldName, values), nil
|
||||
case qbtypes.FilterOperatorNotIn:
|
||||
values, ok := value.([]any)
|
||||
if !ok {
|
||||
return "", qbtypes.ErrInValues
|
||||
}
|
||||
return sb.NotIn(fieldName, values), nil
|
||||
case qbtypes.FilterOperatorExists, qbtypes.FilterOperatorNotExists:
|
||||
intrinsic := []string{"rule_id", "rule_name", "overall_state", "overall_state_changed", "state", "state_changed", "unix_milli", "fingerprint", "value"}
|
||||
if slices.Contains(intrinsic, key.Name) {
|
||||
return "true", nil
|
||||
}
|
||||
if operator == qbtypes.FilterOperatorExists {
|
||||
return fmt.Sprintf("has(JSONExtractKeys(labels), %s)", sb.Var(key.Name)), nil
|
||||
}
|
||||
return fmt.Sprintf("not has(JSONExtractKeys(labels), %s)", sb.Var(key.Name)), nil
|
||||
}
|
||||
|
||||
return "", errors.NewInvalidInputf(errors.CodeInvalidInput, "unsupported operator: %v", operator)
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package implrulestatehistory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
schema "github.com/SigNoz/signoz-otel-collector/cmd/signozschemamigrator/schema_migrator"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
"github.com/huandu/go-sqlbuilder"
|
||||
)
|
||||
|
||||
var ruleStateHistoryColumns = map[string]*schema.Column{
|
||||
"rule_id": {Name: "rule_id", Type: schema.ColumnTypeString},
|
||||
"rule_name": {Name: "rule_name", Type: schema.ColumnTypeString},
|
||||
"overall_state": {Name: "overall_state", Type: schema.ColumnTypeString},
|
||||
"overall_state_changed": {Name: "overall_state_changed", Type: schema.ColumnTypeBool},
|
||||
"state": {Name: "state", Type: schema.ColumnTypeString},
|
||||
"state_changed": {Name: "state_changed", Type: schema.ColumnTypeBool},
|
||||
"unix_milli": {Name: "unix_milli", Type: schema.ColumnTypeInt64},
|
||||
"labels": {Name: "labels", Type: schema.ColumnTypeString},
|
||||
"fingerprint": {Name: "fingerprint", Type: schema.ColumnTypeUInt64},
|
||||
"value": {Name: "value", Type: schema.ColumnTypeFloat64},
|
||||
}
|
||||
|
||||
type fieldMapper struct{}
|
||||
|
||||
func newFieldMapper() qbtypes.FieldMapper {
|
||||
return &fieldMapper{}
|
||||
}
|
||||
|
||||
func (m *fieldMapper) getColumn(_ context.Context, key *telemetrytypes.TelemetryFieldKey) (*schema.Column, error) {
|
||||
name := strings.TrimSpace(key.Name)
|
||||
if col, ok := ruleStateHistoryColumns[name]; ok {
|
||||
return col, nil
|
||||
}
|
||||
return ruleStateHistoryColumns["labels"], nil
|
||||
}
|
||||
|
||||
func (m *fieldMapper) FieldFor(ctx context.Context, key *telemetrytypes.TelemetryFieldKey) (string, error) {
|
||||
col, err := m.getColumn(ctx, key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if col.Name == "labels" && key.Name != "labels" {
|
||||
return fmt.Sprintf("JSONExtractString(labels, '%s')", strings.ReplaceAll(key.Name, "'", "\\'")), nil
|
||||
}
|
||||
return col.Name, nil
|
||||
}
|
||||
|
||||
func (m *fieldMapper) ColumnFor(ctx context.Context, key *telemetrytypes.TelemetryFieldKey) (*schema.Column, error) {
|
||||
return m.getColumn(ctx, key)
|
||||
}
|
||||
|
||||
func (m *fieldMapper) ColumnExpressionFor(ctx context.Context, field *telemetrytypes.TelemetryFieldKey, _ map[string][]*telemetrytypes.TelemetryFieldKey) (string, error) {
|
||||
colName, err := m.FieldFor(ctx, field)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("%s AS `%s`", sqlbuilder.Escape(colName), field.Name), nil
|
||||
}
|
||||
@@ -1,351 +0,0 @@
|
||||
package implrulestatehistory
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/http/binding"
|
||||
"github.com/SigNoz/signoz/pkg/http/render"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rulestatehistory"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/types/rulestatehistorytypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
type handler struct {
|
||||
module rulestatehistory.Module
|
||||
}
|
||||
|
||||
type ruleHistoryRequest struct {
|
||||
Query rulestatehistorytypes.Query
|
||||
Cursor string
|
||||
}
|
||||
|
||||
type cursorToken struct {
|
||||
Offset int64 `json:"offset"`
|
||||
Limit int64 `json:"limit"`
|
||||
}
|
||||
|
||||
func NewHandler(module rulestatehistory.Module) rulestatehistory.Handler {
|
||||
return &handler{module: module}
|
||||
}
|
||||
|
||||
func (h *handler) GetRuleHistoryStats(w http.ResponseWriter, r *http.Request) {
|
||||
ruleID := mux.Vars(r)["id"]
|
||||
req, ok := h.parseV2BaseQueryRequest(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
stats, err := h.module.GetHistoryStats(r.Context(), ruleID, req.Query)
|
||||
if err != nil {
|
||||
render.Error(w, err)
|
||||
return
|
||||
}
|
||||
render.Success(w, http.StatusOK, stats)
|
||||
}
|
||||
|
||||
func (h *handler) GetRuleHistoryOverallStatus(w http.ResponseWriter, r *http.Request) {
|
||||
ruleID := mux.Vars(r)["id"]
|
||||
req, ok := h.parseV2BaseQueryRequest(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
res, err := h.module.GetHistoryOverallStatus(r.Context(), ruleID, req.Query)
|
||||
if err != nil {
|
||||
render.Error(w, err)
|
||||
return
|
||||
}
|
||||
render.Success(w, http.StatusOK, res)
|
||||
}
|
||||
|
||||
func (h *handler) GetRuleHistoryTimeline(w http.ResponseWriter, r *http.Request) {
|
||||
ruleID := mux.Vars(r)["id"]
|
||||
req, ok := h.parseV2TimelineQueryRequest(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if req.Cursor != "" {
|
||||
token, err := decodeCursor(req.Cursor)
|
||||
if err != nil {
|
||||
render.Error(w, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "invalid cursor"))
|
||||
return
|
||||
}
|
||||
req.Query.Offset = token.Offset
|
||||
if req.Query.Limit == 0 {
|
||||
req.Query.Limit = token.Limit
|
||||
}
|
||||
}
|
||||
if req.Query.Limit == 0 {
|
||||
req.Query.Limit = 50
|
||||
}
|
||||
|
||||
timelineItems, timelineTotal, err := h.module.GetHistoryTimeline(r.Context(), ruleID, req.Query)
|
||||
if err != nil {
|
||||
render.Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
resp := rulestatehistorytypes.RuleStateTimelineResponse{}
|
||||
resp.Items = make([]rulestatehistorytypes.RuleStateHistoryResponseItem, 0, len(timelineItems))
|
||||
for _, item := range timelineItems {
|
||||
resp.Items = append(resp.Items, rulestatehistorytypes.RuleStateHistoryResponseItem{
|
||||
RuleID: item.RuleID,
|
||||
RuleName: item.RuleName,
|
||||
OverallState: item.OverallState,
|
||||
OverallStateChanged: item.OverallStateChanged,
|
||||
State: item.State,
|
||||
StateChanged: item.StateChanged,
|
||||
UnixMilli: item.UnixMilli,
|
||||
Labels: toQBLabels(item.Labels),
|
||||
Fingerprint: item.Fingerprint,
|
||||
Value: item.Value,
|
||||
})
|
||||
}
|
||||
resp.Total = timelineTotal
|
||||
if req.Query.Limit > 0 && req.Query.Offset+int64(len(timelineItems)) < int64(timelineTotal) {
|
||||
nextOffset := req.Query.Offset + int64(len(timelineItems))
|
||||
nextCursor, err := encodeCursor(cursorToken{Offset: nextOffset, Limit: req.Query.Limit})
|
||||
if err != nil {
|
||||
render.Error(w, err)
|
||||
return
|
||||
}
|
||||
resp.NextCursor = nextCursor
|
||||
}
|
||||
render.Success(w, http.StatusOK, resp)
|
||||
}
|
||||
|
||||
func (h *handler) GetRuleHistoryContributors(w http.ResponseWriter, r *http.Request) {
|
||||
ruleID := mux.Vars(r)["id"]
|
||||
req, ok := h.parseV2BaseQueryRequest(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
res, err := h.module.GetHistoryContributors(r.Context(), ruleID, req.Query)
|
||||
if err != nil {
|
||||
render.Error(w, err)
|
||||
return
|
||||
}
|
||||
converted := make([]rulestatehistorytypes.RuleStateHistoryContributorResponse, 0, len(res))
|
||||
for _, item := range res {
|
||||
converted = append(converted, rulestatehistorytypes.RuleStateHistoryContributorResponse{
|
||||
Fingerprint: item.Fingerprint,
|
||||
Labels: toQBLabels(item.Labels),
|
||||
Count: item.Count,
|
||||
RelatedTracesLink: item.RelatedTracesLink,
|
||||
RelatedLogsLink: item.RelatedLogsLink,
|
||||
})
|
||||
}
|
||||
render.Success(w, http.StatusOK, converted)
|
||||
}
|
||||
|
||||
func (h *handler) GetRuleHistoryFilterKeys(w http.ResponseWriter, r *http.Request) {
|
||||
ruleID := mux.Vars(r)["id"]
|
||||
query, search, limit, ok := h.parseV2FilterKeysRequest(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
res, err := h.module.GetHistoryFilterKeys(r.Context(), ruleID, query, search, limit)
|
||||
if err != nil {
|
||||
render.Error(w, err)
|
||||
return
|
||||
}
|
||||
render.Success(w, http.StatusOK, res)
|
||||
}
|
||||
|
||||
func (h *handler) GetRuleHistoryFilterValues(w http.ResponseWriter, r *http.Request) {
|
||||
ruleID := mux.Vars(r)["id"]
|
||||
query, key, search, limit, ok := h.parseV2FilterValuesRequest(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
res, err := h.module.GetHistoryFilterValues(r.Context(), ruleID, key, query, search, limit)
|
||||
if err != nil {
|
||||
render.Error(w, err)
|
||||
return
|
||||
}
|
||||
render.Success(w, http.StatusOK, res)
|
||||
}
|
||||
|
||||
func (h *handler) parseV2BaseQueryRequest(w http.ResponseWriter, r *http.Request) (*ruleHistoryRequest, bool) {
|
||||
req, err := parseV2BaseQueryFromURL(r)
|
||||
if err != nil {
|
||||
render.Error(w, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "invalid query parameters"))
|
||||
return nil, false
|
||||
}
|
||||
if req.Query.Start == 0 || req.Query.End == 0 || req.Query.Start >= req.Query.End {
|
||||
render.Error(w, errors.NewInvalidInputf(errors.CodeInvalidInput, "start and end are required and start must be less than end"))
|
||||
return nil, false
|
||||
}
|
||||
return req, true
|
||||
}
|
||||
|
||||
func (h *handler) parseV2TimelineQueryRequest(w http.ResponseWriter, r *http.Request) (*ruleHistoryRequest, bool) {
|
||||
req, err := parseV2TimelineQueryFromURL(r)
|
||||
if err != nil {
|
||||
render.Error(w, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "invalid query parameters"))
|
||||
return nil, false
|
||||
}
|
||||
if err := req.Query.Validate(); err != nil {
|
||||
render.Error(w, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "invalid query parameters"))
|
||||
return nil, false
|
||||
}
|
||||
return req, true
|
||||
}
|
||||
|
||||
func (h *handler) parseV2FilterKeysRequest(w http.ResponseWriter, r *http.Request) (rulestatehistorytypes.Query, string, int64, bool) {
|
||||
raw := telemetrytypes.PostableFieldKeysParams{}
|
||||
if err := binding.Query.BindQuery(r.URL.Query(), &raw); err != nil {
|
||||
render.Error(w, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "invalid query parameters"))
|
||||
return rulestatehistorytypes.Query{}, "", 0, false
|
||||
}
|
||||
|
||||
query := rulestatehistorytypes.Query{
|
||||
Start: raw.StartUnixMilli,
|
||||
End: raw.EndUnixMilli,
|
||||
FilterExpression: qbtypes.Filter{},
|
||||
Order: qbtypes.OrderDirectionAsc,
|
||||
}
|
||||
if err := query.Validate(); err != nil {
|
||||
render.Error(w, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "invalid query parameters"))
|
||||
return rulestatehistorytypes.Query{}, "", 0, false
|
||||
}
|
||||
|
||||
limit := normalizeFilterLimit(int64(raw.Limit))
|
||||
return query, strings.TrimSpace(raw.SearchText), limit, true
|
||||
}
|
||||
|
||||
func (h *handler) parseV2FilterValuesRequest(w http.ResponseWriter, r *http.Request) (rulestatehistorytypes.Query, string, string, int64, bool) {
|
||||
raw := telemetrytypes.PostableFieldValueParams{}
|
||||
if err := binding.Query.BindQuery(r.URL.Query(), &raw); err != nil {
|
||||
render.Error(w, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "invalid query parameters"))
|
||||
return rulestatehistorytypes.Query{}, "", "", 0, false
|
||||
}
|
||||
|
||||
key := strings.TrimSpace(raw.Name)
|
||||
if key == "" {
|
||||
render.Error(w, errors.NewInvalidInputf(errors.CodeInvalidInput, "key is required"))
|
||||
return rulestatehistorytypes.Query{}, "", "", 0, false
|
||||
}
|
||||
|
||||
query := rulestatehistorytypes.Query{
|
||||
Start: raw.StartUnixMilli,
|
||||
End: raw.EndUnixMilli,
|
||||
FilterExpression: parseFilterExpression(raw.ExistingQuery),
|
||||
Order: qbtypes.OrderDirectionAsc,
|
||||
}
|
||||
if err := query.Validate(); err != nil {
|
||||
render.Error(w, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "invalid query parameters"))
|
||||
return rulestatehistorytypes.Query{}, "", "", 0, false
|
||||
}
|
||||
|
||||
limit := normalizeFilterLimit(int64(raw.Limit))
|
||||
return query, key, strings.TrimSpace(raw.SearchText), limit, true
|
||||
}
|
||||
|
||||
func parseV2BaseQueryFromURL(r *http.Request) (*ruleHistoryRequest, error) {
|
||||
raw := rulestatehistorytypes.V2HistoryBaseQueryParams{}
|
||||
if err := binding.Query.BindQuery(r.URL.Query(), &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := &ruleHistoryRequest{}
|
||||
req.Query.Start = raw.Start
|
||||
req.Query.End = raw.End
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func parseV2TimelineQueryFromURL(r *http.Request) (*ruleHistoryRequest, error) {
|
||||
raw := rulestatehistorytypes.V2HistoryTimelineQueryParams{}
|
||||
if err := binding.Query.BindQuery(r.URL.Query(), &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := &ruleHistoryRequest{}
|
||||
req.Query.Start = raw.Start
|
||||
req.Query.End = raw.End
|
||||
req.Query.State = raw.State
|
||||
req.Query.Limit = raw.Limit
|
||||
req.Query.Order = raw.Order
|
||||
req.Query.FilterExpression = parseFilterExpression(raw.FilterExpression)
|
||||
req.Cursor = raw.Cursor
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func encodeCursor(token cursorToken) (string, error) {
|
||||
data, err := json.Marshal(token)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.RawURLEncoding.EncodeToString(data), nil
|
||||
}
|
||||
|
||||
func decodeCursor(cursor string) (*cursorToken, error) {
|
||||
data, err := base64.RawURLEncoding.DecodeString(cursor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
token := &cursorToken{}
|
||||
if err := json.Unmarshal(data, token); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func normalizeFilterLimit(limit int64) int64 {
|
||||
if limit <= 0 {
|
||||
return 50
|
||||
}
|
||||
if limit > 200 {
|
||||
return 200
|
||||
}
|
||||
return limit
|
||||
}
|
||||
|
||||
func toQBLabels(raw rulestatehistorytypes.LabelsString) []*qbtypes.Label {
|
||||
if strings.TrimSpace(string(raw)) == "" {
|
||||
return []*qbtypes.Label{}
|
||||
}
|
||||
|
||||
labelsMap := map[string]any{}
|
||||
if err := json.Unmarshal([]byte(raw), &labelsMap); err != nil {
|
||||
return []*qbtypes.Label{}
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(labelsMap))
|
||||
for key := range labelsMap {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
labels := make([]*qbtypes.Label, 0, len(keys))
|
||||
for _, key := range keys {
|
||||
labels = append(labels, &qbtypes.Label{
|
||||
Key: telemetrytypes.TelemetryFieldKey{
|
||||
Name: key,
|
||||
},
|
||||
Value: labelsMap[key],
|
||||
})
|
||||
}
|
||||
|
||||
return labels
|
||||
}
|
||||
|
||||
func parseFilterExpression(values ...string) qbtypes.Filter {
|
||||
for _, value := range values {
|
||||
expr := strings.TrimSpace(value)
|
||||
if expr != "" {
|
||||
return qbtypes.Filter{Expression: expr}
|
||||
}
|
||||
}
|
||||
return qbtypes.Filter{}
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
package implrulestatehistory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/modules/rulestatehistory"
|
||||
"github.com/SigNoz/signoz/pkg/types/rulestatehistorytypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
)
|
||||
|
||||
type module struct {
|
||||
store rulestatehistorytypes.Store
|
||||
}
|
||||
|
||||
func NewModule(store rulestatehistorytypes.Store) rulestatehistory.Module {
|
||||
return &module{store: store}
|
||||
}
|
||||
|
||||
func (m *module) AddRuleStateHistory(ctx context.Context, entries []rulestatehistorytypes.RuleStateHistory) error {
|
||||
return m.store.AddRuleStateHistory(ctx, entries)
|
||||
}
|
||||
|
||||
func (m *module) GetLastSavedRuleStateHistory(ctx context.Context, ruleID string) ([]rulestatehistorytypes.RuleStateHistory, error) {
|
||||
return m.store.GetLastSavedRuleStateHistory(ctx, ruleID)
|
||||
}
|
||||
|
||||
func (m *module) GetHistoryTimeline(ctx context.Context, ruleID string, query rulestatehistorytypes.Query) ([]rulestatehistorytypes.RuleStateHistory, uint64, error) {
|
||||
return m.store.ReadRuleStateHistoryByRuleID(ctx, ruleID, &query)
|
||||
}
|
||||
|
||||
func (m *module) GetHistoryFilterKeys(ctx context.Context, ruleID string, query rulestatehistorytypes.Query, search string, limit int64) (*telemetrytypes.GettableFieldKeys, error) {
|
||||
return m.store.ReadRuleStateHistoryFilterKeysByRuleID(ctx, ruleID, &query, search, limit)
|
||||
}
|
||||
|
||||
func (m *module) GetHistoryFilterValues(ctx context.Context, ruleID string, key string, query rulestatehistorytypes.Query, search string, limit int64) (*telemetrytypes.GettableFieldValues, error) {
|
||||
return m.store.ReadRuleStateHistoryFilterValuesByRuleID(ctx, ruleID, key, &query, search, limit)
|
||||
}
|
||||
|
||||
func (m *module) GetHistoryContributors(ctx context.Context, ruleID string, query rulestatehistorytypes.Query) ([]rulestatehistorytypes.RuleStateHistoryContributor, error) {
|
||||
return m.store.ReadRuleStateHistoryTopContributorsByRuleID(ctx, ruleID, &query)
|
||||
}
|
||||
|
||||
func (m *module) GetHistoryOverallStatus(ctx context.Context, ruleID string, query rulestatehistorytypes.Query) ([]rulestatehistorytypes.RuleStateWindow, error) {
|
||||
return m.store.GetOverallStateTransitions(ctx, ruleID, &query)
|
||||
}
|
||||
|
||||
func (m *module) GetHistoryStats(ctx context.Context, ruleID string, params rulestatehistorytypes.Query) (rulestatehistorytypes.Stats, error) {
|
||||
totalCurrentTriggers, err := m.store.GetTotalTriggers(ctx, ruleID, ¶ms)
|
||||
if err != nil {
|
||||
return rulestatehistorytypes.Stats{}, err
|
||||
}
|
||||
currentTriggersSeries, err := m.store.GetTriggersByInterval(ctx, ruleID, ¶ms)
|
||||
if err != nil {
|
||||
return rulestatehistorytypes.Stats{}, err
|
||||
}
|
||||
currentAvgResolutionTime, err := m.store.GetAvgResolutionTime(ctx, ruleID, ¶ms)
|
||||
if err != nil {
|
||||
return rulestatehistorytypes.Stats{}, err
|
||||
}
|
||||
currentAvgResolutionTimeSeries, err := m.store.GetAvgResolutionTimeByInterval(ctx, ruleID, ¶ms)
|
||||
if err != nil {
|
||||
return rulestatehistorytypes.Stats{}, err
|
||||
}
|
||||
|
||||
if params.End-params.Start >= 86400000 {
|
||||
days := int64(math.Ceil(float64(params.End-params.Start) / 86400000))
|
||||
params.Start -= days * 86400000
|
||||
params.End -= days * 86400000
|
||||
} else {
|
||||
params.Start -= 86400000
|
||||
params.End -= 86400000
|
||||
}
|
||||
|
||||
totalPastTriggers, err := m.store.GetTotalTriggers(ctx, ruleID, ¶ms)
|
||||
if err != nil {
|
||||
return rulestatehistorytypes.Stats{}, err
|
||||
}
|
||||
pastTriggersSeries, err := m.store.GetTriggersByInterval(ctx, ruleID, ¶ms)
|
||||
if err != nil {
|
||||
return rulestatehistorytypes.Stats{}, err
|
||||
}
|
||||
pastAvgResolutionTime, err := m.store.GetAvgResolutionTime(ctx, ruleID, ¶ms)
|
||||
if err != nil {
|
||||
return rulestatehistorytypes.Stats{}, err
|
||||
}
|
||||
pastAvgResolutionTimeSeries, err := m.store.GetAvgResolutionTimeByInterval(ctx, ruleID, ¶ms)
|
||||
if err != nil {
|
||||
return rulestatehistorytypes.Stats{}, err
|
||||
}
|
||||
|
||||
if math.IsNaN(currentAvgResolutionTime) || math.IsInf(currentAvgResolutionTime, 0) {
|
||||
currentAvgResolutionTime = 0
|
||||
}
|
||||
if math.IsNaN(pastAvgResolutionTime) || math.IsInf(pastAvgResolutionTime, 0) {
|
||||
pastAvgResolutionTime = 0
|
||||
}
|
||||
|
||||
return rulestatehistorytypes.Stats{
|
||||
TotalCurrentTriggers: totalCurrentTriggers,
|
||||
TotalPastTriggers: totalPastTriggers,
|
||||
CurrentTriggersSeries: currentTriggersSeries,
|
||||
PastTriggersSeries: pastTriggersSeries,
|
||||
CurrentAvgResolutionTime: currentAvgResolutionTime,
|
||||
PastAvgResolutionTime: pastAvgResolutionTime,
|
||||
CurrentAvgResolutionTimeSeries: currentAvgResolutionTimeSeries,
|
||||
PastAvgResolutionTimeSeries: pastAvgResolutionTimeSeries,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *module) RecordRuleStateHistory(ctx context.Context, ruleID string, handledRestart bool, itemsToAdd []rulestatehistorytypes.RuleStateHistory) error {
|
||||
revisedItemsToAdd := map[uint64]rulestatehistorytypes.RuleStateHistory{}
|
||||
|
||||
lastSavedState, err := m.store.GetLastSavedRuleStateHistory(ctx, ruleID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !handledRestart && len(lastSavedState) > 0 {
|
||||
currentItemsByFingerprint := make(map[uint64]rulestatehistorytypes.RuleStateHistory, len(itemsToAdd))
|
||||
for _, item := range itemsToAdd {
|
||||
currentItemsByFingerprint[item.Fingerprint] = item
|
||||
}
|
||||
|
||||
shouldSkip := map[uint64]bool{}
|
||||
for _, item := range lastSavedState {
|
||||
currentState, ok := currentItemsByFingerprint[item.Fingerprint]
|
||||
if !ok {
|
||||
if item.State == rulestatehistorytypes.StateFiring || item.State == rulestatehistorytypes.StateNoData {
|
||||
item.State = rulestatehistorytypes.StateInactive
|
||||
item.StateChanged = true
|
||||
item.UnixMilli = time.Now().UnixMilli()
|
||||
revisedItemsToAdd[item.Fingerprint] = item
|
||||
}
|
||||
} else if item.State != currentState.State {
|
||||
item.State = currentState.State
|
||||
item.StateChanged = true
|
||||
item.UnixMilli = time.Now().UnixMilli()
|
||||
revisedItemsToAdd[item.Fingerprint] = item
|
||||
}
|
||||
|
||||
shouldSkip[item.Fingerprint] = true
|
||||
}
|
||||
|
||||
for _, item := range itemsToAdd {
|
||||
if _, ok := revisedItemsToAdd[item.Fingerprint]; !ok && !shouldSkip[item.Fingerprint] {
|
||||
revisedItemsToAdd[item.Fingerprint] = item
|
||||
}
|
||||
}
|
||||
|
||||
newState := rulestatehistorytypes.StateInactive
|
||||
for _, item := range revisedItemsToAdd {
|
||||
if item.State == rulestatehistorytypes.StateFiring || item.State == rulestatehistorytypes.StateNoData {
|
||||
newState = rulestatehistorytypes.StateFiring
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if lastSavedState[0].OverallState != newState {
|
||||
for fingerprint, item := range revisedItemsToAdd {
|
||||
item.OverallState = newState
|
||||
item.OverallStateChanged = true
|
||||
revisedItemsToAdd[fingerprint] = item
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, item := range itemsToAdd {
|
||||
revisedItemsToAdd[item.Fingerprint] = item
|
||||
}
|
||||
}
|
||||
|
||||
if len(revisedItemsToAdd) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
entries := make([]rulestatehistorytypes.RuleStateHistory, 0, len(revisedItemsToAdd))
|
||||
for _, item := range revisedItemsToAdd {
|
||||
entries = append(entries, item)
|
||||
}
|
||||
|
||||
return m.store.AddRuleStateHistory(ctx, entries)
|
||||
}
|
||||
@@ -1,574 +0,0 @@
|
||||
package implrulestatehistory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/querybuilder"
|
||||
"github.com/SigNoz/signoz/pkg/telemetrystore"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/types/rulestatehistorytypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
sqlbuilder "github.com/huandu/go-sqlbuilder"
|
||||
)
|
||||
|
||||
const (
|
||||
signozHistoryDBName = "signoz_analytics"
|
||||
ruleStateHistoryTableName = "distributed_rule_state_history_v0"
|
||||
)
|
||||
|
||||
type store struct {
|
||||
telemetryStore telemetrystore.TelemetryStore
|
||||
telemetryMetadataStore telemetrytypes.MetadataStore
|
||||
fieldMapper qbtypes.FieldMapper
|
||||
conditionBuilder qbtypes.ConditionBuilder
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewStore(telemetryStore telemetrystore.TelemetryStore, telemetryMetadataStore telemetrytypes.MetadataStore, logger *slog.Logger) rulestatehistorytypes.Store {
|
||||
fm := newFieldMapper()
|
||||
return &store{
|
||||
telemetryStore: telemetryStore,
|
||||
telemetryMetadataStore: telemetryMetadataStore,
|
||||
fieldMapper: fm,
|
||||
conditionBuilder: newConditionBuilder(fm),
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *store) AddRuleStateHistory(ctx context.Context, entries []rulestatehistorytypes.RuleStateHistory) error {
|
||||
ib := sqlbuilder.NewInsertBuilder()
|
||||
ib.InsertInto(historyTable())
|
||||
ib.Cols(
|
||||
"rule_id",
|
||||
"rule_name",
|
||||
"overall_state",
|
||||
"overall_state_changed",
|
||||
"state",
|
||||
"state_changed",
|
||||
"unix_milli",
|
||||
"labels",
|
||||
"fingerprint",
|
||||
"value",
|
||||
)
|
||||
insertQuery, _ := ib.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||
|
||||
statement, err := s.telemetryStore.ClickhouseDB().PrepareBatch(
|
||||
ctx,
|
||||
insertQuery,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer statement.Abort() //nolint:errcheck
|
||||
|
||||
for _, history := range entries {
|
||||
if err = statement.Append(
|
||||
history.RuleID,
|
||||
history.RuleName,
|
||||
history.OverallState,
|
||||
history.OverallStateChanged,
|
||||
history.State,
|
||||
history.StateChanged,
|
||||
history.UnixMilli,
|
||||
history.Labels,
|
||||
history.Fingerprint,
|
||||
history.Value,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return statement.Send()
|
||||
}
|
||||
|
||||
func (s *store) GetLastSavedRuleStateHistory(ctx context.Context, ruleID string) ([]rulestatehistorytypes.RuleStateHistory, error) {
|
||||
sb := sqlbuilder.NewSelectBuilder()
|
||||
sb.Select("*")
|
||||
sb.From(historyTable())
|
||||
sb.Where(sb.E("rule_id", ruleID))
|
||||
sb.Where(sb.E("state_changed", true))
|
||||
sb.OrderBy("unix_milli DESC")
|
||||
sb.SQL("LIMIT 1 BY fingerprint")
|
||||
|
||||
query, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||
history := make([]rulestatehistorytypes.RuleStateHistory, 0)
|
||||
if err := s.telemetryStore.ClickhouseDB().Select(ctx, &history, query, args...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return history, nil
|
||||
}
|
||||
|
||||
func (s *store) ReadRuleStateHistoryByRuleID(ctx context.Context, ruleID string, query *rulestatehistorytypes.Query) ([]rulestatehistorytypes.RuleStateHistory, uint64, error) {
|
||||
sb := sqlbuilder.NewSelectBuilder()
|
||||
sb.Select(
|
||||
"rule_id",
|
||||
"rule_name",
|
||||
"overall_state",
|
||||
"overall_state_changed",
|
||||
"state",
|
||||
"state_changed",
|
||||
"unix_milli",
|
||||
"labels",
|
||||
"fingerprint",
|
||||
"value",
|
||||
)
|
||||
sb.From(historyTable())
|
||||
s.applyBaseHistoryFilters(sb, ruleID, query)
|
||||
|
||||
whereClause, err := s.buildFilterClause(ctx, query.FilterExpression, query.Start, query.End)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
if whereClause != nil {
|
||||
sb.AddWhereClause(sqlbuilder.CopyWhereClause(whereClause))
|
||||
}
|
||||
|
||||
sb.OrderBy(fmt.Sprintf("unix_milli %s", strings.ToUpper(query.Order.StringValue())))
|
||||
sb.Limit(int(query.Limit))
|
||||
sb.Offset(int(query.Offset))
|
||||
|
||||
selectQuery, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||
|
||||
history := []rulestatehistorytypes.RuleStateHistory{}
|
||||
if err := s.telemetryStore.ClickhouseDB().Select(ctx, &history, selectQuery, args...); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
countSB := sqlbuilder.NewSelectBuilder()
|
||||
countSB.Select("count(*)")
|
||||
countSB.From(historyTable())
|
||||
s.applyBaseHistoryFilters(countSB, ruleID, query)
|
||||
if whereClause != nil {
|
||||
countSB.AddWhereClause(sqlbuilder.CopyWhereClause(whereClause))
|
||||
}
|
||||
|
||||
var total uint64
|
||||
countQuery, countArgs := countSB.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||
if err := s.telemetryStore.ClickhouseDB().QueryRow(ctx, countQuery, countArgs...).Scan(&total); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return history, total, nil
|
||||
}
|
||||
|
||||
func (s *store) ReadRuleStateHistoryFilterKeysByRuleID(ctx context.Context, ruleID string, query *rulestatehistorytypes.Query, search string, limit int64) (*telemetrytypes.GettableFieldKeys, error) {
|
||||
if limit <= 0 {
|
||||
limit = 50
|
||||
}
|
||||
|
||||
sb := sqlbuilder.NewSelectBuilder()
|
||||
keyExpr := "arrayJoin(JSONExtractKeys(labels))"
|
||||
sb.Select(fmt.Sprintf("DISTINCT %s AS key", keyExpr))
|
||||
sb.From(historyTable())
|
||||
s.applyBaseHistoryFilters(sb, ruleID, query)
|
||||
sb.Where(fmt.Sprintf("%s != ''", keyExpr))
|
||||
|
||||
search = strings.TrimSpace(search)
|
||||
if search != "" {
|
||||
sb.Where(fmt.Sprintf("positionCaseInsensitiveUTF8(%s, %s) > 0", keyExpr, sb.Var(search)))
|
||||
}
|
||||
|
||||
whereClause, err := s.buildFilterClause(ctx, query.FilterExpression, query.Start, query.End)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if whereClause != nil {
|
||||
sb.AddWhereClause(sqlbuilder.CopyWhereClause(whereClause))
|
||||
}
|
||||
|
||||
sb.OrderBy("key ASC")
|
||||
sb.Limit(int(limit + 1))
|
||||
selectQuery, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||
|
||||
rows, err := s.telemetryStore.ClickhouseDB().Query(ctx, selectQuery, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
keys := make([]string, 0, limit+1)
|
||||
for rows.Next() {
|
||||
var key string
|
||||
if err := rows.Scan(&key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key = strings.TrimSpace(key)
|
||||
if key != "" {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
complete := true
|
||||
if int64(len(keys)) > limit {
|
||||
keys = keys[:int(limit)]
|
||||
complete = false
|
||||
}
|
||||
|
||||
keysMap := make(map[string][]*telemetrytypes.TelemetryFieldKey, len(keys))
|
||||
for _, key := range keys {
|
||||
fieldKey := &telemetrytypes.TelemetryFieldKey{
|
||||
Name: key,
|
||||
FieldDataType: telemetrytypes.FieldDataTypeString,
|
||||
}
|
||||
keysMap[key] = []*telemetrytypes.TelemetryFieldKey{fieldKey}
|
||||
}
|
||||
|
||||
return &telemetrytypes.GettableFieldKeys{
|
||||
Keys: keysMap,
|
||||
Complete: complete,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *store) ReadRuleStateHistoryFilterValuesByRuleID(ctx context.Context, ruleID string, key string, query *rulestatehistorytypes.Query, search string, limit int64) (*telemetrytypes.GettableFieldValues, error) {
|
||||
if limit <= 0 {
|
||||
limit = 50
|
||||
}
|
||||
|
||||
sb := sqlbuilder.NewSelectBuilder()
|
||||
valExpr := fmt.Sprintf("JSONExtractString(labels, %s)", sb.Var(key))
|
||||
sb.Select(fmt.Sprintf("DISTINCT %s AS val", valExpr))
|
||||
sb.From(historyTable())
|
||||
s.applyBaseHistoryFilters(sb, ruleID, query)
|
||||
sb.Where(fmt.Sprintf("JSONHas(labels, %s)", sb.Var(key)))
|
||||
sb.Where(fmt.Sprintf("%s != ''", valExpr))
|
||||
|
||||
search = strings.TrimSpace(search)
|
||||
if search != "" {
|
||||
sb.Where(fmt.Sprintf("positionCaseInsensitiveUTF8(%s, %s) > 0", valExpr, sb.Var(search)))
|
||||
}
|
||||
|
||||
whereClause, err := s.buildFilterClause(ctx, query.FilterExpression, query.Start, query.End)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if whereClause != nil {
|
||||
sb.AddWhereClause(sqlbuilder.CopyWhereClause(whereClause))
|
||||
}
|
||||
|
||||
sb.OrderBy("val ASC")
|
||||
sb.Limit(int(limit + 1))
|
||||
selectQuery, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||
|
||||
rows, err := s.telemetryStore.ClickhouseDB().Query(ctx, selectQuery, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
values := make([]string, 0, limit+1)
|
||||
for rows.Next() {
|
||||
var value string
|
||||
if err := rows.Scan(&value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
value = strings.TrimSpace(value)
|
||||
if value != "" {
|
||||
values = append(values, value)
|
||||
}
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
complete := true
|
||||
if int64(len(values)) > limit {
|
||||
values = values[:int(limit)]
|
||||
complete = false
|
||||
}
|
||||
|
||||
return &telemetrytypes.GettableFieldValues{
|
||||
Values: &telemetrytypes.TelemetryFieldValues{
|
||||
StringValues: values,
|
||||
},
|
||||
Complete: complete,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *store) ReadRuleStateHistoryTopContributorsByRuleID(ctx context.Context, ruleID string, query *rulestatehistorytypes.Query) ([]rulestatehistorytypes.RuleStateHistoryContributor, error) {
|
||||
sb := sqlbuilder.NewSelectBuilder()
|
||||
sb.Select(
|
||||
"fingerprint",
|
||||
"argMax(labels, unix_milli) AS labels",
|
||||
"count(*) AS count",
|
||||
)
|
||||
sb.From(historyTable())
|
||||
sb.Where(sb.E("rule_id", ruleID))
|
||||
sb.Where(sb.E("state_changed", true))
|
||||
sb.Where(sb.E("state", rulestatehistorytypes.StateFiring.StringValue()))
|
||||
sb.Where(sb.GE("unix_milli", query.Start))
|
||||
sb.Where(sb.LT("unix_milli", query.End))
|
||||
|
||||
whereClause, err := s.buildFilterClause(ctx, query.FilterExpression, query.Start, query.End)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if whereClause != nil {
|
||||
sb.AddWhereClause(sqlbuilder.CopyWhereClause(whereClause))
|
||||
}
|
||||
|
||||
sb.GroupBy("fingerprint")
|
||||
sb.Having("labels != '{}'")
|
||||
sb.OrderBy("count DESC")
|
||||
selectQuery, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||
|
||||
contributors := []rulestatehistorytypes.RuleStateHistoryContributor{}
|
||||
if err := s.telemetryStore.ClickhouseDB().Select(ctx, &contributors, selectQuery, args...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return contributors, nil
|
||||
}
|
||||
|
||||
func (s *store) GetOverallStateTransitions(ctx context.Context, ruleID string, query *rulestatehistorytypes.Query) ([]rulestatehistorytypes.RuleStateWindow, error) {
|
||||
innerSB := sqlbuilder.NewSelectBuilder()
|
||||
|
||||
eventsSubquery := fmt.Sprintf(
|
||||
`SELECT %s AS ts, if(count(*) = 0, %s, argMax(overall_state, unix_milli)) AS state
|
||||
FROM %s
|
||||
WHERE rule_id = %s
|
||||
AND unix_milli <= %s
|
||||
UNION ALL
|
||||
SELECT unix_milli AS ts, anyLast(overall_state) AS state
|
||||
FROM %s
|
||||
WHERE rule_id = %s
|
||||
AND overall_state_changed = true
|
||||
AND unix_milli > %s
|
||||
AND unix_milli < %s
|
||||
GROUP BY unix_milli`,
|
||||
innerSB.Var(query.Start),
|
||||
innerSB.Var(rulestatehistorytypes.StateInactive.StringValue()),
|
||||
historyTable(),
|
||||
innerSB.Var(ruleID),
|
||||
innerSB.Var(query.Start),
|
||||
historyTable(),
|
||||
innerSB.Var(ruleID),
|
||||
innerSB.Var(query.Start),
|
||||
innerSB.Var(query.End),
|
||||
)
|
||||
|
||||
innerSB.Select(
|
||||
"state",
|
||||
"ts AS start",
|
||||
fmt.Sprintf(
|
||||
"ifNull(leadInFrame(toNullable(ts), 1) OVER (ORDER BY ts ASC ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), %s) AS end",
|
||||
innerSB.Var(query.End),
|
||||
),
|
||||
)
|
||||
innerSB.From(fmt.Sprintf("(%s) AS events", eventsSubquery))
|
||||
innerSB.OrderBy("start ASC")
|
||||
innerQuery, args := innerSB.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||
|
||||
outerSB := sqlbuilder.NewSelectBuilder()
|
||||
outerSB.Select("state", "start", "end")
|
||||
outerSB.From(fmt.Sprintf("(%s) AS windows", innerQuery))
|
||||
outerSB.Where("start < end")
|
||||
selectQuery, outerArgs := outerSB.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||
args = append(args, outerArgs...)
|
||||
|
||||
windows := []rulestatehistorytypes.RuleStateWindow{}
|
||||
if err := s.telemetryStore.ClickhouseDB().Select(ctx, &windows, selectQuery, args...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return windows, nil
|
||||
}
|
||||
|
||||
func (s *store) GetAvgResolutionTime(ctx context.Context, ruleID string, query *rulestatehistorytypes.Query) (float64, error) {
|
||||
cte := s.buildMatchedEventsCTE(ruleID, query)
|
||||
sb := cte.Select("ifNull(toFloat64(avg(resolution_time - firing_time)) / 1000, 0) AS avg_resolution_time")
|
||||
sb.From("matched_events")
|
||||
selectQuery, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||
|
||||
var avg float64
|
||||
if err := s.telemetryStore.ClickhouseDB().QueryRow(ctx, selectQuery, args...).Scan(&avg); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return avg, nil
|
||||
}
|
||||
|
||||
func (s *store) GetAvgResolutionTimeByInterval(ctx context.Context, ruleID string, query *rulestatehistorytypes.Query) (*qbtypes.TimeSeries, error) {
|
||||
step := minStepSeconds(query.Start, query.End)
|
||||
cte := s.buildMatchedEventsCTE(ruleID, query)
|
||||
sb := cte.Select(
|
||||
fmt.Sprintf("toFloat64(avg(resolution_time - firing_time)) / 1000 AS value, toStartOfInterval(toDateTime(intDiv(firing_time, 1000)), INTERVAL %d SECOND) AS ts", step),
|
||||
)
|
||||
sb.From("matched_events")
|
||||
sb.GroupBy("ts")
|
||||
sb.OrderBy("ts ASC")
|
||||
selectQuery, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||
|
||||
return s.querySeries(ctx, selectQuery, args...)
|
||||
}
|
||||
|
||||
func (s *store) GetTotalTriggers(ctx context.Context, ruleID string, query *rulestatehistorytypes.Query) (uint64, error) {
|
||||
sb := sqlbuilder.NewSelectBuilder()
|
||||
sb.Select("count(*)")
|
||||
sb.From(historyTable())
|
||||
sb.Where(sb.E("rule_id", ruleID))
|
||||
sb.Where(sb.E("state_changed", true))
|
||||
sb.Where(sb.E("state", rulestatehistorytypes.StateFiring.StringValue()))
|
||||
sb.Where(sb.GE("unix_milli", query.Start))
|
||||
sb.Where(sb.LT("unix_milli", query.End))
|
||||
selectQuery, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||
|
||||
var total uint64
|
||||
if err := s.telemetryStore.ClickhouseDB().QueryRow(ctx, selectQuery, args...).Scan(&total); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return total, nil
|
||||
}
|
||||
|
||||
func (s *store) GetTriggersByInterval(ctx context.Context, ruleID string, query *rulestatehistorytypes.Query) (*qbtypes.TimeSeries, error) {
|
||||
step := minStepSeconds(query.Start, query.End)
|
||||
sb := sqlbuilder.NewSelectBuilder()
|
||||
sb.Select(
|
||||
fmt.Sprintf("toFloat64(count(*)) AS value, toStartOfInterval(toDateTime(intDiv(unix_milli, 1000)), INTERVAL %d SECOND) AS ts", step),
|
||||
)
|
||||
sb.From(historyTable())
|
||||
sb.Where(sb.E("rule_id", ruleID))
|
||||
sb.Where(sb.E("state_changed", true))
|
||||
sb.Where(sb.E("state", rulestatehistorytypes.StateFiring.StringValue()))
|
||||
sb.Where(sb.GE("unix_milli", query.Start))
|
||||
sb.Where(sb.LT("unix_milli", query.End))
|
||||
sb.GroupBy("ts")
|
||||
sb.OrderBy("ts ASC")
|
||||
selectQuery, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
|
||||
|
||||
return s.querySeries(ctx, selectQuery, args...)
|
||||
}
|
||||
|
||||
func (s *store) querySeries(ctx context.Context, selectQuery string, args ...any) (*qbtypes.TimeSeries, error) {
|
||||
rows, err := s.telemetryStore.ClickhouseDB().Query(ctx, selectQuery, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
series := &qbtypes.TimeSeries{
|
||||
Labels: []*qbtypes.Label{},
|
||||
Values: []*qbtypes.TimeSeriesValue{},
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
var value float64
|
||||
var ts time.Time
|
||||
if err := rows.Scan(&value, &ts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
series.Values = append(series.Values, &qbtypes.TimeSeriesValue{
|
||||
Timestamp: ts.UnixMilli(),
|
||||
Value: value,
|
||||
})
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return series, nil
|
||||
}
|
||||
|
||||
func (s *store) buildFilterClause(ctx context.Context, filter qbtypes.Filter, startMillis, endMillis int64) (*sqlbuilder.WhereClause, error) {
|
||||
expression := strings.TrimSpace(filter.Expression)
|
||||
if expression == "" {
|
||||
return nil, nil //nolint:nilnil
|
||||
}
|
||||
|
||||
selectors := querybuilder.QueryStringToKeysSelectors(expression)
|
||||
for i := range selectors {
|
||||
selectors[i].SelectorMatchType = telemetrytypes.FieldSelectorMatchTypeExact
|
||||
}
|
||||
|
||||
fieldKeys, _, err := s.telemetryMetadataStore.GetKeysMulti(ctx, selectors)
|
||||
if err != nil || len(fieldKeys) == 0 {
|
||||
fieldKeys = map[string][]*telemetrytypes.TelemetryFieldKey{}
|
||||
for _, sel := range selectors {
|
||||
fieldKeys[sel.Name] = []*telemetrytypes.TelemetryFieldKey{{
|
||||
Name: sel.Name,
|
||||
Signal: sel.Signal,
|
||||
FieldContext: sel.FieldContext,
|
||||
FieldDataType: sel.FieldDataType,
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
opts := querybuilder.FilterExprVisitorOpts{
|
||||
Logger: s.logger,
|
||||
FieldMapper: s.fieldMapper,
|
||||
ConditionBuilder: s.conditionBuilder,
|
||||
FieldKeys: fieldKeys,
|
||||
FullTextColumn: &telemetrytypes.TelemetryFieldKey{Name: "labels", FieldContext: telemetrytypes.FieldContextAttribute},
|
||||
}
|
||||
|
||||
startNs := querybuilder.ToNanoSecs(uint64(startMillis))
|
||||
endNs := querybuilder.ToNanoSecs(uint64(endMillis))
|
||||
prepared, err := querybuilder.PrepareWhereClause(expression, opts, startNs, endNs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if prepared == nil || prepared.WhereClause == nil {
|
||||
return nil, nil //nolint:nilnil
|
||||
}
|
||||
return prepared.WhereClause, nil
|
||||
}
|
||||
|
||||
func (s *store) applyBaseHistoryFilters(sb *sqlbuilder.SelectBuilder, ruleID string, query *rulestatehistorytypes.Query) {
|
||||
sb.Where(sb.E("rule_id", ruleID))
|
||||
sb.Where(sb.GE("unix_milli", query.Start))
|
||||
sb.Where(sb.LT("unix_milli", query.End))
|
||||
if !query.State.IsZero() {
|
||||
sb.Where(sb.E("state", query.State.StringValue()))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *store) buildMatchedEventsCTE(ruleID string, query *rulestatehistorytypes.Query) *sqlbuilder.CTEBuilder {
|
||||
firingSB := sqlbuilder.NewSelectBuilder()
|
||||
firingSB.Select("rule_id", "unix_milli AS firing_time")
|
||||
firingSB.From(historyTable())
|
||||
firingSB.Where(firingSB.E("overall_state", rulestatehistorytypes.StateFiring.StringValue()))
|
||||
firingSB.Where(firingSB.E("overall_state_changed", true))
|
||||
firingSB.Where(firingSB.E("rule_id", ruleID))
|
||||
firingSB.Where(firingSB.GE("unix_milli", query.Start))
|
||||
firingSB.Where(firingSB.LT("unix_milli", query.End))
|
||||
|
||||
resolutionSB := sqlbuilder.NewSelectBuilder()
|
||||
resolutionSB.Select("rule_id", "unix_milli AS resolution_time")
|
||||
resolutionSB.From(historyTable())
|
||||
resolutionSB.Where(resolutionSB.E("overall_state", rulestatehistorytypes.StateInactive.StringValue()))
|
||||
resolutionSB.Where(resolutionSB.E("overall_state_changed", true))
|
||||
resolutionSB.Where(resolutionSB.E("rule_id", ruleID))
|
||||
resolutionSB.Where(resolutionSB.GE("unix_milli", query.Start))
|
||||
resolutionSB.Where(resolutionSB.LT("unix_milli", query.End))
|
||||
|
||||
matchedSB := sqlbuilder.NewSelectBuilder()
|
||||
matchedSB.Select("f.rule_id", "f.firing_time", "min(r.resolution_time) AS resolution_time")
|
||||
matchedSB.From("firing_events f")
|
||||
matchedSB.JoinWithOption(sqlbuilder.LeftJoin, "resolution_events r", "f.rule_id = r.rule_id")
|
||||
matchedSB.Where("r.resolution_time > f.firing_time")
|
||||
matchedSB.GroupBy("f.rule_id", "f.firing_time")
|
||||
|
||||
return sqlbuilder.With(
|
||||
sqlbuilder.CTEQuery("firing_events").As(firingSB),
|
||||
sqlbuilder.CTEQuery("resolution_events").As(resolutionSB),
|
||||
sqlbuilder.CTEQuery("matched_events").As(matchedSB),
|
||||
)
|
||||
}
|
||||
|
||||
func historyTable() string {
|
||||
return fmt.Sprintf("%s.%s", signozHistoryDBName, ruleStateHistoryTableName)
|
||||
}
|
||||
|
||||
func minStepSeconds(start, end int64) int64 {
|
||||
if end <= start {
|
||||
return 60
|
||||
}
|
||||
rangeSeconds := (end - start) / 1000
|
||||
if rangeSeconds <= 0 {
|
||||
return 60
|
||||
}
|
||||
step := rangeSeconds / 120
|
||||
return max(step, int64(60))
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package rulestatehistory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/types/rulestatehistorytypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
)
|
||||
|
||||
type Module interface {
|
||||
RecordRuleStateHistory(context.Context, string, bool, []rulestatehistorytypes.RuleStateHistory) error
|
||||
AddRuleStateHistory(context.Context, []rulestatehistorytypes.RuleStateHistory) error
|
||||
GetLastSavedRuleStateHistory(context.Context, string) ([]rulestatehistorytypes.RuleStateHistory, error)
|
||||
GetHistoryStats(context.Context, string, rulestatehistorytypes.Query) (rulestatehistorytypes.Stats, error)
|
||||
GetHistoryTimeline(context.Context, string, rulestatehistorytypes.Query) ([]rulestatehistorytypes.RuleStateHistory, uint64, error)
|
||||
GetHistoryFilterKeys(context.Context, string, rulestatehistorytypes.Query, string, int64) (*telemetrytypes.GettableFieldKeys, error)
|
||||
GetHistoryFilterValues(context.Context, string, string, rulestatehistorytypes.Query, string, int64) (*telemetrytypes.GettableFieldValues, error)
|
||||
GetHistoryContributors(context.Context, string, rulestatehistorytypes.Query) ([]rulestatehistorytypes.RuleStateHistoryContributor, error)
|
||||
GetHistoryOverallStatus(context.Context, string, rulestatehistorytypes.Query) ([]rulestatehistorytypes.RuleStateWindow, error)
|
||||
}
|
||||
|
||||
type Handler interface {
|
||||
GetRuleHistoryStats(http.ResponseWriter, *http.Request)
|
||||
GetRuleHistoryTimeline(http.ResponseWriter, *http.Request)
|
||||
GetRuleHistoryFilterKeys(http.ResponseWriter, *http.Request)
|
||||
GetRuleHistoryFilterValues(http.ResponseWriter, *http.Request)
|
||||
GetRuleHistoryContributors(http.ResponseWriter, *http.Request)
|
||||
GetRuleHistoryOverallStatus(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
@@ -87,6 +88,41 @@ func (client *client) Read(ctx context.Context, query *prompb.Query, sortSeries
|
||||
return remote.FromQueryResult(sortSeries, res), nil
|
||||
}
|
||||
|
||||
func (c *client) ReadMultiple(ctx context.Context, queries []*prompb.Query, sortSeries bool) (storage.SeriesSet, error) {
|
||||
if len(queries) == 0 {
|
||||
return storage.EmptySeriesSet(), nil
|
||||
}
|
||||
if len(queries) == 1 {
|
||||
return c.Read(ctx, queries[0], sortSeries)
|
||||
}
|
||||
|
||||
type result struct {
|
||||
ss storage.SeriesSet
|
||||
err error
|
||||
}
|
||||
|
||||
results := make([]result, len(queries))
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(queries))
|
||||
for i, q := range queries {
|
||||
go func(i int, q *prompb.Query) {
|
||||
defer wg.Done()
|
||||
ss, err := c.Read(ctx, q, sortSeries)
|
||||
results[i] = result{ss, err}
|
||||
}(i, q)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
sets := make([]storage.SeriesSet, 0, len(queries))
|
||||
for _, r := range results {
|
||||
if r.err != nil {
|
||||
return nil, r.err
|
||||
}
|
||||
sets = append(sets, r.ss)
|
||||
}
|
||||
return storage.NewMergeSeriesSet(sets, 0, storage.ChainedSeriesMerge), nil
|
||||
}
|
||||
|
||||
func (client *client) queryToClickhouseQuery(_ context.Context, query *prompb.Query, metricName string, subQuery bool) (string, []any, error) {
|
||||
var clickHouseQuery string
|
||||
var conditions []string
|
||||
|
||||
@@ -2,6 +2,7 @@ package prometheus
|
||||
|
||||
import (
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/prometheus/prometheus/model/labels"
|
||||
"github.com/prometheus/prometheus/promql"
|
||||
)
|
||||
|
||||
@@ -19,26 +20,18 @@ func RemoveExtraLabels(res *promql.Result, labelsToRemove ...string) error {
|
||||
case promql.Vector:
|
||||
value := res.Value.(promql.Vector)
|
||||
for i := range value {
|
||||
series := &(value)[i]
|
||||
dst := series.Metric[:0]
|
||||
for _, lbl := range series.Metric {
|
||||
if _, drop := toRemove[lbl.Name]; !drop {
|
||||
dst = append(dst, lbl)
|
||||
}
|
||||
}
|
||||
series.Metric = dst
|
||||
b := labels.NewBuilder(value[i].Metric)
|
||||
b.Del(labelsToRemove...)
|
||||
newLabels := b.Labels()
|
||||
value[i].Metric = newLabels
|
||||
}
|
||||
case promql.Matrix:
|
||||
value := res.Value.(promql.Matrix)
|
||||
for i := range value {
|
||||
series := &(value)[i]
|
||||
dst := series.Metric[:0]
|
||||
for _, lbl := range series.Metric {
|
||||
if _, drop := toRemove[lbl.Name]; !drop {
|
||||
dst = append(dst, lbl)
|
||||
}
|
||||
}
|
||||
series.Metric = dst
|
||||
b := labels.NewBuilder(value[i].Metric)
|
||||
b.Del(labelsToRemove...)
|
||||
newLabels := b.Labels()
|
||||
value[i].Metric = newLabels
|
||||
}
|
||||
case promql.Scalar:
|
||||
return nil
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/querybuilder"
|
||||
qbv5 "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
"github.com/prometheus/prometheus/model/labels"
|
||||
"github.com/prometheus/prometheus/promql"
|
||||
"github.com/prometheus/prometheus/promql/parser"
|
||||
)
|
||||
@@ -240,14 +241,13 @@ func (q *promqlQuery) Execute(ctx context.Context) (*qbv5.Result, error) {
|
||||
var series []*qbv5.TimeSeries
|
||||
for _, v := range matrix {
|
||||
var s qbv5.TimeSeries
|
||||
lbls := make([]*qbv5.Label, 0, len(v.Metric))
|
||||
for name, value := range v.Metric.Copy().Map() {
|
||||
lbls := make([]*qbv5.Label, 0, v.Metric.Len())
|
||||
v.Metric.Range(func(l labels.Label) {
|
||||
lbls = append(lbls, &qbv5.Label{
|
||||
Key: telemetrytypes.TelemetryFieldKey{Name: name},
|
||||
Value: value,
|
||||
Key: telemetrytypes.TelemetryFieldKey{Name: l.Name},
|
||||
Value: l.Value,
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
s.Labels = lbls
|
||||
|
||||
for idx := range v.Floats {
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/http/middleware"
|
||||
"github.com/SigNoz/signoz/pkg/licensing/nooplicensing"
|
||||
"github.com/SigNoz/signoz/pkg/modules/organization"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rulestatehistory"
|
||||
"github.com/SigNoz/signoz/pkg/prometheus"
|
||||
"github.com/SigNoz/signoz/pkg/querier"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/agentConf"
|
||||
@@ -107,7 +106,6 @@ func NewServer(config signoz.Config, signoz *signoz.SigNoz) (*Server, error) {
|
||||
signoz.TelemetryMetadataStore,
|
||||
signoz.Prometheus,
|
||||
signoz.Modules.OrgGetter,
|
||||
signoz.Modules.RuleStateHistory,
|
||||
signoz.Querier,
|
||||
signoz.Instrumentation.ToProviderSettings(),
|
||||
signoz.QueryParser,
|
||||
@@ -338,7 +336,6 @@ func makeRulesManager(
|
||||
metadataStore telemetrytypes.MetadataStore,
|
||||
prometheus prometheus.Prometheus,
|
||||
orgGetter organization.Getter,
|
||||
ruleStateHistoryModule rulestatehistory.Module,
|
||||
querier querier.Querier,
|
||||
providerSettings factory.ProviderSettings,
|
||||
queryParser queryparser.QueryParser,
|
||||
@@ -347,23 +344,22 @@ func makeRulesManager(
|
||||
maintenanceStore := sqlrulestore.NewMaintenanceStore(sqlstore)
|
||||
// create manager opts
|
||||
managerOpts := &rules.ManagerOptions{
|
||||
TelemetryStore: telemetryStore,
|
||||
MetadataStore: metadataStore,
|
||||
Prometheus: prometheus,
|
||||
Context: context.Background(),
|
||||
Logger: zap.L(),
|
||||
Reader: ch,
|
||||
Querier: querier,
|
||||
SLogger: providerSettings.Logger,
|
||||
Cache: cache,
|
||||
EvalDelay: constants.GetEvalDelay(),
|
||||
OrgGetter: orgGetter,
|
||||
Alertmanager: alertmanager,
|
||||
RuleStore: ruleStore,
|
||||
MaintenanceStore: maintenanceStore,
|
||||
SqlStore: sqlstore,
|
||||
QueryParser: queryParser,
|
||||
RuleStateHistoryModule: ruleStateHistoryModule,
|
||||
TelemetryStore: telemetryStore,
|
||||
MetadataStore: metadataStore,
|
||||
Prometheus: prometheus,
|
||||
Context: context.Background(),
|
||||
Logger: zap.L(),
|
||||
Reader: ch,
|
||||
Querier: querier,
|
||||
SLogger: providerSettings.Logger,
|
||||
Cache: cache,
|
||||
EvalDelay: constants.GetEvalDelay(),
|
||||
OrgGetter: orgGetter,
|
||||
Alertmanager: alertmanager,
|
||||
RuleStore: ruleStore,
|
||||
MaintenanceStore: maintenanceStore,
|
||||
SqlStore: sqlstore,
|
||||
QueryParser: queryParser,
|
||||
}
|
||||
|
||||
// create Manager
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rulestatehistory"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/constants"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/interfaces"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/model"
|
||||
@@ -18,7 +17,6 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/queryparser"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/types/rulestatehistorytypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/ruletypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
@@ -98,8 +96,6 @@ type BaseRule struct {
|
||||
// newGroupEvalDelay is the grace period for new alert groups
|
||||
newGroupEvalDelay valuer.TextDuration
|
||||
|
||||
ruleStateHistoryModule rulestatehistory.Module
|
||||
|
||||
queryParser queryparser.QueryParser
|
||||
}
|
||||
|
||||
@@ -147,12 +143,6 @@ func WithMetadataStore(metadataStore telemetrytypes.MetadataStore) RuleOption {
|
||||
}
|
||||
}
|
||||
|
||||
func WithRuleStateHistoryModule(module rulestatehistory.Module) RuleOption {
|
||||
return func(r *BaseRule) {
|
||||
r.ruleStateHistoryModule = module
|
||||
}
|
||||
}
|
||||
|
||||
func NewBaseRule(id string, orgID valuer.UUID, p *ruletypes.PostableRule, reader interfaces.Reader, opts ...RuleOption) (*BaseRule, error) {
|
||||
if p.RuleCondition == nil || !p.RuleCondition.IsValid() {
|
||||
return nil, fmt.Errorf("invalid rule condition")
|
||||
@@ -410,59 +400,100 @@ func (r *BaseRule) ForEachActiveAlert(f func(*ruletypes.Alert)) {
|
||||
}
|
||||
|
||||
func (r *BaseRule) RecordRuleStateHistory(ctx context.Context, prevState, currentState model.AlertState, itemsToAdd []model.RuleStateHistory) error {
|
||||
if r.ruleStateHistoryModule == nil {
|
||||
return nil
|
||||
}
|
||||
zap.L().Debug("recording rule state history", zap.String("ruleid", r.ID()), zap.Any("prevState", prevState), zap.Any("currentState", currentState), zap.Any("itemsToAdd", itemsToAdd))
|
||||
revisedItemsToAdd := map[uint64]model.RuleStateHistory{}
|
||||
|
||||
if err := r.ruleStateHistoryModule.RecordRuleStateHistory(ctx, r.ID(), r.handledRestart, toRuleStateHistoryTypes(itemsToAdd)); err != nil {
|
||||
zap.L().Error("error while recording rule state history", zap.Error(err), zap.Any("itemsToAdd", itemsToAdd))
|
||||
lastSavedState, err := r.reader.GetLastSavedRuleStateHistory(ctx, r.ID())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if the query-service has been restarted, or the rule has been modified (which re-initializes the rule),
|
||||
// the state would reset so we need to add the corresponding state changes to previously saved states
|
||||
if !r.handledRestart && len(lastSavedState) > 0 {
|
||||
zap.L().Debug("handling restart", zap.String("ruleid", r.ID()), zap.Any("lastSavedState", lastSavedState))
|
||||
l := map[uint64]model.RuleStateHistory{}
|
||||
for _, item := range itemsToAdd {
|
||||
l[item.Fingerprint] = item
|
||||
}
|
||||
|
||||
shouldSkip := map[uint64]bool{}
|
||||
|
||||
for _, item := range lastSavedState {
|
||||
// for the last saved item with fingerprint, check if there is a corresponding entry in the current state
|
||||
currentState, ok := l[item.Fingerprint]
|
||||
if !ok {
|
||||
// there was a state change in the past, but not in the current state
|
||||
// if the state was firing, then we should add a resolved state change
|
||||
if item.State == model.StateFiring || item.State == model.StateNoData {
|
||||
item.State = model.StateInactive
|
||||
item.StateChanged = true
|
||||
item.UnixMilli = time.Now().UnixMilli()
|
||||
revisedItemsToAdd[item.Fingerprint] = item
|
||||
}
|
||||
// there is nothing to do if the prev state was normal
|
||||
} else {
|
||||
if item.State != currentState.State {
|
||||
item.State = currentState.State
|
||||
item.StateChanged = true
|
||||
item.UnixMilli = time.Now().UnixMilli()
|
||||
revisedItemsToAdd[item.Fingerprint] = item
|
||||
}
|
||||
}
|
||||
// do not add this item to revisedItemsToAdd as it is already processed
|
||||
shouldSkip[item.Fingerprint] = true
|
||||
}
|
||||
zap.L().Debug("after lastSavedState loop", zap.String("ruleid", r.ID()), zap.Any("revisedItemsToAdd", revisedItemsToAdd))
|
||||
|
||||
// if there are any new state changes that were not saved, add them to the revised items
|
||||
for _, item := range itemsToAdd {
|
||||
if _, ok := revisedItemsToAdd[item.Fingerprint]; !ok && !shouldSkip[item.Fingerprint] {
|
||||
revisedItemsToAdd[item.Fingerprint] = item
|
||||
}
|
||||
}
|
||||
zap.L().Debug("after itemsToAdd loop", zap.String("ruleid", r.ID()), zap.Any("revisedItemsToAdd", revisedItemsToAdd))
|
||||
|
||||
newState := model.StateInactive
|
||||
for _, item := range revisedItemsToAdd {
|
||||
if item.State == model.StateFiring || item.State == model.StateNoData {
|
||||
newState = model.StateFiring
|
||||
break
|
||||
}
|
||||
}
|
||||
zap.L().Debug("newState", zap.String("ruleid", r.ID()), zap.Any("newState", newState))
|
||||
|
||||
// if there is a change in the overall state, update the overall state
|
||||
if lastSavedState[0].OverallState != newState {
|
||||
for fingerprint, item := range revisedItemsToAdd {
|
||||
item.OverallState = newState
|
||||
item.OverallStateChanged = true
|
||||
revisedItemsToAdd[fingerprint] = item
|
||||
}
|
||||
}
|
||||
zap.L().Debug("revisedItemsToAdd after newState", zap.String("ruleid", r.ID()), zap.Any("revisedItemsToAdd", revisedItemsToAdd))
|
||||
|
||||
} else {
|
||||
for _, item := range itemsToAdd {
|
||||
revisedItemsToAdd[item.Fingerprint] = item
|
||||
}
|
||||
}
|
||||
|
||||
if len(revisedItemsToAdd) > 0 && r.reader != nil {
|
||||
zap.L().Debug("writing rule state history", zap.String("ruleid", r.ID()), zap.Any("revisedItemsToAdd", revisedItemsToAdd))
|
||||
|
||||
entries := make([]model.RuleStateHistory, 0, len(revisedItemsToAdd))
|
||||
for _, item := range revisedItemsToAdd {
|
||||
entries = append(entries, item)
|
||||
}
|
||||
err := r.reader.AddRuleStateHistory(ctx, entries)
|
||||
if err != nil {
|
||||
zap.L().Error("error while inserting rule state history", zap.Error(err), zap.Any("itemsToAdd", itemsToAdd))
|
||||
}
|
||||
}
|
||||
r.handledRestart = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO(srikanthccv): remove these when v3 is cleaned up
|
||||
func toRuleStateHistoryTypes(entries []model.RuleStateHistory) []rulestatehistorytypes.RuleStateHistory {
|
||||
converted := make([]rulestatehistorytypes.RuleStateHistory, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
converted = append(converted, rulestatehistorytypes.RuleStateHistory{
|
||||
RuleID: entry.RuleID,
|
||||
RuleName: entry.RuleName,
|
||||
OverallState: toRuleStateHistoryAlertState(entry.OverallState),
|
||||
OverallStateChanged: entry.OverallStateChanged,
|
||||
State: toRuleStateHistoryAlertState(entry.State),
|
||||
StateChanged: entry.StateChanged,
|
||||
UnixMilli: entry.UnixMilli,
|
||||
Labels: rulestatehistorytypes.LabelsString(entry.Labels),
|
||||
Fingerprint: entry.Fingerprint,
|
||||
Value: entry.Value,
|
||||
})
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func toRuleStateHistoryAlertState(state model.AlertState) rulestatehistorytypes.AlertState {
|
||||
switch state {
|
||||
case model.StateInactive:
|
||||
return rulestatehistorytypes.StateInactive
|
||||
case model.StatePending:
|
||||
return rulestatehistorytypes.StatePending
|
||||
case model.StateRecovering:
|
||||
return rulestatehistorytypes.StateRecovering
|
||||
case model.StateFiring:
|
||||
return rulestatehistorytypes.StateFiring
|
||||
case model.StateNoData:
|
||||
return rulestatehistorytypes.StateNoData
|
||||
case model.StateDisabled:
|
||||
return rulestatehistorytypes.StateDisabled
|
||||
default:
|
||||
return rulestatehistorytypes.StateInactive
|
||||
}
|
||||
}
|
||||
|
||||
func (r *BaseRule) PopulateTemporality(ctx context.Context, orgID valuer.UUID, qp *v3.QueryRangeParamsV3) error {
|
||||
missingTemporality := make([]string, 0)
|
||||
metricNameToTemporality := make(map[string]map[v3.Temporality]bool)
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/alertmanager"
|
||||
"github.com/SigNoz/signoz/pkg/cache"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rulestatehistory"
|
||||
"github.com/SigNoz/signoz/pkg/modules/organization"
|
||||
"github.com/SigNoz/signoz/pkg/prometheus"
|
||||
querierV5 "github.com/SigNoz/signoz/pkg/querier"
|
||||
@@ -100,8 +99,6 @@ type ManagerOptions struct {
|
||||
|
||||
EvalDelay valuer.TextDuration
|
||||
|
||||
RuleStateHistoryModule rulestatehistory.Module
|
||||
|
||||
PrepareTaskFunc func(opts PrepareTaskOptions) (Task, error)
|
||||
PrepareTestRuleFunc func(opts PrepareTestRuleOptions) (int, *model.ApiError)
|
||||
Alertmanager alertmanager.Alertmanager
|
||||
@@ -177,7 +174,6 @@ func defaultPrepareTaskFunc(opts PrepareTaskOptions) (Task, error) {
|
||||
WithSQLStore(opts.SQLStore),
|
||||
WithQueryParser(opts.ManagerOpts.QueryParser),
|
||||
WithMetadataStore(opts.ManagerOpts.MetadataStore),
|
||||
WithRuleStateHistoryModule(opts.ManagerOpts.RuleStateHistoryModule),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@@ -202,7 +198,6 @@ func defaultPrepareTaskFunc(opts PrepareTaskOptions) (Task, error) {
|
||||
WithSQLStore(opts.SQLStore),
|
||||
WithQueryParser(opts.ManagerOpts.QueryParser),
|
||||
WithMetadataStore(opts.ManagerOpts.MetadataStore),
|
||||
WithRuleStateHistoryModule(opts.ManagerOpts.RuleStateHistoryModule),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/prometheus"
|
||||
"github.com/SigNoz/signoz/pkg/units"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/interfaces"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/model"
|
||||
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
|
||||
@@ -18,7 +17,9 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/query-service/utils/timestamp"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/types/ruletypes"
|
||||
"github.com/SigNoz/signoz/pkg/units"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
"github.com/prometheus/prometheus/model/labels"
|
||||
"github.com/prometheus/prometheus/promql"
|
||||
)
|
||||
|
||||
@@ -461,12 +462,12 @@ func toCommonSeries(series promql.Series) v3.Series {
|
||||
Points: make([]v3.Point, 0),
|
||||
}
|
||||
|
||||
for _, lbl := range series.Metric {
|
||||
series.Metric.Range(func(lbl labels.Label) {
|
||||
commonSeries.Labels[lbl.Name] = lbl.Value
|
||||
commonSeries.LabelsArray = append(commonSeries.LabelsArray, map[string]string{
|
||||
lbl.Name: lbl.Value,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
for _, f := range series.Floats {
|
||||
commonSeries.Points = append(commonSeries.Points, v3.Point{
|
||||
|
||||
@@ -35,7 +35,7 @@ func TestThresholdRuleEvalBackwardCompat(t *testing.T) {
|
||||
AlertName: "Eval Backward Compatibility Test without recovery target",
|
||||
AlertType: ruletypes.AlertTypeMetric,
|
||||
RuleType: ruletypes.RuleTypeThreshold,
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{Kind: ruletypes.RollingEvaluation, Spec: ruletypes.RollingWindow{
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{ruletypes.RollingEvaluation, ruletypes.RollingWindow{
|
||||
EvalWindow: valuer.MustParseTextDuration("5m"),
|
||||
Frequency: valuer.MustParseTextDuration("1m"),
|
||||
}},
|
||||
@@ -151,7 +151,7 @@ func TestPrepareLinksToLogs(t *testing.T) {
|
||||
AlertName: "Tricky Condition Tests",
|
||||
AlertType: ruletypes.AlertTypeLogs,
|
||||
RuleType: ruletypes.RuleTypeThreshold,
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{Kind: ruletypes.RollingEvaluation, Spec: ruletypes.RollingWindow{
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{ruletypes.RollingEvaluation, ruletypes.RollingWindow{
|
||||
EvalWindow: valuer.MustParseTextDuration("5m"),
|
||||
Frequency: valuer.MustParseTextDuration("1m"),
|
||||
}},
|
||||
@@ -205,7 +205,7 @@ func TestPrepareLinksToLogsV5(t *testing.T) {
|
||||
AlertName: "Tricky Condition Tests",
|
||||
AlertType: ruletypes.AlertTypeLogs,
|
||||
RuleType: ruletypes.RuleTypeThreshold,
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{Kind: ruletypes.RollingEvaluation, Spec: ruletypes.RollingWindow{
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{ruletypes.RollingEvaluation, ruletypes.RollingWindow{
|
||||
EvalWindow: valuer.MustParseTextDuration("5m"),
|
||||
Frequency: valuer.MustParseTextDuration("1m"),
|
||||
}},
|
||||
@@ -266,7 +266,7 @@ func TestPrepareLinksToTracesV5(t *testing.T) {
|
||||
AlertName: "Tricky Condition Tests",
|
||||
AlertType: ruletypes.AlertTypeTraces,
|
||||
RuleType: ruletypes.RuleTypeThreshold,
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{Kind: ruletypes.RollingEvaluation, Spec: ruletypes.RollingWindow{
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{ruletypes.RollingEvaluation, ruletypes.RollingWindow{
|
||||
EvalWindow: valuer.MustParseTextDuration("5m"),
|
||||
Frequency: valuer.MustParseTextDuration("1m"),
|
||||
}},
|
||||
@@ -327,7 +327,7 @@ func TestPrepareLinksToTraces(t *testing.T) {
|
||||
AlertName: "Links to traces test",
|
||||
AlertType: ruletypes.AlertTypeTraces,
|
||||
RuleType: ruletypes.RuleTypeThreshold,
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{Kind: ruletypes.RollingEvaluation, Spec: ruletypes.RollingWindow{
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{ruletypes.RollingEvaluation, ruletypes.RollingWindow{
|
||||
EvalWindow: valuer.MustParseTextDuration("5m"),
|
||||
Frequency: valuer.MustParseTextDuration("1m"),
|
||||
}},
|
||||
@@ -381,7 +381,7 @@ func TestThresholdRuleLabelNormalization(t *testing.T) {
|
||||
AlertName: "Tricky Condition Tests",
|
||||
AlertType: ruletypes.AlertTypeMetric,
|
||||
RuleType: ruletypes.RuleTypeThreshold,
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{Kind: ruletypes.RollingEvaluation, Spec: ruletypes.RollingWindow{
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{ruletypes.RollingEvaluation, ruletypes.RollingWindow{
|
||||
EvalWindow: valuer.MustParseTextDuration("5m"),
|
||||
Frequency: valuer.MustParseTextDuration("1m"),
|
||||
}},
|
||||
|
||||
@@ -22,8 +22,6 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/modules/quickfilter/implquickfilter"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rawdataexport"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rawdataexport/implrawdataexport"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rulestatehistory"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rulestatehistory/implrulestatehistory"
|
||||
"github.com/SigNoz/signoz/pkg/modules/savedview"
|
||||
"github.com/SigNoz/signoz/pkg/modules/savedview/implsavedview"
|
||||
"github.com/SigNoz/signoz/pkg/modules/serviceaccount"
|
||||
@@ -46,7 +44,6 @@ type Handlers struct {
|
||||
QuickFilter quickfilter.Handler
|
||||
TraceFunnel tracefunnel.Handler
|
||||
RawDataExport rawdataexport.Handler
|
||||
RuleStateHistory rulestatehistory.Handler
|
||||
SpanPercentile spanpercentile.Handler
|
||||
Services services.Handler
|
||||
MetricsExplorer metricsexplorer.Handler
|
||||
@@ -80,7 +77,6 @@ func NewHandlers(
|
||||
QuickFilter: implquickfilter.NewHandler(modules.QuickFilter),
|
||||
TraceFunnel: impltracefunnel.NewHandler(modules.TraceFunnel),
|
||||
RawDataExport: implrawdataexport.NewHandler(modules.RawDataExport),
|
||||
RuleStateHistory: implrulestatehistory.NewHandler(modules.RuleStateHistory),
|
||||
Services: implservices.NewHandler(modules.Services),
|
||||
MetricsExplorer: implmetricsexplorer.NewHandler(modules.MetricsExplorer),
|
||||
SpanPercentile: implspanpercentile.NewHandler(modules.SpanPercentile),
|
||||
|
||||
@@ -25,8 +25,6 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/modules/quickfilter/implquickfilter"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rawdataexport"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rawdataexport/implrawdataexport"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rulestatehistory"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rulestatehistory/implrulestatehistory"
|
||||
"github.com/SigNoz/signoz/pkg/modules/savedview"
|
||||
"github.com/SigNoz/signoz/pkg/modules/savedview/implsavedview"
|
||||
"github.com/SigNoz/signoz/pkg/modules/serviceaccount"
|
||||
@@ -53,25 +51,24 @@ import (
|
||||
)
|
||||
|
||||
type Modules struct {
|
||||
OrgGetter organization.Getter
|
||||
OrgSetter organization.Setter
|
||||
Preference preference.Module
|
||||
User user.Module
|
||||
UserGetter user.Getter
|
||||
SavedView savedview.Module
|
||||
Apdex apdex.Module
|
||||
Dashboard dashboard.Module
|
||||
QuickFilter quickfilter.Module
|
||||
TraceFunnel tracefunnel.Module
|
||||
RawDataExport rawdataexport.Module
|
||||
RuleStateHistory rulestatehistory.Module
|
||||
AuthDomain authdomain.Module
|
||||
Session session.Module
|
||||
Services services.Module
|
||||
SpanPercentile spanpercentile.Module
|
||||
MetricsExplorer metricsexplorer.Module
|
||||
Promote promote.Module
|
||||
ServiceAccount serviceaccount.Module
|
||||
OrgGetter organization.Getter
|
||||
OrgSetter organization.Setter
|
||||
Preference preference.Module
|
||||
User user.Module
|
||||
UserGetter user.Getter
|
||||
SavedView savedview.Module
|
||||
Apdex apdex.Module
|
||||
Dashboard dashboard.Module
|
||||
QuickFilter quickfilter.Module
|
||||
TraceFunnel tracefunnel.Module
|
||||
RawDataExport rawdataexport.Module
|
||||
AuthDomain authdomain.Module
|
||||
Session session.Module
|
||||
Services services.Module
|
||||
SpanPercentile spanpercentile.Module
|
||||
MetricsExplorer metricsexplorer.Module
|
||||
Promote promote.Module
|
||||
ServiceAccount serviceaccount.Module
|
||||
}
|
||||
|
||||
func NewModules(
|
||||
@@ -99,24 +96,23 @@ func NewModules(
|
||||
ruleStore := sqlrulestore.NewRuleStore(sqlstore, queryParser, providerSettings)
|
||||
|
||||
return Modules{
|
||||
OrgGetter: orgGetter,
|
||||
OrgSetter: orgSetter,
|
||||
Preference: implpreference.NewModule(implpreference.NewStore(sqlstore), preferencetypes.NewAvailablePreference()),
|
||||
SavedView: implsavedview.NewModule(sqlstore),
|
||||
Apdex: implapdex.NewModule(sqlstore),
|
||||
Dashboard: dashboard,
|
||||
User: user,
|
||||
UserGetter: userGetter,
|
||||
QuickFilter: quickfilter,
|
||||
TraceFunnel: impltracefunnel.NewModule(impltracefunnel.NewStore(sqlstore)),
|
||||
RawDataExport: implrawdataexport.NewModule(querier),
|
||||
RuleStateHistory: implrulestatehistory.NewModule(implrulestatehistory.NewStore(telemetryStore, telemetryMetadataStore, providerSettings.Logger)),
|
||||
AuthDomain: implauthdomain.NewModule(implauthdomain.NewStore(sqlstore), authNs),
|
||||
Session: implsession.NewModule(providerSettings, authNs, user, userGetter, implauthdomain.NewModule(implauthdomain.NewStore(sqlstore), authNs), tokenizer, orgGetter),
|
||||
SpanPercentile: implspanpercentile.NewModule(querier, providerSettings),
|
||||
Services: implservices.NewModule(querier, telemetryStore),
|
||||
MetricsExplorer: implmetricsexplorer.NewModule(telemetryStore, telemetryMetadataStore, cache, ruleStore, dashboard, providerSettings, config.MetricsExplorer),
|
||||
Promote: implpromote.NewModule(telemetryMetadataStore, telemetryStore),
|
||||
ServiceAccount: implserviceaccount.NewModule(implserviceaccount.NewStore(sqlstore), authz, emailing, providerSettings),
|
||||
OrgGetter: orgGetter,
|
||||
OrgSetter: orgSetter,
|
||||
Preference: implpreference.NewModule(implpreference.NewStore(sqlstore), preferencetypes.NewAvailablePreference()),
|
||||
SavedView: implsavedview.NewModule(sqlstore),
|
||||
Apdex: implapdex.NewModule(sqlstore),
|
||||
Dashboard: dashboard,
|
||||
User: user,
|
||||
UserGetter: userGetter,
|
||||
QuickFilter: quickfilter,
|
||||
TraceFunnel: impltracefunnel.NewModule(impltracefunnel.NewStore(sqlstore)),
|
||||
RawDataExport: implrawdataexport.NewModule(querier),
|
||||
AuthDomain: implauthdomain.NewModule(implauthdomain.NewStore(sqlstore), authNs),
|
||||
Session: implsession.NewModule(providerSettings, authNs, user, userGetter, implauthdomain.NewModule(implauthdomain.NewStore(sqlstore), authNs), tokenizer, orgGetter),
|
||||
SpanPercentile: implspanpercentile.NewModule(querier, providerSettings),
|
||||
Services: implservices.NewModule(querier, telemetryStore),
|
||||
MetricsExplorer: implmetricsexplorer.NewModule(telemetryStore, telemetryMetadataStore, cache, ruleStore, dashboard, providerSettings, config.MetricsExplorer),
|
||||
Promote: implpromote.NewModule(telemetryMetadataStore, telemetryStore),
|
||||
ServiceAccount: implserviceaccount.NewModule(implserviceaccount.NewStore(sqlstore), authz, emailing, providerSettings),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/modules/organization"
|
||||
"github.com/SigNoz/signoz/pkg/modules/preference"
|
||||
"github.com/SigNoz/signoz/pkg/modules/promote"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rulestatehistory"
|
||||
"github.com/SigNoz/signoz/pkg/modules/serviceaccount"
|
||||
"github.com/SigNoz/signoz/pkg/modules/session"
|
||||
"github.com/SigNoz/signoz/pkg/modules/user"
|
||||
@@ -62,7 +61,6 @@ func NewOpenAPI(ctx context.Context, instrumentation instrumentation.Instrumenta
|
||||
struct{ zeus.Handler }{},
|
||||
struct{ querier.Handler }{},
|
||||
struct{ serviceaccount.Handler }{},
|
||||
struct{ rulestatehistory.Handler }{},
|
||||
).New(ctx, instrumentation.ToProviderSettings(), apiserver.Config{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -256,7 +256,6 @@ func NewAPIServerProviderFactories(orgGetter organization.Getter, authz authz.Au
|
||||
handlers.ZeusHandler,
|
||||
handlers.QuerierHandler,
|
||||
handlers.ServiceAccountHandler,
|
||||
handlers.RuleStateHistory,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ func (c *conditionBuilder) conditionFor(
|
||||
return "", err
|
||||
}
|
||||
|
||||
if column.IsJSONColumn() && querybuilder.BodyJSONQueryEnabled {
|
||||
if column.Type.GetType() == schema.ColumnTypeEnumJSON && querybuilder.BodyJSONQueryEnabled {
|
||||
valueType, value := InferDataType(value, operator, key)
|
||||
cond, err := NewJSONConditionBuilder(key, valueType).buildJSONCondition(operator, value, sb)
|
||||
if err != nil {
|
||||
|
||||
@@ -17,7 +17,7 @@ const (
|
||||
LogsV2TimestampColumn = "timestamp"
|
||||
LogsV2ObservedTimestampColumn = "observed_timestamp"
|
||||
LogsV2BodyColumn = "body"
|
||||
LogsV2BodyJSONColumn = constants.BodyJSONColumn
|
||||
LogsV2BodyJSONColumn = constants.BodyV2Column
|
||||
LogsV2BodyPromotedColumn = constants.BodyPromotedColumn
|
||||
LogsV2TraceIDColumn = "trace_id"
|
||||
LogsV2SpanIDColumn = "span_id"
|
||||
@@ -34,7 +34,7 @@ const (
|
||||
LogsV2ResourcesStringColumn = "resources_string"
|
||||
LogsV2ScopeStringColumn = "scope_string"
|
||||
|
||||
BodyJSONColumnPrefix = constants.BodyJSONColumnPrefix
|
||||
BodyJSONColumnPrefix = constants.BodyV2ColumnPrefix
|
||||
BodyPromotedColumnPrefix = constants.BodyPromotedColumnPrefix
|
||||
)
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
type fieldMapper struct {}
|
||||
type fieldMapper struct{}
|
||||
|
||||
func NewFieldMapper() qbtypes.FieldMapper {
|
||||
return &fieldMapper{}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -253,7 +253,7 @@ func buildListLogsJSONIndexesQuery(cluster string, filters ...string) (string, [
|
||||
sb.Where(sb.Equal("database", telemetrylogs.DBName))
|
||||
sb.Where(sb.Equal("table", telemetrylogs.LogsV2LocalTableName))
|
||||
sb.Where(sb.Or(
|
||||
sb.ILike("expr", fmt.Sprintf("%%%s%%", querybuilder.FormatValueForContains(constants.BodyJSONColumnPrefix))),
|
||||
sb.ILike("expr", fmt.Sprintf("%%%s%%", querybuilder.FormatValueForContains(constants.BodyV2ColumnPrefix))),
|
||||
sb.ILike("expr", fmt.Sprintf("%%%s%%", querybuilder.FormatValueForContains(constants.BodyPromotedColumnPrefix))),
|
||||
))
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ func TestBuildListLogsJSONIndexesQuery(t *testing.T) {
|
||||
expectedArgs: []any{
|
||||
telemetrylogs.DBName,
|
||||
telemetrylogs.LogsV2LocalTableName,
|
||||
fmt.Sprintf("%%%s%%", querybuilder.FormatValueForContains(constants.BodyJSONColumnPrefix)),
|
||||
fmt.Sprintf("%%%s%%", querybuilder.FormatValueForContains(constants.BodyV2ColumnPrefix)),
|
||||
fmt.Sprintf("%%%s%%", querybuilder.FormatValueForContains(constants.BodyPromotedColumnPrefix)),
|
||||
},
|
||||
},
|
||||
@@ -130,7 +130,7 @@ func TestBuildListLogsJSONIndexesQuery(t *testing.T) {
|
||||
expectedArgs: []any{
|
||||
telemetrylogs.DBName,
|
||||
telemetrylogs.LogsV2LocalTableName,
|
||||
fmt.Sprintf("%%%s%%", querybuilder.FormatValueForContains(constants.BodyJSONColumnPrefix)),
|
||||
fmt.Sprintf("%%%s%%", querybuilder.FormatValueForContains(constants.BodyV2ColumnPrefix)),
|
||||
fmt.Sprintf("%%%s%%", querybuilder.FormatValueForContains(constants.BodyPromotedColumnPrefix)),
|
||||
fmt.Sprintf("%%%s%%", querybuilder.FormatValueForContains("foo")),
|
||||
fmt.Sprintf("%%%s%%", querybuilder.FormatValueForContains("bar")),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package alertmanagertypes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
@@ -90,8 +91,8 @@ func NewDeprecatedGettableAlertsFromGettableAlerts(gettableAlerts GettableAlerts
|
||||
}
|
||||
|
||||
// Converts a slice of PostableAlert to a slice of Alert.
|
||||
func NewAlertsFromPostableAlerts(postableAlerts PostableAlerts, resolveTimeout time.Duration, now time.Time) ([]*types.Alert, []error) {
|
||||
alerts := v2.OpenAPIAlertsToAlerts(postableAlerts)
|
||||
func NewAlertsFromPostableAlerts(postableAlerts PostableAlerts, resolveTimeout time.Duration, now time.Time, ctx context.Context) ([]*types.Alert, []error) {
|
||||
alerts := v2.OpenAPIAlertsToAlerts(ctx, postableAlerts)
|
||||
|
||||
for _, alert := range alerts {
|
||||
alert.UpdatedAt = now
|
||||
@@ -196,8 +197,15 @@ func NewGettableAlertsFromAlertProvider(
|
||||
if err = iterator.Err(); err != nil {
|
||||
break
|
||||
}
|
||||
if a == nil {
|
||||
break
|
||||
}
|
||||
alertData := a.Data
|
||||
if alertData == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
routes := dispatch.NewRoute(cfg.alertmanagerConfig.Route, nil).Match(a.Labels)
|
||||
routes := dispatch.NewRoute(cfg.alertmanagerConfig.Route, nil).Match(alertData.Labels)
|
||||
receivers := make([]string, 0, len(routes))
|
||||
for _, r := range routes {
|
||||
receivers = append(receivers, r.RouteOpts.Receiver)
|
||||
@@ -207,11 +215,11 @@ func NewGettableAlertsFromAlertProvider(
|
||||
continue
|
||||
}
|
||||
|
||||
if !alertFilter(a, now) {
|
||||
if !alertFilter(alertData, now) {
|
||||
continue
|
||||
}
|
||||
|
||||
alert := v2.AlertToOpenAPIAlert(a, getAlertStatusFunc(a.Fingerprint()), receivers, nil)
|
||||
alert := v2.AlertToOpenAPIAlert(alertData, getAlertStatusFunc(alertData.Fingerprint()), receivers, nil)
|
||||
|
||||
res = append(res, alert)
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ func TestNewConfigFromChannels(t *testing.T) {
|
||||
"require_tls": true,
|
||||
"html": "{{ template \"email.default.html\" . }}",
|
||||
"tls_config": map[string]any{"insecure_skip_verify": false},
|
||||
"threading": map[string]any{},
|
||||
}},
|
||||
},
|
||||
},
|
||||
@@ -62,6 +63,7 @@ func TestNewConfigFromChannels(t *testing.T) {
|
||||
"slack_configs": []any{map[string]any{
|
||||
"send_resolved": true,
|
||||
"api_url": "https://slack.com/api/test",
|
||||
"app_url": "https://slack.com/api/chat.postMessage",
|
||||
"channel": "#alerts",
|
||||
"callback_id": "{{ template \"slack.default.callbackid\" . }}",
|
||||
"color": "{{ if eq .Status \"firing\" }}danger{{ else }}good{{ end }}",
|
||||
@@ -71,6 +73,7 @@ func TestNewConfigFromChannels(t *testing.T) {
|
||||
"icon_url": "{{ template \"slack.default.iconurl\" . }}",
|
||||
"pretext": "{{ template \"slack.default.pretext\" . }}",
|
||||
"text": "{{ template \"slack.default.text\" . }}",
|
||||
"timeout": float64(0),
|
||||
"title": "{{ template \"slack.default.title\" . }}",
|
||||
"title_link": "{{ template \"slack.default.titlelink\" . }}",
|
||||
"username": "{{ template \"slack.default.username\" . }}",
|
||||
@@ -106,11 +109,12 @@ func TestNewConfigFromChannels(t *testing.T) {
|
||||
"client_url": "{{ template \"pagerduty.default.clientURL\" . }}",
|
||||
"description": "{{ template \"pagerduty.default.description\" .}}",
|
||||
"source": "{{ template \"pagerduty.default.client\" . }}",
|
||||
"timeout": float64(0),
|
||||
"details": map[string]any{
|
||||
"firing": "{{ template \"pagerduty.default.instances\" .Alerts.Firing }}",
|
||||
"firing": "{{ .Alerts.Firing | toJson }}",
|
||||
"num_firing": "{{ .Alerts.Firing | len }}",
|
||||
"num_resolved": "{{ .Alerts.Resolved | len }}",
|
||||
"resolved": "{{ template \"pagerduty.default.instances\" .Alerts.Resolved }}",
|
||||
"resolved": "{{ .Alerts.Resolved | toJson }}",
|
||||
},
|
||||
"http_config": map[string]any{
|
||||
"tls_config": map[string]any{"insecure_skip_verify": false},
|
||||
@@ -149,11 +153,12 @@ func TestNewConfigFromChannels(t *testing.T) {
|
||||
"client_url": "{{ template \"pagerduty.default.clientURL\" . }}",
|
||||
"description": "{{ template \"pagerduty.default.description\" .}}",
|
||||
"source": "{{ template \"pagerduty.default.client\" . }}",
|
||||
"timeout": float64(0),
|
||||
"details": map[string]any{
|
||||
"firing": "{{ template \"pagerduty.default.instances\" .Alerts.Firing }}",
|
||||
"firing": "{{ .Alerts.Firing | toJson }}",
|
||||
"num_firing": "{{ .Alerts.Firing | len }}",
|
||||
"num_resolved": "{{ .Alerts.Resolved | len }}",
|
||||
"resolved": "{{ template \"pagerduty.default.instances\" .Alerts.Resolved }}",
|
||||
"resolved": "{{ .Alerts.Resolved | toJson }}",
|
||||
},
|
||||
"http_config": map[string]any{
|
||||
"tls_config": map[string]any{"insecure_skip_verify": false},
|
||||
@@ -168,6 +173,7 @@ func TestNewConfigFromChannels(t *testing.T) {
|
||||
"slack_configs": []any{map[string]any{
|
||||
"send_resolved": true,
|
||||
"api_url": "https://slack.com/api/test",
|
||||
"app_url": "https://slack.com/api/chat.postMessage",
|
||||
"channel": "#alerts",
|
||||
"callback_id": "{{ template \"slack.default.callbackid\" . }}",
|
||||
"color": "{{ if eq .Status \"firing\" }}danger{{ else }}good{{ end }}",
|
||||
@@ -177,6 +183,7 @@ func TestNewConfigFromChannels(t *testing.T) {
|
||||
"icon_url": "{{ template \"slack.default.iconurl\" . }}",
|
||||
"pretext": "{{ template \"slack.default.pretext\" . }}",
|
||||
"text": "{{ template \"slack.default.text\" . }}",
|
||||
"timeout": float64(0),
|
||||
"title": "{{ template \"slack.default.title\" . }}",
|
||||
"title_link": "{{ template \"slack.default.titlelink\" . }}",
|
||||
"username": "{{ template \"slack.default.username\" . }}",
|
||||
@@ -270,7 +277,7 @@ func TestNewChannelFromReceiver(t *testing.T) {
|
||||
expected: &Channel{
|
||||
Name: "test-receiver",
|
||||
Type: "slack",
|
||||
Data: `{"name":"test-receiver","slack_configs":[{"send_resolved":true,"api_url":"https://slack.com/api/test","channel":"#alerts"}]}`,
|
||||
Data: `{"name":"test-receiver","slack_configs":[{"send_resolved":true,"api_url":"https://slack.com/api/test","channel":"#alerts","timeout":0}]}`,
|
||||
},
|
||||
pass: true,
|
||||
},
|
||||
|
||||
@@ -36,8 +36,8 @@ func (i *PromotePath) ValidateAndSetDefaults() error {
|
||||
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "array paths can not be promoted or indexed")
|
||||
}
|
||||
|
||||
if strings.HasPrefix(i.Path, constants.BodyJSONColumnPrefix) || strings.HasPrefix(i.Path, constants.BodyPromotedColumnPrefix) {
|
||||
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "`%s`, `%s` don't add these prefixes to the path", constants.BodyJSONColumnPrefix, constants.BodyPromotedColumnPrefix)
|
||||
if strings.HasPrefix(i.Path, constants.BodyV2ColumnPrefix) || strings.HasPrefix(i.Path, constants.BodyPromotedColumnPrefix) {
|
||||
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "`%s`, `%s` don't add these prefixes to the path", constants.BodyV2ColumnPrefix, constants.BodyPromotedColumnPrefix)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(i.Path, telemetrytypes.BodyJSONStringSearchPrefix) {
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package rulestatehistorytypes
|
||||
|
||||
import qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
|
||||
// V2HistoryBaseQueryParams defines URL query params common across v2 rule history APIs.
|
||||
type V2HistoryBaseQueryParams struct {
|
||||
Start int64 `query:"start" required:"true"`
|
||||
End int64 `query:"end" required:"true"`
|
||||
}
|
||||
|
||||
// V2HistoryTimelineQueryParams defines URL query params for timeline API.
|
||||
type V2HistoryTimelineQueryParams struct {
|
||||
Start int64 `query:"start" required:"true"`
|
||||
End int64 `query:"end" required:"true"`
|
||||
State AlertState `query:"state"`
|
||||
FilterExpression string `query:"filterExpression"`
|
||||
Limit int64 `query:"limit"`
|
||||
Order qbtypes.OrderDirection `query:"order"`
|
||||
Cursor string `query:"cursor"`
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package rulestatehistorytypes
|
||||
|
||||
import (
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
)
|
||||
|
||||
type Query struct {
|
||||
Start int64
|
||||
End int64
|
||||
State AlertState
|
||||
FilterExpression qbtypes.Filter
|
||||
Limit int64
|
||||
Offset int64
|
||||
Order qbtypes.OrderDirection
|
||||
}
|
||||
|
||||
func (q *Query) Validate() error {
|
||||
if q.Start == 0 || q.End == 0 {
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "start and end are required")
|
||||
}
|
||||
if q.Start >= q.End {
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "start must be less than end")
|
||||
}
|
||||
if q.Limit < 0 || q.Offset < 0 {
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "limit and offset must be greater than or equal to 0")
|
||||
}
|
||||
if q.Order.IsZero() {
|
||||
q.Order = qbtypes.OrderDirectionDesc
|
||||
}
|
||||
if q.Order != qbtypes.OrderDirectionAsc && q.Order != qbtypes.OrderDirectionDesc {
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "order must be asc or desc")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package rulestatehistorytypes
|
||||
|
||||
import (
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
)
|
||||
|
||||
type RuleStateTimelineResponse struct {
|
||||
Items []RuleStateHistoryResponseItem `json:"items" required:"true"`
|
||||
Total uint64 `json:"total" required:"true"`
|
||||
NextCursor string `json:"nextCursor,omitempty"`
|
||||
}
|
||||
|
||||
type RuleStateHistoryResponseItem struct {
|
||||
RuleID string `json:"ruleID" required:"true"`
|
||||
RuleName string `json:"ruleName" required:"true"`
|
||||
OverallState AlertState `json:"overallState" required:"true"`
|
||||
OverallStateChanged bool `json:"overallStateChanged" required:"true"`
|
||||
State AlertState `json:"state" required:"true"`
|
||||
StateChanged bool `json:"stateChanged" required:"true"`
|
||||
UnixMilli int64 `json:"unixMilli" required:"true"`
|
||||
Labels []*qbtypes.Label `json:"labels" required:"true"`
|
||||
Fingerprint uint64 `json:"fingerprint" required:"true"`
|
||||
Value float64 `json:"value" required:"true"`
|
||||
}
|
||||
|
||||
type RuleStateHistoryContributorResponse struct {
|
||||
Fingerprint uint64 `json:"fingerprint" required:"true"`
|
||||
Labels []*qbtypes.Label `json:"labels" required:"true"`
|
||||
Count uint64 `json:"count" required:"true"`
|
||||
RelatedTracesLink string `json:"relatedTracesLink,omitempty"`
|
||||
RelatedLogsLink string `json:"relatedLogsLink,omitempty"`
|
||||
}
|
||||
|
||||
type RuleStateWindow struct {
|
||||
State AlertState `json:"state" ch:"state" required:"true"`
|
||||
Start int64 `json:"start" ch:"start" required:"true"`
|
||||
End int64 `json:"end" ch:"end" required:"true"`
|
||||
}
|
||||
|
||||
type Stats struct {
|
||||
TotalCurrentTriggers uint64 `json:"totalCurrentTriggers" required:"true"`
|
||||
TotalPastTriggers uint64 `json:"totalPastTriggers" required:"true"`
|
||||
CurrentTriggersSeries *qbtypes.TimeSeries `json:"currentTriggersSeries" required:"true" nullable:"true"`
|
||||
PastTriggersSeries *qbtypes.TimeSeries `json:"pastTriggersSeries" required:"true" nullable:"true"`
|
||||
CurrentAvgResolutionTime float64 `json:"currentAvgResolutionTime" required:"true"`
|
||||
PastAvgResolutionTime float64 `json:"pastAvgResolutionTime" required:"true"`
|
||||
CurrentAvgResolutionTimeSeries *qbtypes.TimeSeries `json:"currentAvgResolutionTimeSeries" required:"true" nullable:"true"`
|
||||
PastAvgResolutionTimeSeries *qbtypes.TimeSeries `json:"pastAvgResolutionTimeSeries" required:"true" nullable:"true"`
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
package rulestatehistorytypes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql/driver"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
)
|
||||
|
||||
type AlertState struct {
|
||||
valuer.String
|
||||
}
|
||||
|
||||
var (
|
||||
StateInactive = AlertState{valuer.NewString("inactive")}
|
||||
StatePending = AlertState{valuer.NewString("pending")}
|
||||
StateRecovering = AlertState{valuer.NewString("recovering")}
|
||||
StateFiring = AlertState{valuer.NewString("firing")}
|
||||
StateNoData = AlertState{valuer.NewString("nodata")}
|
||||
StateDisabled = AlertState{valuer.NewString("disabled")}
|
||||
)
|
||||
|
||||
type LabelsString string
|
||||
|
||||
func (AlertState) Enum() []any {
|
||||
return []any{
|
||||
StateInactive,
|
||||
StatePending,
|
||||
StateRecovering,
|
||||
StateFiring,
|
||||
StateNoData,
|
||||
StateDisabled,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LabelsString) Scan(src any) error {
|
||||
switch data := src.(type) {
|
||||
case nil:
|
||||
*l = ""
|
||||
case string:
|
||||
*l = LabelsString(data)
|
||||
case []byte:
|
||||
*l = LabelsString(string(data))
|
||||
default:
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "unsupported labels type")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l LabelsString) Value() (driver.Value, error) {
|
||||
return string(l), nil
|
||||
}
|
||||
|
||||
type RuleStateHistory struct {
|
||||
RuleID string `ch:"rule_id"`
|
||||
RuleName string `ch:"rule_name"`
|
||||
|
||||
OverallState AlertState `ch:"overall_state"`
|
||||
OverallStateChanged bool `ch:"overall_state_changed"`
|
||||
|
||||
State AlertState `ch:"state"`
|
||||
StateChanged bool `ch:"state_changed"`
|
||||
UnixMilli int64 `ch:"unix_milli"`
|
||||
Labels LabelsString `ch:"labels"`
|
||||
Fingerprint uint64 `ch:"fingerprint"`
|
||||
Value float64 `ch:"value"`
|
||||
}
|
||||
|
||||
type RuleStateHistoryContributor struct {
|
||||
Fingerprint uint64 `ch:"fingerprint"`
|
||||
Labels LabelsString `ch:"labels"`
|
||||
Count uint64 `ch:"count"`
|
||||
RelatedTracesLink string
|
||||
RelatedLogsLink string
|
||||
}
|
||||
|
||||
type Store interface {
|
||||
AddRuleStateHistory(ctx context.Context, entries []RuleStateHistory) error
|
||||
GetLastSavedRuleStateHistory(ctx context.Context, ruleID string) ([]RuleStateHistory, error)
|
||||
ReadRuleStateHistoryByRuleID(ctx context.Context, ruleID string, query *Query) ([]RuleStateHistory, uint64, error)
|
||||
ReadRuleStateHistoryFilterKeysByRuleID(ctx context.Context, ruleID string, query *Query, search string, limit int64) (*telemetrytypes.GettableFieldKeys, error)
|
||||
ReadRuleStateHistoryFilterValuesByRuleID(ctx context.Context, ruleID string, key string, query *Query, search string, limit int64) (*telemetrytypes.GettableFieldValues, error)
|
||||
ReadRuleStateHistoryTopContributorsByRuleID(ctx context.Context, ruleID string, query *Query) ([]RuleStateHistoryContributor, error)
|
||||
GetOverallStateTransitions(ctx context.Context, ruleID string, query *Query) ([]RuleStateWindow, error)
|
||||
GetTotalTriggers(ctx context.Context, ruleID string, query *Query) (uint64, error)
|
||||
GetTriggersByInterval(ctx context.Context, ruleID string, query *Query) (*qbtypes.TimeSeries, error)
|
||||
GetAvgResolutionTime(ctx context.Context, ruleID string, query *Query) (float64, error)
|
||||
GetAvgResolutionTimeByInterval(ctx context.Context, ruleID string, query *Query) (*qbtypes.TimeSeries, error)
|
||||
}
|
||||
Reference in New Issue
Block a user