2017-06-14 16:04:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Copyright 2017 The Prometheus Authors
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Licensed under the Apache License, Version 2.0 (the "License");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// you may not use this file except in compliance with the License.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// You may obtain a copy of the License at
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// http://www.apache.org/licenses/LICENSE-2.0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Unless required by applicable law or agreed to in writing, software
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// distributed under the License is distributed on an "AS IS" BASIS,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// See the License for the specific language governing permissions and
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// limitations under the License.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								package rulefmt
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								import (
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-09 21:42:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"bytes"
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 20:55:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"context"
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									"errors"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"fmt"
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-09 21:42:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"io"
							 | 
						
					
						
							
								
									
										
										
										
											2022-04-27 17:24:36 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									"os"
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-16 00:52:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"strings"
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 20:55:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"time"
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-14 17:37:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"github.com/prometheus/common/model"
							 | 
						
					
						
							
								
									
										
										
										
											2022-08-31 21:50:38 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									"gopkg.in/yaml.v3"
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-26 07:01:12 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-08 22:23:17 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"github.com/prometheus/prometheus/model/timestamp"
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-13 03:14:31 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									"github.com/prometheus/prometheus/promql"
							 | 
						
					
						
							
								
									
										
										
										
											2020-02-04 02:06:39 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"github.com/prometheus/prometheus/promql/parser"
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 20:55:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"github.com/prometheus/prometheus/template"
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-02 22:54:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Error represents semantic errors on parsing rule groups.
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type Error struct {
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 23:39:06 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Group    string
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Rule     int
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									RuleName string
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Err      WrappedError
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-13 06:38:59 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Error prints the error message in a formatted string.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (err *Error) Error() string {
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if err.Err.err == nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return ""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-13 06:38:59 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if err.Err.nodeAlt != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										return fmt.Sprintf("%d:%d: %d:%d: group %q, rule %d, %q: %v", err.Err.node.Line, err.Err.node.Column, err.Err.nodeAlt.Line, err.Err.nodeAlt.Column, err.Group, err.Rule, err.RuleName, err.Err.err)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err.Err.node != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return fmt.Sprintf("%d:%d: group %q, rule %d, %q: %v", err.Err.node.Line, err.Err.node.Column, err.Group, err.Rule, err.RuleName, err.Err.err)
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-13 06:38:59 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return fmt.Sprintf("group %q, rule %d, %q: %v", err.Group, err.Rule, err.RuleName, err.Err.err)
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-13 06:38:59 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-20 23:57:34 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Unwrap unpacks wrapped error for use in errors.Is & errors.As.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (err *Error) Unwrap() error {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return &err.Err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// WrappedError wraps error with the yaml node which can be used to represent
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// the line and column numbers of the error.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type WrappedError struct {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									err     error
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									node    *yaml.Node
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									nodeAlt *yaml.Node
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-13 06:38:59 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Error prints the error message in a formatted string.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (we *WrappedError) Error() string {
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if we.err == nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return ""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-13 06:38:59 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if we.nodeAlt != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										return fmt.Sprintf("%d:%d: %d:%d: %v", we.node.Line, we.node.Column, we.nodeAlt.Line, we.nodeAlt.Column, we.err)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if we.node != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return fmt.Sprintf("%d:%d: %v", we.node.Line, we.node.Column, we.err)
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-13 06:38:59 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return we.err.Error()
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-20 23:57:34 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Unwrap unpacks wrapped error for use in errors.Is & errors.As.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (we *WrappedError) Unwrap() error {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return we.err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// RuleGroups is a set of rule groups that are typically exposed in a file.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type RuleGroups struct {
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-19 19:08:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Groups []RuleGroup `yaml:"groups"`
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type ruleGroups struct {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Groups []yaml.Node `yaml:"groups"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Validate validates all rules in the rule groups.
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (g *RuleGroups) Validate(node ruleGroups) (errs []error) {
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-14 14:49:21 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									set := map[string]struct{}{}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for j, g := range g.Groups {
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-14 15:51:32 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if g.Name == "" {
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											errs = append(errs, fmt.Errorf("%d:%d: Groupname must not be empty", node.Groups[j].Line, node.Groups[j].Column))
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-14 15:51:32 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-14 14:49:21 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if _, ok := set[g.Name]; ok {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											errs = append(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												errs,
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												fmt.Errorf("%d:%d: groupname: \"%s\" is repeated in the same file", node.Groups[j].Line, node.Groups[j].Column, g.Name),
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-14 14:49:21 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-10-19 02:43:32 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										for k, v := range g.Labels {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if !model.LabelName(k).IsValid() || k == model.MetricNameLabel {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												errs = append(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													errs, fmt.Errorf("invalid label name: %s", k),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if !model.LabelValue(v).IsValid() {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												errs = append(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													errs, fmt.Errorf("invalid label value: %s", v),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-14 14:49:21 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										set[g.Name] = struct{}{}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										for i, r := range g.Rules {
							 | 
						
					
						
							
								
									
										
										
										
											2021-10-16 02:24:55 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											for _, node := range g.Rules[i].Validate() {
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												var ruleName yaml.Node
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												if r.Alert.Value != "" {
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 23:39:06 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													ruleName = r.Alert
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													ruleName = r.Record
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												}
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												errs = append(errs, &Error{
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 23:39:06 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													Group:    g.Name,
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-02 18:09:01 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													Rule:     i + 1,
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													RuleName: ruleName.Value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													Err:      node,
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-16 19:14:33 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return errs
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// RuleGroup is a list of sequentially evaluated recording and alerting rules.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type RuleGroup struct {
							 | 
						
					
						
							
								
									
										
										
										
											2022-10-19 02:43:32 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									Name        string            `yaml:"name"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Interval    model.Duration    `yaml:"interval,omitempty"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									QueryOffset *model.Duration   `yaml:"query_offset,omitempty"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Limit       int               `yaml:"limit,omitempty"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Rules       []RuleNode        `yaml:"rules"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Labels      map[string]string `yaml:"labels,omitempty"`
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Rule describes an alerting or recording rule.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type Rule struct {
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-09 19:21:38 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									Record        string            `yaml:"record,omitempty"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Alert         string            `yaml:"alert,omitempty"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Expr          string            `yaml:"expr"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									For           model.Duration    `yaml:"for,omitempty"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									KeepFiringFor model.Duration    `yaml:"keep_firing_for,omitempty"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Labels        map[string]string `yaml:"labels,omitempty"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Annotations   map[string]string `yaml:"annotations,omitempty"`
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// RuleNode adds yaml.v3 layer to support line and column outputs for invalid rules.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type RuleNode struct {
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-09 19:21:38 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									Record        yaml.Node         `yaml:"record,omitempty"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Alert         yaml.Node         `yaml:"alert,omitempty"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Expr          yaml.Node         `yaml:"expr"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									For           model.Duration    `yaml:"for,omitempty"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									KeepFiringFor model.Duration    `yaml:"keep_firing_for,omitempty"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Labels        map[string]string `yaml:"labels,omitempty"`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Annotations   map[string]string `yaml:"annotations,omitempty"`
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Validate the rule and return a list of encountered errors.
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *RuleNode) Validate() (nodes []WrappedError) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if r.Record.Value != "" && r.Alert.Value != "" {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										nodes = append(nodes, WrappedError{
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-03 20:15:51 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											err:     errors.New("only one of 'record' and 'alert' must be set"),
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											node:    &r.Record,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nodeAlt: &r.Alert,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										})
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if r.Record.Value == "" && r.Alert.Value == "" {
							 | 
						
					
						
							
								
									
										
										
										
											2020-03-21 21:34:00 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										nodes = append(nodes, WrappedError{
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-03 20:15:51 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											err:     errors.New("one of 'record' or 'alert' must be set"),
							 | 
						
					
						
							
								
									
										
										
										
											2020-03-21 21:34:00 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											node:    &r.Record,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nodeAlt: &r.Alert,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										})
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-14 15:51:32 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if r.Expr.Value == "" {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										nodes = append(nodes, WrappedError{
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-03 20:15:51 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											err:  errors.New("field 'expr' must be set in rule"),
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											node: &r.Expr,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										})
							 | 
						
					
						
							
								
									
										
										
										
											2020-02-04 02:06:39 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else if _, err := parser.ParseExpr(r.Expr.Value); err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										nodes = append(nodes, WrappedError{
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											err:  fmt.Errorf("could not parse expression: %w", err),
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											node: &r.Expr,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										})
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if r.Record.Value != "" {
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if len(r.Annotations) > 0 {
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nodes = append(nodes, WrappedError{
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-03 20:15:51 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												err:  errors.New("invalid field 'annotations' in recording rule"),
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												node: &r.Record,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											})
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-16 13:16:21 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if r.For != 0 {
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nodes = append(nodes, WrappedError{
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-03 20:15:51 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												err:  errors.New("invalid field 'for' in recording rule"),
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												node: &r.Record,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											})
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-09 19:21:38 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if r.KeepFiringFor != 0 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nodes = append(nodes, WrappedError{
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-03 20:15:51 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												err:  errors.New("invalid field 'keep_firing_for' in recording rule"),
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-09 19:21:38 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												node: &r.Record,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if !model.IsValidMetricName(model.LabelValue(r.Record.Value)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nodes = append(nodes, WrappedError{
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												err:  fmt.Errorf("invalid recording rule name: %s", r.Record.Value),
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												node: &r.Record,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											})
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-17 17:22:59 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-14 17:37:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for k, v := range r.Labels {
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-13 05:37:31 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if !model.LabelName(k).IsValid() || k == model.MetricNameLabel {
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nodes = append(nodes, WrappedError{
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												err: fmt.Errorf("invalid label name: %s", k),
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											})
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-14 17:37:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if !model.LabelValue(v).IsValid() {
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nodes = append(nodes, WrappedError{
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												err: fmt.Errorf("invalid label value: %s", v),
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											})
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-14 17:37:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for k := range r.Annotations {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if !model.LabelName(k).IsValid() {
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nodes = append(nodes, WrappedError{
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												err: fmt.Errorf("invalid annotation name: %s", k),
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											})
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-14 17:37:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for _, err := range testTemplateParsing(r) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										nodes = append(nodes, WrappedError{err: err})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2023-09-29 16:38:10 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 20:55:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// testTemplateParsing checks if the templates used in labels and annotations
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// of the alerting rules are parsed correctly.
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func testTemplateParsing(rl *RuleNode) (errs []error) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if rl.Alert.Value == "" {
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 20:55:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// Not an alerting rule.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return errs
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Trying to parse templates.
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-13 03:14:31 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									tmplData := template.AlertTemplateData(map[string]string{}, map[string]string{}, "", promql.Sample{})
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-16 00:52:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									defs := []string{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										"{{$labels := .Labels}}",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										"{{$externalLabels := .ExternalLabels}}",
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-31 11:35:26 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										"{{$externalURL := .ExternalURL}}",
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-16 00:52:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										"{{$value := .Value}}",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 20:55:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									parseTest := func(text string) error {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										tmpl := template.NewTemplateExpander(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											context.TODO(),
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-16 00:52:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											strings.Join(append(defs, text), ""),
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											"__alert_"+rl.Alert.Value,
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 20:55:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											tmplData,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											model.Time(timestamp.FromTime(time.Now())),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nil,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nil,
							 | 
						
					
						
							
								
									
										
										
										
											2021-09-13 19:49:08 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nil,
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 20:55:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return tmpl.ParseTest()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Parsing Labels.
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 23:36:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for k, val := range rl.Labels {
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 20:55:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										err := parseTest(val)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											errs = append(errs, fmt.Errorf("label %q: %w", k, err))
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 20:55:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Parsing Annotations.
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 23:36:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for k, val := range rl.Annotations {
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 20:55:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										err := parseTest(val)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											errs = append(errs, fmt.Errorf("annotation %q: %w", k, err))
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 20:55:58 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return errs
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-22 18:43:52 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Parse parses and validates a set of rules.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func Parse(content []byte) (*RuleGroups, []error) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									var (
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										groups RuleGroups
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										node   ruleGroups
							 | 
						
					
						
							
								
									
										
										
										
											2020-03-21 20:05:19 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										errs   []error
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									)
							 | 
						
					
						
							
								
									
										
										
										
											2020-03-21 20:05:19 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-09 21:42:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									decoder := yaml.NewDecoder(bytes.NewReader(content))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									decoder.KnownFields(true)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									err := decoder.Decode(&groups)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Ignore io.EOF which happens with empty input.
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if err != nil && !errors.Is(err, io.EOF) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-03-21 20:05:19 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										errs = append(errs, err)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									err = yaml.Unmarshal(content, &node)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										errs = append(errs, err)
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-22 18:43:52 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2020-03-21 20:05:19 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if len(errs) > 0 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errs
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-16 02:07:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return &groups, groups.Validate(node)
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-22 18:43:52 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// ParseFile reads and parses rules from a file.
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func ParseFile(file string) (*RuleGroups, []error) {
							 | 
						
					
						
							
								
									
										
										
										
											2022-04-27 17:24:36 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									b, err := os.ReadFile(file)
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										return nil, []error{fmt.Errorf("%s: %w", file, err)}
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 23:36:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									rgs, errs := Parse(b)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for i := range errs {
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-28 03:29:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										errs[i] = fmt.Errorf("%s: %w", file, errs[i])
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 23:36:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return rgs, errs
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-07 22:58:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |