tagquery

package
v0.13.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 17, 2019 License: AGPL-3.0, BSD-2-Clause Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
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() hash.Hash32
)

Functions

This section is empty.

Types

type Expression

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
	// metric1 has tags ["name=a.b.c", "some=value"] in the metric tag index, we evaluate the expression
	// "anothertag!=value":
	// 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

	// StringIntoBuilder takes a builder and writes a string representation of this expression into it
	StringIntoBuilder(builder *strings.Builder)
}

Expression represents one expression inside a query of 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

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

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) StringIntoBuilder

func (o ExpressionOperator) StringIntoBuilder(builder *strings.Builder)

type Expressions

type Expressions []Expression

func ParseExpressions

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

func (Expressions) MarshalJSON

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

func (e Expressions) Sort()

func (Expressions) Strings

func (e Expressions) Strings() []string

type FilterDecision

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

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

type InvalidExpressionError

type InvalidExpressionError string

func (InvalidExpressionError) Error

func (i InvalidExpressionError) Error() string

type MetaTagRecord

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

func ParseMetaTagRecord

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

func (*MetaTagRecord) EqualExpressions

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

EqualExpressions compares another meta tag record's expressions to this one's expressions Returns true if they are equal, otherwise false It is assumed that all the expressions are already sorted

func (*MetaTagRecord) Equals

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

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

func (*MetaTagRecord) HasMetaTags

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

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

type MetricDefinitionFilter

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

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
}

func NewQuery

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

func NewQueryFromStrings

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

func (*Query) GetTagClause

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

type Tag struct {
	Key   string
	Value string
}

func ParseTag

func ParseTag(tag string) (Tag, error)

func (*Tag) DecodeMsg

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

DecodeMsg implements msgp.Decodable

func (Tag) EncodeMsg

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

EncodeMsg implements msgp.Encodable

func (Tag) MarshalMsg

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

MarshalMsg implements msgp.Marshaler

func (Tag) Msgsize

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

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

func (*Tag) StringIntoBuilder

func (t *Tag) StringIntoBuilder(builder *strings.Builder)

func (*Tag) UnmarshalMsg

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

UnmarshalMsg implements msgp.Unmarshaler

type Tags

type Tags []Tag

func ParseTags

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

func ParseTagsFromMetricName

func ParseTagsFromMetricName(name string) (Tags, error)

func (*Tags) DecodeMsg

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

DecodeMsg implements msgp.Decodable

func (Tags) EncodeMsg

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

EncodeMsg implements msgp.Encodable

func (Tags) Len

func (t Tags) Len() int

func (Tags) Less

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

func (Tags) MarshalJSON

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

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

MarshalMsg implements msgp.Marshaler

func (Tags) Msgsize

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

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

func (Tags) Strings

func (t Tags) Strings() []string

func (Tags) Swap

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

func (*Tags) UnmarshalMsg

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

UnmarshalMsg implements msgp.Unmarshaler

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL