metrictank: github.com/grafana/metrictank/expr/tagquery Index | Files

package tagquery

import "github.com/grafana/metrictank/expr/tagquery"

Index

Package Files

expression.go expression_common.go expression_equal.go expression_has_tag.go expression_match.go expression_match_all.go expression_match_none.go expression_match_tag.go expression_not_equal.go expression_not_has_tag.go expression_not_match.go expression_prefix.go expression_prefix_tag.go meta_tag_record.go query.go tag.go tag_gen.go utils.go

Variables

var (
    MatchCacheSize int
    MetaTagSupport bool

    // the function we use to get the hash for hashing the meta records
    // it can be replaced for mocking in tests
    QueryHash func() util.StringHash32
)

func IsSeriesByTagExpression Uses

func IsSeriesByTagExpression(query string) bool

IsSeriesByTag returns true if the given query is a `seriesByTag` query

type Expression Uses

type Expression interface {
    // Equals takes another expression and compares it against itself. Returns true if they are equal
    // or false otherwise
    Equals(Expression) bool

    // GetDefaultDecision defines what decision should be made if the filter has not come to a conclusive
    // decision based on a single index. When looking at more than one tag index in order of decreasing
    // priority to decide whether a metric should be part of the final result set, some operators and metric
    // combinations can come to a conclusive decision without looking at all indexes and some others can't.
    // if an expression has evaluated a metric against all indexes and has not come to a conclusive
    // decision, then the default decision gets applied.
    //
    // Example using the expression returned by `ParseExpression("anothertag!=value")`
    // metric1 has tags ["name=a.b.c", "some=value"] in the metric tag index
    // 1) expression looks at the metric tag index and it sees that metric1 does not have a tag "anothertag"
    //    with the value "value", but at this point it doesn't know if another index that will be looked
    //    at later does, so it returns the decision "none".
    // 2) expression now looks at index2 and sees again that metric1 does not have the tag and value
    //    it is looking for, so it returns "none" again.
    // 3) the expression execution sees that there are no more indexes left, so it applies the default
    //    decision for the operator != which is "pass", meaning the expression "anothertag!=value" has
    //    not filtered the metric metric1 out of the result set.
    //
    // metric2 has tags ["name=a.b.c", "anothertag=value"] according to the metric tag index and it has
    // no meta tags, we still evaluate the same expression:
    // 1) expression looks at metric tag index and see metric2 has tag "anothertag" with value "value".
    //    it directly comes to a conclusive decision that this metric needs to be filtered out of the
    //    result set and returns the filter decision "fail".
    //
    // metric3 has tags ["name=aaa", "abc=cba"] according to the metric tag index and there is a meta
    // record assigning the tag "anothertag=value" to metrics matching that query expression "abc=cba".
    // 1) expression looks at metric3 and sees it does not have the tag & value it's looking for, so
    //    it returns the filter decision "none" because it cannot know for sure whether another index
    //    will assign "anothertag=value" to metric3.
    // 2) expression looks at the meta tag index and it sees that there are meta records matching the
    //    tag "anothertag" and the value "value", so it retrieves the according filter functions of
    //    of these meta records and passes metric3's tag set into them.
    // 3) the filter function of the meta record for the query set "abc=cba" returns true, indicating
    //    that its meta tag gets applied to metric3.
    // 4) based on that the tag expression comes to the decision that metric3 should not be part of
    //    final result set, so it returns "fail".
    GetDefaultDecision() FilterDecision

    // GetKey returns tag to who's values this expression get's applied to
    // example:
    // in the expression "tag1=value" GetKey() would return "tag1"
    GetKey() string

    // GetValue returns the value part of the expression
    // example:
    // in the expression "abc!=cba" this would return "cba"
    GetValue() string

    // GetOperator returns the operator of this expression
    GetOperator() ExpressionOperator

    // GetOperatorCost returns a value which should roughly reflect the cost of this operator compared
    // to other operators. F.e. = is cheaper than =~. Keep in mind that this is only a very rough
    // estimate and will never be accurate.
    GetOperatorCost() uint32

    // OperatesOnTag returns whether this expression operators on the tag key
    // (if not, it operates on the value).
    // Expressions such has expressionHasTag, expressionMatchTag, expressionPrefixTag would return true,
    // because in order to make a decision regarding whether a metric should be part of the result set
    // they need to look at a metric's tags, as opposed to looking at the values associated with some
    // specified tag.
    // If this returns true, then tags shall be passed into ValuePasses(), other values associated with
    // the tag returned by GetKey() shall be passed into ValuePasses().
    OperatesOnTag() bool

    // RequiresNonEmptyValue returns whether this expression requires a non-empty value.
    // Every valid query must have at least one expression requiring a non-empty value.
    RequiresNonEmptyValue() bool

    // ResultIsSmallerWhenInverted returns a bool indicating whether the result set after evaluating
    // this expression will likely be bigger than half of the tested index entries or smaller.
    // This is never guaranteed to actually be correct, it is only an assumption based on which we
    // can optimize performance.
    // F.e. operators = / =~ / __tag=   would return false
    //      operators != / !=~          would return true
    ResultIsSmallerWhenInverted() bool

    // Matches takes a string which should either be a tag key or value depending on the return
    // value of OperatesOnTag(), then it returns whether the given string satisfies this expression
    Matches(string) bool

    // MatchesExactly returns a bool to indicate whether the key / value of this expression (depending
    // on OperatesOnTag()) needs to be an exact match with the key / value of the metrics it evaluates
    // F.e:
    // in the case of the expression "tag1=value1" we're only looking for metrics where the value
    // associated with tag key "tag1" is exactly "value1", so a simple string comparison is sufficient.
    // in other cases like "tag1=~val.*" or "tag^=val" this isn't the case, a simple string comparison
    // is not sufficient to decide whether a metric should be part of the result set or not.
    // since simple string comparisons are cheaper than other comparison methods, whenever possible we
    // want to use string comparison.
    MatchesExactly() bool

    // GetMetricDefinitionFilter returns a MetricDefinitionFilter
    // The MetricDefinitionFilter takes a metric definition, looks at its tags and returns a decision
    // regarding this query expression applied to its tags
    GetMetricDefinitionFilter(lookup IdTagLookup) MetricDefinitionFilter

    // StringIntoWriter takes a string writer and writes a representation of this expression into it
    StringIntoWriter(writer io.Writer)
}

Expression represents a single Graphite tag expression (see documentation for `ParseExpressions`). An expression is part of a query containing one or many expressions. It provides all the necessary methods that are required to do a tag lookup from an index keyed by tags & values, such as the type memory.TagIndex or the type memory.metaTagIndex. It is also comes with a method to generate a filter which decides whether a given MetricDefinition matches the requirements defined by this expression or not. This filter can be obtained from the method GetMetricDefinitionFilter().

func ParseExpression Uses

func ParseExpression(expr string) (Expression, error)

ParseExpression returns an expression that's been generated from the given string, in case of an error the error gets returned as the second value

type ExpressionOperator Uses

type ExpressionOperator uint16
const (
    EQUAL       ExpressionOperator = iota // =
    NOT_EQUAL                             // !=
    MATCH                                 // =~        regular expression
    MATCH_TAG                             // __tag=~   relies on special key __tag. non-standard, required for `/metrics/tags` requests with "filter"
    NOT_MATCH                             // !=~
    PREFIX                                // ^=        exact prefix, not regex. non-standard, required for auto complete of tag values
    PREFIX_TAG                            // __tag^=   exact prefix with tag. non-standard, required for auto complete of tag keys
    HAS_TAG                               // <tag>!="" specified tag must be present
    NOT_HAS_TAG                           // <tag>="" specified tag must not be present
    MATCH_ALL                             // special case of expression that matches every metric (f.e. key=.*)
    MATCH_NONE                            // special case of expression that matches no metric (f.e. key!=.*)
)

func (ExpressionOperator) StringIntoWriter Uses

func (o ExpressionOperator) StringIntoWriter(writer io.Writer)

type Expressions Uses

type Expressions []Expression

func ParseExpressions Uses

func ParseExpressions(expressions []string) (Expressions, error)

ParseExpressions parses a list of graphite tag expressions (as used by the `seriesByTag` function). tag expression definitions: https://graphite.readthedocs.io/en/latest/tags.html#querying seriesBytTag documentation: https://graphite.readthedocs.io/en/latest/functions.html#graphite.render.functions.seriesByTag Some possible tag expressions are: "status=200", "path!=/", "name=~cpu\..*" (`name` is a special tag which is automatically applied to the metric name).

func ParseSeriesByTagExpression Uses

func ParseSeriesByTagExpression(seriesByTagQuery string) (Expressions, error)

ParseSeriesByTagExpression takes a `seriesByTag` query which includes multiple tag query expressions example query: "seriesByTag('a=b', 'c=d', 'e!=~f.*')" it then returns a slice of strings where each string is one of the expressions, and an error which is non-nil if there was an error in the expression parsing and validation. All expressions are validated and an error is returned if one or more are invalid. This method does not validate that the passed in query is a valid `seriesByTag` query. It is assumed that `IsSeriesByTagExpression` has been run (and returned true) before this function is called.

func (Expressions) Equal Uses

func (e Expressions) Equal(other Expressions) bool

func (Expressions) MarshalJSON Uses

func (e Expressions) MarshalJSON() ([]byte, error)

MarshalJSON satisfies the json.Marshaler interface it is used by the api endpoint /metaTags to list the meta tag records

func (Expressions) Sort Uses

func (e Expressions) Sort()

func (Expressions) Strings Uses

func (e Expressions) Strings() []string

func (*Expressions) UnmarshalJSON Uses

func (e *Expressions) UnmarshalJSON(data []byte) error

type FilterDecision Uses

type FilterDecision uint8
const (
    None FilterDecision = iota // no decision has been made, because the decision might change depending on what other indexes defines
    Fail                       // it has been decided by the filter that this metric does not end up in the result set
    Pass                       // the filter has passed
)

type IdTagLookup Uses

type IdTagLookup func(id schema.MKey, tag, value string) bool

type InvalidExpressionError Uses

type InvalidExpressionError string

func (InvalidExpressionError) Error Uses

func (i InvalidExpressionError) Error() string

func (InvalidExpressionError) HTTPStatusCode Uses

func (i InvalidExpressionError) HTTPStatusCode() int

type MetaTagRecord Uses

type MetaTagRecord struct {
    MetaTags    Tags        `json:"metaTags"`
    Expressions Expressions `json:"expressions"`
}

func ParseMetaTagRecord Uses

func ParseMetaTagRecord(metaTags []string, expressions []string) (MetaTagRecord, error)

func (*MetaTagRecord) Equals Uses

func (m *MetaTagRecord) Equals(other *MetaTagRecord) bool

Equals takes another MetaTagRecord and compares all its properties to its own properties. It is assumed that the expressions of both meta tag records are already sorted.

func (*MetaTagRecord) GetMetricDefinitionFilter Uses

func (m *MetaTagRecord) GetMetricDefinitionFilter(lookup IdTagLookup) MetricDefinitionFilter

func (*MetaTagRecord) HasMetaTags Uses

func (m *MetaTagRecord) HasMetaTags() bool

HasMetaTags returns true if the meta tag record has one or more meta tags, otherwise it returns false

func (*MetaTagRecord) HashExpressions Uses

func (m *MetaTagRecord) HashExpressions() uint32

HashExpressions returns a hash of all expressions in this meta tag record It is assumed that the expressions are already sorted

func (*MetaTagRecord) HashMetaTags Uses

func (m *MetaTagRecord) HashMetaTags() uint32

HashMetaTags returns a hash of all meta tags in this meta tag record It is assumed that the meta tags are already sorted

func (*MetaTagRecord) HashRecord Uses

func (m *MetaTagRecord) HashRecord() uint64

type MetricDefinitionFilter Uses

type MetricDefinitionFilter func(id schema.MKey, name string, tags []string) FilterDecision

MetricDefinitionFilter takes a metric name together with its tags and returns a FilterDecision

type Query Uses

type Query struct {
    // clause that operates on LastUpdate field
    From int64

    // slice of expressions sorted by the estimated cost of their operators
    Expressions Expressions
    // contains filtered or unexported fields
}

Query is a set of graphite tag expressions as used by the graphite `seriesByTag` function. tag expression definitions: https://graphite.readthedocs.io/en/latest/tags.html#querying seriesByTag documentation: https://graphite.readthedocs.io/en/latest/functions.html#graphite.render.functions.seriesByTag

func NewQuery Uses

func NewQuery(expressions Expressions, from int64) (Query, error)

func NewQueryFromStrings Uses

func NewQueryFromStrings(expressionStrs []string, from int64) (Query, error)

NewQueryFromStrings parses a list of graphite tag expressions as used by the graphite `seriesByTag` function. tag expression definitions: https://graphite.readthedocs.io/en/latest/tags.html#querying seriesByTag documentation: https://graphite.readthedocs.io/en/latest/functions.html#graphite.render.functions.seriesByTag Some possible tag expressions are: "status=200", "path!=/", "name=~cpu\..*" (`name` is a special tag which is automatically applied to the metric name).

func (*Query) GetTagClause Uses

func (q *Query) GetTagClause() Expression

GetTagClause returns the expression which operates on tags, if one is present. This assumes that Query has been instantiated via NewQuery(), which either sets .tagClause to a valid value or returns an error. There can only be one tagClause per Query.

type Tag Uses

type Tag struct {
    Key   string
    Value string
}

func ParseTag Uses

func ParseTag(tag string) (Tag, error)

func (*Tag) DecodeMsg Uses

func (z *Tag) DecodeMsg(dc *msgp.Reader) (err error)

DecodeMsg implements msgp.Decodable

func (Tag) EncodeMsg Uses

func (z Tag) EncodeMsg(en *msgp.Writer) (err error)

EncodeMsg implements msgp.Encodable

func (Tag) MarshalMsg Uses

func (z Tag) MarshalMsg(b []byte) (o []byte, err error)

MarshalMsg implements msgp.Marshaler

func (Tag) Msgsize Uses

func (z Tag) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (*Tag) StringIntoWriter Uses

func (t *Tag) StringIntoWriter(writer io.Writer)

func (*Tag) UnmarshalMsg Uses

func (z *Tag) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

type Tags Uses

type Tags []Tag

go:generate msgp

func ParseTags Uses

func ParseTags(tags []string) (Tags, error)

ParseTags parses a list of key value pairs into a list of Tags. ParseTags([]string{"key=value", "name=whatever"}) -> Tags{{Key: "key", Value: "value"}, {Key: "name", Value: "whatever"}}}

func ParseTagsFromMetricName Uses

func ParseTagsFromMetricName(name string) (Tags, error)

func (*Tags) DecodeMsg Uses

func (z *Tags) DecodeMsg(dc *msgp.Reader) (err error)

DecodeMsg implements msgp.Decodable

func (Tags) EncodeMsg Uses

func (z Tags) EncodeMsg(en *msgp.Writer) (err error)

EncodeMsg implements msgp.Encodable

func (Tags) Equal Uses

func (t Tags) Equal(other Tags) bool

func (Tags) Len Uses

func (t Tags) Len() int

func (Tags) Less Uses

func (t Tags) Less(i, j int) bool

func (Tags) MarshalJSON Uses

func (t Tags) MarshalJSON() ([]byte, error)

MarshalJSON satisfies the json.Marshaler interface it is used by the api endpoint /metaTags to list the meta tag records

func (Tags) MarshalMsg Uses

func (z Tags) MarshalMsg(b []byte) (o []byte, err error)

MarshalMsg implements msgp.Marshaler

func (Tags) Msgsize Uses

func (z Tags) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (Tags) Sort Uses

func (t Tags) Sort()

func (Tags) Strings Uses

func (t Tags) Strings() []string

func (Tags) Swap Uses

func (t Tags) Swap(i, j int)

func (*Tags) UnmarshalJSON Uses

func (t *Tags) UnmarshalJSON(data []byte) error

func (*Tags) UnmarshalMsg Uses

func (z *Tags) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

Package tagquery imports 13 packages (graph) and is imported by 20 packages. Updated 2020-03-28. Refresh now. Tools for package owners.