mirror of https://github.com/grafana/loki
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
315 lines
7.3 KiB
315 lines
7.3 KiB
package syntax
|
|
|
|
import (
|
|
"github.com/prometheus/prometheus/model/labels"
|
|
|
|
"github.com/grafana/loki/v3/pkg/logql/log"
|
|
)
|
|
|
|
type cloneVisitor struct {
|
|
cloned Expr
|
|
}
|
|
|
|
var _ RootVisitor = &cloneVisitor{}
|
|
|
|
func cloneGrouping(g *Grouping) *Grouping {
|
|
copied := &Grouping{
|
|
Without: g.Without,
|
|
}
|
|
if g.Groups != nil {
|
|
copied.Groups = make([]string, len(g.Groups))
|
|
copy(copied.Groups, g.Groups)
|
|
}
|
|
return copied
|
|
}
|
|
|
|
func cloneVectorMatching(v *VectorMatching) *VectorMatching {
|
|
copied := *v
|
|
copy(copied.Include, v.Include)
|
|
copy(copied.MatchingLabels, v.MatchingLabels)
|
|
|
|
return &copied
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitBinOp(e *BinOpExpr) {
|
|
lhs := MustClone[SampleExpr](e.SampleExpr)
|
|
rhs := MustClone[SampleExpr](e.RHS)
|
|
copied := &BinOpExpr{
|
|
SampleExpr: lhs,
|
|
RHS: rhs,
|
|
Op: e.Op,
|
|
}
|
|
|
|
if e.Opts != nil {
|
|
copied.Opts = &BinOpOptions{
|
|
ReturnBool: e.Opts.ReturnBool,
|
|
VectorMatching: cloneVectorMatching(e.Opts.VectorMatching),
|
|
}
|
|
}
|
|
|
|
v.cloned = copied
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitVectorAggregation(e *VectorAggregationExpr) {
|
|
copied := &VectorAggregationExpr{
|
|
Left: MustClone[SampleExpr](e.Left),
|
|
Params: e.Params,
|
|
Operation: e.Operation,
|
|
}
|
|
|
|
if e.Grouping != nil {
|
|
copied.Grouping = cloneGrouping(e.Grouping)
|
|
}
|
|
|
|
v.cloned = copied
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitRangeAggregation(e *RangeAggregationExpr) {
|
|
copied := &RangeAggregationExpr{
|
|
Left: MustClone[*LogRangeExpr](e.Left),
|
|
Operation: e.Operation,
|
|
}
|
|
|
|
if e.Grouping != nil {
|
|
copied.Grouping = cloneGrouping(e.Grouping)
|
|
}
|
|
|
|
if e.Params != nil {
|
|
tmp := *e.Params
|
|
copied.Params = &tmp
|
|
}
|
|
|
|
v.cloned = copied
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitLabelReplace(e *LabelReplaceExpr) {
|
|
left := MustClone[SampleExpr](e.Left)
|
|
v.cloned = mustNewLabelReplaceExpr(left, e.Dst, e.Replacement, e.Src, e.Regex)
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitLiteral(e *LiteralExpr) {
|
|
v.cloned = &LiteralExpr{Val: e.Val}
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitVector(e *VectorExpr) {
|
|
v.cloned = &VectorExpr{Val: e.Val}
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitLogRange(e *LogRangeExpr) {
|
|
copied := &LogRangeExpr{
|
|
Left: MustClone[LogSelectorExpr](e.Left),
|
|
Interval: e.Interval,
|
|
Offset: e.Offset,
|
|
}
|
|
if e.Unwrap != nil {
|
|
copied.Unwrap = &UnwrapExpr{
|
|
Identifier: e.Unwrap.Identifier,
|
|
Operation: e.Unwrap.Operation,
|
|
}
|
|
if e.Unwrap.PostFilters != nil {
|
|
copied.Unwrap.PostFilters = make([]log.LabelFilterer, len(e.Unwrap.PostFilters))
|
|
for i, f := range e.Unwrap.PostFilters {
|
|
copied.Unwrap.PostFilters[i] = cloneLabelFilterer(f)
|
|
}
|
|
}
|
|
}
|
|
|
|
v.cloned = copied
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitMatchers(e *MatchersExpr) {
|
|
copied := &MatchersExpr{
|
|
Mts: make([]*labels.Matcher, len(e.Mts)),
|
|
}
|
|
for i, m := range e.Mts {
|
|
copied.Mts[i] = labels.MustNewMatcher(m.Type, m.Name, m.Value)
|
|
}
|
|
|
|
v.cloned = copied
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitPipeline(e *PipelineExpr) {
|
|
copied := &PipelineExpr{
|
|
Left: MustClone[*MatchersExpr](e.Left),
|
|
MultiStages: make(MultiStageExpr, len(e.MultiStages)),
|
|
}
|
|
for i, s := range e.MultiStages {
|
|
copied.MultiStages[i] = MustClone[StageExpr](s)
|
|
}
|
|
|
|
v.cloned = copied
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitDecolorize(*DecolorizeExpr) {
|
|
v.cloned = &DecolorizeExpr{}
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitDropLabels(e *DropLabelsExpr) {
|
|
copied := &DropLabelsExpr{
|
|
dropLabels: make([]log.NamedLabelMatcher, len(e.dropLabels)),
|
|
}
|
|
for i, l := range e.dropLabels {
|
|
var matcher *labels.Matcher
|
|
if l.Matcher != nil {
|
|
matcher = labels.MustNewMatcher(l.Matcher.Type, l.Matcher.Name, l.Matcher.Value)
|
|
}
|
|
copied.dropLabels[i] = log.NewNamedLabelMatcher(matcher, l.Name)
|
|
}
|
|
|
|
v.cloned = copied
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitJSONExpressionParser(e *JSONExpressionParserExpr) {
|
|
copied := &JSONExpressionParserExpr{
|
|
Expressions: make([]log.LabelExtractionExpr, len(e.Expressions)),
|
|
}
|
|
copy(copied.Expressions, e.Expressions)
|
|
|
|
v.cloned = copied
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitKeepLabel(e *KeepLabelsExpr) {
|
|
copied := &KeepLabelsExpr{
|
|
keepLabels: make([]log.NamedLabelMatcher, len(e.keepLabels)),
|
|
}
|
|
for i, k := range e.keepLabels {
|
|
copied.keepLabels[i] = log.NamedLabelMatcher{
|
|
Name: k.Name,
|
|
}
|
|
if k.Matcher != nil {
|
|
copied.keepLabels[i].Matcher = labels.MustNewMatcher(k.Matcher.Type, k.Matcher.Name, k.Matcher.Value)
|
|
}
|
|
}
|
|
|
|
v.cloned = copied
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitLabelFilter(e *LabelFilterExpr) {
|
|
v.cloned = &LabelFilterExpr{
|
|
LabelFilterer: cloneLabelFilterer(e.LabelFilterer),
|
|
}
|
|
}
|
|
|
|
func cloneLabelFilterer(filter log.LabelFilterer) log.LabelFilterer {
|
|
switch concrete := filter.(type) {
|
|
case *log.BinaryLabelFilter:
|
|
return &log.BinaryLabelFilter{
|
|
Left: cloneLabelFilterer(concrete.Left),
|
|
Right: cloneLabelFilterer(concrete.Right),
|
|
And: concrete.And,
|
|
}
|
|
case *log.NoopLabelFilter:
|
|
copied := &log.NoopLabelFilter{}
|
|
if concrete.Matcher != nil {
|
|
copied.Matcher = mustNewMatcher(concrete.Type, concrete.Name, concrete.Value)
|
|
}
|
|
|
|
return copied
|
|
case *log.BytesLabelFilter:
|
|
return &log.BytesLabelFilter{
|
|
Name: concrete.Name,
|
|
Value: concrete.Value,
|
|
Type: concrete.Type,
|
|
}
|
|
case *log.DurationLabelFilter:
|
|
return &log.DurationLabelFilter{
|
|
Name: concrete.Name,
|
|
Value: concrete.Value,
|
|
Type: concrete.Type,
|
|
}
|
|
case *log.NumericLabelFilter:
|
|
return &log.NumericLabelFilter{
|
|
Name: concrete.Name,
|
|
Value: concrete.Value,
|
|
Type: concrete.Type,
|
|
}
|
|
case *log.StringLabelFilter:
|
|
copied := &log.StringLabelFilter{}
|
|
if concrete.Matcher != nil {
|
|
copied.Matcher = mustNewMatcher(concrete.Type, concrete.Name, concrete.Value)
|
|
}
|
|
return copied
|
|
case *log.LineFilterLabelFilter:
|
|
copied := &log.LineFilterLabelFilter{
|
|
Filter: concrete.Filter,
|
|
}
|
|
if concrete.Matcher != nil {
|
|
copied.Matcher = mustNewMatcher(concrete.Type, concrete.Name, concrete.Value)
|
|
}
|
|
return copied
|
|
case *log.IPLabelFilter:
|
|
return log.NewIPLabelFilter(concrete.Pattern, concrete.Label, concrete.Ty)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitLabelFmt(e *LabelFmtExpr) {
|
|
copied := &LabelFmtExpr{
|
|
Formats: make([]log.LabelFmt, len(e.Formats)),
|
|
}
|
|
copy(copied.Formats, e.Formats)
|
|
v.cloned = copied
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitLabelParser(e *LineParserExpr) {
|
|
v.cloned = &LineParserExpr{
|
|
Op: e.Op,
|
|
Param: e.Param,
|
|
}
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitLineFilter(e *LineFilterExpr) {
|
|
copied := &LineFilterExpr{
|
|
LineFilter: LineFilter{
|
|
Ty: e.Ty,
|
|
Match: e.Match,
|
|
Op: e.Op,
|
|
},
|
|
IsOrChild: e.IsOrChild,
|
|
}
|
|
|
|
if e.Left != nil {
|
|
copied.Left = MustClone[*LineFilterExpr](e.Left)
|
|
}
|
|
|
|
if e.Or != nil {
|
|
copied.Or = MustClone[*LineFilterExpr](e.Or)
|
|
}
|
|
|
|
v.cloned = copied
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitLineFmt(e *LineFmtExpr) {
|
|
v.cloned = &LineFmtExpr{Value: e.Value}
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitLogfmtExpressionParser(e *LogfmtExpressionParserExpr) {
|
|
copied := &LogfmtExpressionParserExpr{
|
|
Expressions: make([]log.LabelExtractionExpr, len(e.Expressions)),
|
|
Strict: e.Strict,
|
|
KeepEmpty: e.KeepEmpty,
|
|
}
|
|
copy(copied.Expressions, e.Expressions)
|
|
|
|
v.cloned = copied
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitLogfmtParser(e *LogfmtParserExpr) {
|
|
v.cloned = &LogfmtParserExpr{
|
|
Strict: e.Strict,
|
|
KeepEmpty: e.KeepEmpty,
|
|
}
|
|
}
|
|
|
|
func (v *cloneVisitor) VisitVariants(e *MultiVariantExpr) {
|
|
copied := &MultiVariantExpr{
|
|
logRange: MustClone[*LogRangeExpr](e.logRange),
|
|
variants: make([]SampleExpr, len(e.variants)),
|
|
}
|
|
|
|
for i, v := range e.variants {
|
|
copied.variants[i] = MustClone[SampleExpr](v)
|
|
}
|
|
|
|
v.cloned = copied
|
|
}
|
|
|