mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 20:38:59 +08:00
chore: add total count and state filter (#5745)
This commit is contained in:
parent
d7fd1d032b
commit
b798518aa9
@ -5223,7 +5223,7 @@ func (r *ClickHouseReader) AddRuleStateHistory(ctx context.Context, ruleStateHis
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *ClickHouseReader) ReadRuleStateHistoryByRuleID(
|
func (r *ClickHouseReader) ReadRuleStateHistoryByRuleID(
|
||||||
ctx context.Context, ruleID string, params *v3.QueryRuleStateHistory) ([]v3.RuleStateHistory, error) {
|
ctx context.Context, ruleID string, params *v3.QueryRuleStateHistory) (*v3.RuleStateTimeline, error) {
|
||||||
|
|
||||||
var conditions []string
|
var conditions []string
|
||||||
|
|
||||||
@ -5231,6 +5231,10 @@ func (r *ClickHouseReader) ReadRuleStateHistoryByRuleID(
|
|||||||
|
|
||||||
conditions = append(conditions, fmt.Sprintf("unix_milli >= %d AND unix_milli < %d", params.Start, params.End))
|
conditions = append(conditions, fmt.Sprintf("unix_milli >= %d AND unix_milli < %d", params.Start, params.End))
|
||||||
|
|
||||||
|
if params.State != "" {
|
||||||
|
conditions = append(conditions, fmt.Sprintf("state = '%s'", params.State))
|
||||||
|
}
|
||||||
|
|
||||||
if params.Filters != nil && len(params.Filters.Items) != 0 {
|
if params.Filters != nil && len(params.Filters.Items) != 0 {
|
||||||
for _, item := range params.Filters.Items {
|
for _, item := range params.Filters.Items {
|
||||||
toFormat := item.Value
|
toFormat := item.Value
|
||||||
@ -5289,7 +5293,19 @@ func (r *ClickHouseReader) ReadRuleStateHistoryByRuleID(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return history, nil
|
var total uint64
|
||||||
|
err = r.db.QueryRow(ctx, fmt.Sprintf("SELECT count(*) FROM %s.%s WHERE %s",
|
||||||
|
signozHistoryDBName, ruleStateHistoryTableName, whereClause)).Scan(&total)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
timeline := &v3.RuleStateTimeline{
|
||||||
|
Items: history,
|
||||||
|
Total: total,
|
||||||
|
}
|
||||||
|
|
||||||
|
return timeline, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ClickHouseReader) ReadRuleStateHistoryTopContributorsByRuleID(
|
func (r *ClickHouseReader) ReadRuleStateHistoryTopContributorsByRuleID(
|
||||||
|
@ -716,6 +716,13 @@ func (aH *APIHandler) getRuleStats(w http.ResponseWriter, r *http.Request) {
|
|||||||
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if math.IsNaN(currentAvgResolutionTime) || math.IsInf(currentAvgResolutionTime, 0) {
|
||||||
|
currentAvgResolutionTime = 0
|
||||||
|
}
|
||||||
|
if math.IsNaN(pastAvgResolutionTime) || math.IsInf(pastAvgResolutionTime, 0) {
|
||||||
|
pastAvgResolutionTime = 0
|
||||||
|
}
|
||||||
|
|
||||||
stats := v3.Stats{
|
stats := v3.Stats{
|
||||||
TotalCurrentTriggers: totalCurrentTriggers,
|
TotalCurrentTriggers: totalCurrentTriggers,
|
||||||
TotalPastTriggers: totalPastTriggers,
|
TotalPastTriggers: totalPastTriggers,
|
||||||
@ -788,6 +795,37 @@ func (aH *APIHandler) getRuleStateHistory(w http.ResponseWriter, r *http.Request
|
|||||||
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rule, err := aH.ruleManager.GetRule(r.Context(), ruleID)
|
||||||
|
if err == nil {
|
||||||
|
for idx := range res.Items {
|
||||||
|
lbls := make(map[string]string)
|
||||||
|
err := json.Unmarshal([]byte(res.Items[idx].Labels), &lbls)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
filterItems := []v3.FilterItem{}
|
||||||
|
if rule.AlertType == "LOGS_BASED_ALERT" || rule.AlertType == "TRACES_BASED_ALERT" {
|
||||||
|
if rule.RuleCondition.CompositeQuery != nil {
|
||||||
|
if rule.RuleCondition.QueryType() == v3.QueryTypeBuilder {
|
||||||
|
for _, query := range rule.RuleCondition.CompositeQuery.BuilderQueries {
|
||||||
|
if query.Filters != nil && len(query.Filters.Items) > 0 {
|
||||||
|
filterItems = append(filterItems, query.Filters.Items...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newFilters := common.PrepareFilters(lbls, filterItems)
|
||||||
|
ts := time.Unix(res.Items[idx].UnixMilli/1000, 0)
|
||||||
|
if rule.AlertType == "LOGS_BASED_ALERT" {
|
||||||
|
res.Items[idx].RelatedLogsLink = common.PrepareLinksToLogs(ts, newFilters)
|
||||||
|
} else if rule.AlertType == "TRACES_BASED_ALERT" {
|
||||||
|
res.Items[idx].RelatedTracesLink = common.PrepareLinksToTraces(ts, newFilters)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
aH.Respond(w, res)
|
aH.Respond(w, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,6 +843,25 @@ func (aH *APIHandler) getRuleStateHistoryTopContributors(w http.ResponseWriter,
|
|||||||
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rule, err := aH.ruleManager.GetRule(r.Context(), ruleID)
|
||||||
|
if err == nil {
|
||||||
|
for idx := range res {
|
||||||
|
lbls := make(map[string]string)
|
||||||
|
err := json.Unmarshal([]byte(res[idx].Labels), &lbls)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ts := time.Unix(params.End/1000, 0)
|
||||||
|
filters := common.PrepareFilters(lbls, nil)
|
||||||
|
if rule.AlertType == "LOGS_BASED_ALERT" {
|
||||||
|
res[idx].RelatedLogsLink = common.PrepareLinksToLogs(ts, filters)
|
||||||
|
} else if rule.AlertType == "TRACES_BASED_ALERT" {
|
||||||
|
res[idx].RelatedTracesLink = common.PrepareLinksToTraces(ts, filters)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
aH.Respond(w, res)
|
aH.Respond(w, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.signoz.io/signoz/pkg/query-service/constants"
|
"go.signoz.io/signoz/pkg/query-service/constants"
|
||||||
@ -70,3 +73,183 @@ func LCMList(nums []int64) int64 {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(srikanthccv): move the custom function in threshold_rule.go to here
|
||||||
|
func PrepareLinksToTraces(ts time.Time, filterItems []v3.FilterItem) string {
|
||||||
|
|
||||||
|
start := ts.Add(-time.Minute * 15)
|
||||||
|
end := ts.Add(time.Minute * 15)
|
||||||
|
|
||||||
|
// Traces list view expects time in nanoseconds
|
||||||
|
tr := v3.URLShareableTimeRange{
|
||||||
|
Start: start.UnixNano(),
|
||||||
|
End: end.UnixNano(),
|
||||||
|
PageSize: 100,
|
||||||
|
}
|
||||||
|
|
||||||
|
options := v3.URLShareableOptions{
|
||||||
|
MaxLines: 2,
|
||||||
|
Format: "list",
|
||||||
|
SelectColumns: constants.TracesListViewDefaultSelectedColumns,
|
||||||
|
}
|
||||||
|
|
||||||
|
period, _ := json.Marshal(tr)
|
||||||
|
urlEncodedTimeRange := url.QueryEscape(string(period))
|
||||||
|
|
||||||
|
urlData := v3.URLShareableCompositeQuery{
|
||||||
|
QueryType: string(v3.QueryTypeBuilder),
|
||||||
|
Builder: v3.URLShareableBuilderQuery{
|
||||||
|
QueryData: []v3.BuilderQuery{
|
||||||
|
{
|
||||||
|
DataSource: v3.DataSourceTraces,
|
||||||
|
QueryName: "A",
|
||||||
|
AggregateOperator: v3.AggregateOperatorNoOp,
|
||||||
|
AggregateAttribute: v3.AttributeKey{},
|
||||||
|
Filters: &v3.FilterSet{
|
||||||
|
Items: filterItems,
|
||||||
|
Operator: "AND",
|
||||||
|
},
|
||||||
|
Expression: "A",
|
||||||
|
Disabled: false,
|
||||||
|
Having: []v3.Having{},
|
||||||
|
StepInterval: 60,
|
||||||
|
OrderBy: []v3.OrderBy{
|
||||||
|
{
|
||||||
|
ColumnName: "timestamp",
|
||||||
|
Order: "desc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
QueryFormulas: make([]string, 0),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
data, _ := json.Marshal(urlData)
|
||||||
|
compositeQuery := url.QueryEscape(string(data))
|
||||||
|
|
||||||
|
optionsData, _ := json.Marshal(options)
|
||||||
|
urlEncodedOptions := url.QueryEscape(string(optionsData))
|
||||||
|
|
||||||
|
return fmt.Sprintf("compositeQuery=%s&timeRange=%s&startTime=%d&endTime=%d&options=%s", compositeQuery, urlEncodedTimeRange, tr.Start, tr.End, urlEncodedOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PrepareLinksToLogs(ts time.Time, filterItems []v3.FilterItem) string {
|
||||||
|
start := ts.Add(-time.Minute * 15)
|
||||||
|
end := ts.Add(time.Minute * 15)
|
||||||
|
|
||||||
|
// Logs list view expects time in milliseconds
|
||||||
|
// Logs list view expects time in milliseconds
|
||||||
|
tr := v3.URLShareableTimeRange{
|
||||||
|
Start: start.UnixMilli(),
|
||||||
|
End: end.UnixMilli(),
|
||||||
|
PageSize: 100,
|
||||||
|
}
|
||||||
|
|
||||||
|
options := v3.URLShareableOptions{
|
||||||
|
MaxLines: 2,
|
||||||
|
Format: "list",
|
||||||
|
SelectColumns: []v3.AttributeKey{},
|
||||||
|
}
|
||||||
|
|
||||||
|
period, _ := json.Marshal(tr)
|
||||||
|
urlEncodedTimeRange := url.QueryEscape(string(period))
|
||||||
|
|
||||||
|
urlData := v3.URLShareableCompositeQuery{
|
||||||
|
QueryType: string(v3.QueryTypeBuilder),
|
||||||
|
Builder: v3.URLShareableBuilderQuery{
|
||||||
|
QueryData: []v3.BuilderQuery{
|
||||||
|
{
|
||||||
|
DataSource: v3.DataSourceLogs,
|
||||||
|
QueryName: "A",
|
||||||
|
AggregateOperator: v3.AggregateOperatorNoOp,
|
||||||
|
AggregateAttribute: v3.AttributeKey{},
|
||||||
|
Filters: &v3.FilterSet{
|
||||||
|
Items: filterItems,
|
||||||
|
Operator: "AND",
|
||||||
|
},
|
||||||
|
Expression: "A",
|
||||||
|
Disabled: false,
|
||||||
|
Having: []v3.Having{},
|
||||||
|
StepInterval: 60,
|
||||||
|
OrderBy: []v3.OrderBy{
|
||||||
|
{
|
||||||
|
ColumnName: "timestamp",
|
||||||
|
Order: "desc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
QueryFormulas: make([]string, 0),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
data, _ := json.Marshal(urlData)
|
||||||
|
compositeQuery := url.QueryEscape(string(data))
|
||||||
|
|
||||||
|
optionsData, _ := json.Marshal(options)
|
||||||
|
urlEncodedOptions := url.QueryEscape(string(optionsData))
|
||||||
|
|
||||||
|
return fmt.Sprintf("compositeQuery=%s&timeRange=%s&startTime=%d&endTime=%d&options=%s", compositeQuery, urlEncodedTimeRange, tr.Start, tr.End, urlEncodedOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following function is used to prepare the where clause for the query
|
||||||
|
// `lbls` contains the key value pairs of the labels from the result of the query
|
||||||
|
// We iterate over the where clause and replace the labels with the actual values
|
||||||
|
// There are two cases:
|
||||||
|
// 1. The label is present in the where clause
|
||||||
|
// 2. The label is not present in the where clause
|
||||||
|
//
|
||||||
|
// Example for case 2:
|
||||||
|
// Latency by serviceName without any filter
|
||||||
|
// In this case, for each service with latency > threshold we send a notification
|
||||||
|
// The expectation will be that clicking on the related traces for service A, will
|
||||||
|
// take us to the traces page with the filter serviceName=A
|
||||||
|
// So for all the missing labels in the where clause, we add them as key = value
|
||||||
|
//
|
||||||
|
// Example for case 1:
|
||||||
|
// Severity text IN (WARN, ERROR)
|
||||||
|
// In this case, the Severity text will appear in the `lbls` if it were part of the group
|
||||||
|
// by clause, in which case we replace it with the actual value for the notification
|
||||||
|
// i.e Severity text = WARN
|
||||||
|
// If the Severity text is not part of the group by clause, then we add it as it is
|
||||||
|
func PrepareFilters(labels map[string]string, filters []v3.FilterItem) []v3.FilterItem {
|
||||||
|
var filterItems []v3.FilterItem
|
||||||
|
|
||||||
|
added := make(map[string]struct{})
|
||||||
|
|
||||||
|
for _, item := range filters {
|
||||||
|
exists := false
|
||||||
|
for key, value := range labels {
|
||||||
|
if item.Key.Key == key {
|
||||||
|
// if the label is present in the where clause, replace it with key = value
|
||||||
|
filterItems = append(filterItems, v3.FilterItem{
|
||||||
|
Key: item.Key,
|
||||||
|
Operator: v3.FilterOperatorEqual,
|
||||||
|
Value: value,
|
||||||
|
})
|
||||||
|
exists = true
|
||||||
|
added[key] = struct{}{}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
// if the label is not present in the where clause, add it as it is
|
||||||
|
filterItems = append(filterItems, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the labels which are not present in the where clause
|
||||||
|
for key, value := range labels {
|
||||||
|
if _, ok := added[key]; !ok {
|
||||||
|
filterItems = append(filterItems, v3.FilterItem{
|
||||||
|
Key: v3.AttributeKey{Key: key},
|
||||||
|
Operator: v3.FilterOperatorEqual,
|
||||||
|
Value: value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filterItems
|
||||||
|
}
|
||||||
|
@ -110,7 +110,7 @@ type Reader interface {
|
|||||||
|
|
||||||
AddRuleStateHistory(ctx context.Context, ruleStateHistory []v3.RuleStateHistory) error
|
AddRuleStateHistory(ctx context.Context, ruleStateHistory []v3.RuleStateHistory) error
|
||||||
GetOverallStateTransitions(ctx context.Context, ruleID string, params *v3.QueryRuleStateHistory) ([]v3.RuleStateTransition, error)
|
GetOverallStateTransitions(ctx context.Context, ruleID string, params *v3.QueryRuleStateHistory) ([]v3.RuleStateTransition, error)
|
||||||
ReadRuleStateHistoryByRuleID(ctx context.Context, ruleID string, params *v3.QueryRuleStateHistory) ([]v3.RuleStateHistory, error)
|
ReadRuleStateHistoryByRuleID(ctx context.Context, ruleID string, params *v3.QueryRuleStateHistory) (*v3.RuleStateTimeline, error)
|
||||||
GetTotalTriggers(ctx context.Context, ruleID string, params *v3.QueryRuleStateHistory) (uint64, error)
|
GetTotalTriggers(ctx context.Context, ruleID string, params *v3.QueryRuleStateHistory) (uint64, error)
|
||||||
GetTriggersByInterval(ctx context.Context, ruleID string, params *v3.QueryRuleStateHistory) (*v3.Series, error)
|
GetTriggersByInterval(ctx context.Context, ruleID string, params *v3.QueryRuleStateHistory) (*v3.Series, error)
|
||||||
GetAvgResolutionTime(ctx context.Context, ruleID string, params *v3.QueryRuleStateHistory) (float64, error)
|
GetAvgResolutionTime(ctx context.Context, ruleID string, params *v3.QueryRuleStateHistory) (float64, error)
|
||||||
|
@ -1181,6 +1181,11 @@ func (l LabelsString) String() string {
|
|||||||
return string(l)
|
return string(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RuleStateTimeline struct {
|
||||||
|
Items []RuleStateHistory `json:"items"`
|
||||||
|
Total uint64 `json:"total"`
|
||||||
|
}
|
||||||
|
|
||||||
type RuleStateHistory struct {
|
type RuleStateHistory struct {
|
||||||
RuleID string `json:"ruleID" ch:"rule_id"`
|
RuleID string `json:"ruleID" ch:"rule_id"`
|
||||||
RuleName string `json:"ruleName" ch:"rule_name"`
|
RuleName string `json:"ruleName" ch:"rule_name"`
|
||||||
@ -1194,11 +1199,15 @@ type RuleStateHistory struct {
|
|||||||
Labels LabelsString `json:"labels" ch:"labels"`
|
Labels LabelsString `json:"labels" ch:"labels"`
|
||||||
Fingerprint uint64 `json:"fingerprint" ch:"fingerprint"`
|
Fingerprint uint64 `json:"fingerprint" ch:"fingerprint"`
|
||||||
Value float64 `json:"value" ch:"value"`
|
Value float64 `json:"value" ch:"value"`
|
||||||
|
|
||||||
|
RelatedTracesLink string `json:"relatedTracesLink"`
|
||||||
|
RelatedLogsLink string `json:"relatedLogsLink"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type QueryRuleStateHistory struct {
|
type QueryRuleStateHistory struct {
|
||||||
Start int64 `json:"start"`
|
Start int64 `json:"start"`
|
||||||
End int64 `json:"end"`
|
End int64 `json:"end"`
|
||||||
|
State string `json:"state"`
|
||||||
Filters *FilterSet `json:"filters"`
|
Filters *FilterSet `json:"filters"`
|
||||||
Offset int64 `json:"offset"`
|
Offset int64 `json:"offset"`
|
||||||
Limit int64 `json:"limit"`
|
Limit int64 `json:"limit"`
|
||||||
@ -1222,6 +1231,8 @@ type RuleStateHistoryContributor struct {
|
|||||||
Fingerprint uint64 `json:"fingerprint" ch:"fingerprint"`
|
Fingerprint uint64 `json:"fingerprint" ch:"fingerprint"`
|
||||||
Labels LabelsString `json:"labels" ch:"labels"`
|
Labels LabelsString `json:"labels" ch:"labels"`
|
||||||
Count uint64 `json:"count" ch:"count"`
|
Count uint64 `json:"count" ch:"count"`
|
||||||
|
RelatedTracesLink string `json:"relatedTracesLink"`
|
||||||
|
RelatedLogsLink string `json:"relatedLogsLink"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RuleStateTransition struct {
|
type RuleStateTransition struct {
|
||||||
@ -1255,3 +1266,25 @@ type QueryProgress struct {
|
|||||||
|
|
||||||
ElapsedMs uint64 `json:"elapsed_ms"`
|
ElapsedMs uint64 `json:"elapsed_ms"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type URLShareableTimeRange struct {
|
||||||
|
Start int64 `json:"start"`
|
||||||
|
End int64 `json:"end"`
|
||||||
|
PageSize int64 `json:"pageSize"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type URLShareableBuilderQuery struct {
|
||||||
|
QueryData []BuilderQuery `json:"queryData"`
|
||||||
|
QueryFormulas []string `json:"queryFormulas"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type URLShareableCompositeQuery struct {
|
||||||
|
QueryType string `json:"queryType"`
|
||||||
|
Builder URLShareableBuilderQuery `json:"builder"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type URLShareableOptions struct {
|
||||||
|
MaxLines int `json:"maxLines"`
|
||||||
|
Format string `json:"format"`
|
||||||
|
SelectColumns []AttributeKey `json:"selectColumns"`
|
||||||
|
}
|
||||||
|
@ -67,6 +67,8 @@ type Alert struct {
|
|||||||
Labels labels.BaseLabels
|
Labels labels.BaseLabels
|
||||||
Annotations labels.BaseLabels
|
Annotations labels.BaseLabels
|
||||||
|
|
||||||
|
QueryResultLables labels.BaseLabels
|
||||||
|
|
||||||
GeneratorURL string
|
GeneratorURL string
|
||||||
|
|
||||||
// list of preferred receivers, e.g. slack
|
// list of preferred receivers, e.g. slack
|
||||||
|
@ -242,25 +242,3 @@ type GettableRule struct {
|
|||||||
UpdatedAt *time.Time `json:"updateAt"`
|
UpdatedAt *time.Time `json:"updateAt"`
|
||||||
UpdatedBy *string `json:"updateBy"`
|
UpdatedBy *string `json:"updateBy"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type timeRange struct {
|
|
||||||
Start int64 `json:"start"`
|
|
||||||
End int64 `json:"end"`
|
|
||||||
PageSize int64 `json:"pageSize"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type builderQuery struct {
|
|
||||||
QueryData []v3.BuilderQuery `json:"queryData"`
|
|
||||||
QueryFormulas []string `json:"queryFormulas"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type urlShareableCompositeQuery struct {
|
|
||||||
QueryType string `json:"queryType"`
|
|
||||||
Builder builderQuery `json:"builder"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Options struct {
|
|
||||||
MaxLines int `json:"maxLines"`
|
|
||||||
Format string `json:"format"`
|
|
||||||
SelectColumns []v3.AttributeKey `json:"selectColumns"`
|
|
||||||
}
|
|
||||||
|
@ -411,6 +411,7 @@ func (r *PromRule) Eval(ctx context.Context, ts time.Time, queriers *Queriers) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
lb := plabels.NewBuilder(alertSmpl.Metric).Del(plabels.MetricName)
|
lb := plabels.NewBuilder(alertSmpl.Metric).Del(plabels.MetricName)
|
||||||
|
resultLabels := plabels.NewBuilder(alertSmpl.Metric).Del(plabels.MetricName).Labels()
|
||||||
|
|
||||||
for _, l := range r.labels {
|
for _, l := range r.labels {
|
||||||
lb.Set(l.Name, expand(l.Value))
|
lb.Set(l.Name, expand(l.Value))
|
||||||
@ -440,6 +441,7 @@ func (r *PromRule) Eval(ctx context.Context, ts time.Time, queriers *Queriers) (
|
|||||||
|
|
||||||
alerts[h] = &Alert{
|
alerts[h] = &Alert{
|
||||||
Labels: lbs,
|
Labels: lbs,
|
||||||
|
QueryResultLables: resultLabels,
|
||||||
Annotations: annotations,
|
Annotations: annotations,
|
||||||
ActiveAt: ts,
|
ActiveAt: ts,
|
||||||
State: StatePending,
|
State: StatePending,
|
||||||
@ -489,7 +491,7 @@ func (r *PromRule) Eval(ctx context.Context, ts time.Time, queriers *Queriers) (
|
|||||||
StateChanged: true,
|
StateChanged: true,
|
||||||
UnixMilli: ts.UnixMilli(),
|
UnixMilli: ts.UnixMilli(),
|
||||||
Labels: v3.LabelsString(labelsJSON),
|
Labels: v3.LabelsString(labelsJSON),
|
||||||
Fingerprint: a.Labels.Hash(),
|
Fingerprint: a.QueryResultLables.Hash(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@ -509,7 +511,7 @@ func (r *PromRule) Eval(ctx context.Context, ts time.Time, queriers *Queriers) (
|
|||||||
StateChanged: true,
|
StateChanged: true,
|
||||||
UnixMilli: ts.UnixMilli(),
|
UnixMilli: ts.UnixMilli(),
|
||||||
Labels: v3.LabelsString(labelsJSON),
|
Labels: v3.LabelsString(labelsJSON),
|
||||||
Fingerprint: a.Labels.Hash(),
|
Fingerprint: a.QueryResultLables.Hash(),
|
||||||
Value: a.Value,
|
Value: a.Value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -625,13 +625,13 @@ func (r *ThresholdRule) prepareLinksToLogs(ts time.Time, lbls labels.Labels) str
|
|||||||
|
|
||||||
q := r.prepareQueryRange(ts)
|
q := r.prepareQueryRange(ts)
|
||||||
// Logs list view expects time in milliseconds
|
// Logs list view expects time in milliseconds
|
||||||
tr := timeRange{
|
tr := v3.URLShareableTimeRange{
|
||||||
Start: q.Start,
|
Start: q.Start,
|
||||||
End: q.End,
|
End: q.End,
|
||||||
PageSize: 100,
|
PageSize: 100,
|
||||||
}
|
}
|
||||||
|
|
||||||
options := Options{
|
options := v3.URLShareableOptions{
|
||||||
MaxLines: 2,
|
MaxLines: 2,
|
||||||
Format: "list",
|
Format: "list",
|
||||||
SelectColumns: []v3.AttributeKey{},
|
SelectColumns: []v3.AttributeKey{},
|
||||||
@ -641,9 +641,9 @@ func (r *ThresholdRule) prepareLinksToLogs(ts time.Time, lbls labels.Labels) str
|
|||||||
urlEncodedTimeRange := url.QueryEscape(string(period))
|
urlEncodedTimeRange := url.QueryEscape(string(period))
|
||||||
|
|
||||||
filterItems := r.fetchFilters(selectedQuery, lbls)
|
filterItems := r.fetchFilters(selectedQuery, lbls)
|
||||||
urlData := urlShareableCompositeQuery{
|
urlData := v3.URLShareableCompositeQuery{
|
||||||
QueryType: string(v3.QueryTypeBuilder),
|
QueryType: string(v3.QueryTypeBuilder),
|
||||||
Builder: builderQuery{
|
Builder: v3.URLShareableBuilderQuery{
|
||||||
QueryData: []v3.BuilderQuery{
|
QueryData: []v3.BuilderQuery{
|
||||||
{
|
{
|
||||||
DataSource: v3.DataSourceLogs,
|
DataSource: v3.DataSourceLogs,
|
||||||
@ -689,13 +689,13 @@ func (r *ThresholdRule) prepareLinksToTraces(ts time.Time, lbls labels.Labels) s
|
|||||||
|
|
||||||
q := r.prepareQueryRange(ts)
|
q := r.prepareQueryRange(ts)
|
||||||
// Traces list view expects time in nanoseconds
|
// Traces list view expects time in nanoseconds
|
||||||
tr := timeRange{
|
tr := v3.URLShareableTimeRange{
|
||||||
Start: q.Start * time.Second.Microseconds(),
|
Start: q.Start * time.Second.Microseconds(),
|
||||||
End: q.End * time.Second.Microseconds(),
|
End: q.End * time.Second.Microseconds(),
|
||||||
PageSize: 100,
|
PageSize: 100,
|
||||||
}
|
}
|
||||||
|
|
||||||
options := Options{
|
options := v3.URLShareableOptions{
|
||||||
MaxLines: 2,
|
MaxLines: 2,
|
||||||
Format: "list",
|
Format: "list",
|
||||||
SelectColumns: constants.TracesListViewDefaultSelectedColumns,
|
SelectColumns: constants.TracesListViewDefaultSelectedColumns,
|
||||||
@ -705,9 +705,9 @@ func (r *ThresholdRule) prepareLinksToTraces(ts time.Time, lbls labels.Labels) s
|
|||||||
urlEncodedTimeRange := url.QueryEscape(string(period))
|
urlEncodedTimeRange := url.QueryEscape(string(period))
|
||||||
|
|
||||||
filterItems := r.fetchFilters(selectedQuery, lbls)
|
filterItems := r.fetchFilters(selectedQuery, lbls)
|
||||||
urlData := urlShareableCompositeQuery{
|
urlData := v3.URLShareableCompositeQuery{
|
||||||
QueryType: string(v3.QueryTypeBuilder),
|
QueryType: string(v3.QueryTypeBuilder),
|
||||||
Builder: builderQuery{
|
Builder: v3.URLShareableBuilderQuery{
|
||||||
QueryData: []v3.BuilderQuery{
|
QueryData: []v3.BuilderQuery{
|
||||||
{
|
{
|
||||||
DataSource: v3.DataSourceTraces,
|
DataSource: v3.DataSourceTraces,
|
||||||
@ -954,6 +954,7 @@ func (r *ThresholdRule) Eval(ctx context.Context, ts time.Time, queriers *Querie
|
|||||||
}
|
}
|
||||||
|
|
||||||
lb := labels.NewBuilder(smpl.Metric).Del(labels.MetricNameLabel).Del(labels.TemporalityLabel)
|
lb := labels.NewBuilder(smpl.Metric).Del(labels.MetricNameLabel).Del(labels.TemporalityLabel)
|
||||||
|
resultLabels := labels.NewBuilder(smpl.MetricOrig).Del(labels.MetricNameLabel).Del(labels.TemporalityLabel).Labels()
|
||||||
|
|
||||||
for _, l := range r.labels {
|
for _, l := range r.labels {
|
||||||
lb.Set(l.Name, expand(l.Value))
|
lb.Set(l.Name, expand(l.Value))
|
||||||
@ -1002,6 +1003,7 @@ func (r *ThresholdRule) Eval(ctx context.Context, ts time.Time, queriers *Querie
|
|||||||
|
|
||||||
alerts[h] = &Alert{
|
alerts[h] = &Alert{
|
||||||
Labels: lbs,
|
Labels: lbs,
|
||||||
|
QueryResultLables: resultLabels,
|
||||||
Annotations: annotations,
|
Annotations: annotations,
|
||||||
ActiveAt: ts,
|
ActiveAt: ts,
|
||||||
State: StatePending,
|
State: StatePending,
|
||||||
@ -1034,7 +1036,7 @@ func (r *ThresholdRule) Eval(ctx context.Context, ts time.Time, queriers *Querie
|
|||||||
|
|
||||||
// Check if any pending alerts should be removed or fire now. Write out alert timeseries.
|
// Check if any pending alerts should be removed or fire now. Write out alert timeseries.
|
||||||
for fp, a := range r.active {
|
for fp, a := range r.active {
|
||||||
labelsJSON, err := json.Marshal(a.Labels)
|
labelsJSON, err := json.Marshal(a.QueryResultLables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.L().Error("error marshaling labels", zap.Error(err), zap.Any("labels", a.Labels))
|
zap.L().Error("error marshaling labels", zap.Error(err), zap.Any("labels", a.Labels))
|
||||||
}
|
}
|
||||||
@ -1054,7 +1056,7 @@ func (r *ThresholdRule) Eval(ctx context.Context, ts time.Time, queriers *Querie
|
|||||||
StateChanged: true,
|
StateChanged: true,
|
||||||
UnixMilli: ts.UnixMilli(),
|
UnixMilli: ts.UnixMilli(),
|
||||||
Labels: v3.LabelsString(labelsJSON),
|
Labels: v3.LabelsString(labelsJSON),
|
||||||
Fingerprint: a.Labels.Hash(),
|
Fingerprint: a.QueryResultLables.Hash(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@ -1074,7 +1076,7 @@ func (r *ThresholdRule) Eval(ctx context.Context, ts time.Time, queriers *Querie
|
|||||||
StateChanged: true,
|
StateChanged: true,
|
||||||
UnixMilli: ts.UnixMilli(),
|
UnixMilli: ts.UnixMilli(),
|
||||||
Labels: v3.LabelsString(labelsJSON),
|
Labels: v3.LabelsString(labelsJSON),
|
||||||
Fingerprint: a.Labels.Hash(),
|
Fingerprint: a.QueryResultLables.Hash(),
|
||||||
Value: a.Value,
|
Value: a.Value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user