Skip to main content

Overview

Tags in Slung allow you to filter time-series data using boolean logic. The tag syntax supports infix notation with three operators: AND, OR, and NOT.

Syntax

Tags are specified as the third component of a query, enclosed in square brackets:
OP:SERIES:[tag_expression]:[RANGE]

Basic Tag Filtering

A simple tag filter:
SUM:cpu.total:[env=prod]
Matches data points that have the env=prod tag.

Empty Tag Filters

You can use empty brackets to match all data points:
AVG:memory.used:[]
When tags are empty ([]), all data points are matched regardless of their tags.

Tag Operators

AND - Logical AND

Both conditions must be true. Syntax:
[tag1 AND tag2]
Example:
SUM:cpu.total:[env=prod AND host=h-9]
Matches data points that have both env=prod and host=h-9 tags. Test Case from Source:
[site=eu AND env=prod OR region=west]
This parses as three tags with two operators, evaluated left-to-right: (site=eu AND env=prod) OR region=west.

OR - Logical OR

At least one condition must be true. Syntax:
[tag1 OR tag2]
Example:
AVG:memory.used:[service=db OR NOT muted]
Matches data points that have service=db or do not have the muted tag.

NOT - Logical NOT

Negates the following tag. Syntax (Binary):
[tag1 NOT tag2]
Matches data points that have tag1 but not tag2. Syntax (Unary):
[NOT tag1]
Matches data points that do not have tag1. Example:
AVG:cpu.total:[region=us-west AND NOT host=test]
Matches data points with region=us-west but excludes those with host=test. Unary NOT Example:
SUM:cpu.total:[NOT muted]
Matches all data points that do not have the muted tag.

Tag Format

Tags are typically key-value pairs separated by =, but Slung treats the entire string as the tag:
  • env=prod - Standard key-value format
  • region=us-west - Multi-part value
  • enabled - Boolean-style tag (no value)
  • muted - Simple flag

Operator Precedence

Slung evaluates tag expressions left-to-right with equal precedence for all operators:
[tag1 AND tag2 OR tag3]
Evaluates as: (tag1 AND tag2) OR tag3

NOT as Binary Operator

When NOT appears between two tags, it’s treated as a binary operator equivalent to AND NOT:
[tag1 NOT tag2]
This is equivalent to: tag1 AND (NOT tag2)

NOT as Unary Operator

When NOT appears before a tag (no tag preceding it), it’s a unary operator:
[NOT tag1 AND tag2]
Matches data points that do not have tag1 but do have tag2.

Real-World Examples

Production Environment, Specific Host

AVG:cpu.total:[env=prod AND host=h-9]
Calculates average CPU for production environment on host h-9. Test Verification:
const tags_ok = [_][]const u8{ "region=eu", "env=prod", "host=h-9" };
const tags_fail = [_][]const u8{ "env=prod", "host=h-8" };
// tags_ok matches, tags_fail does not

Database Service or Non-Muted

AVG:memory.used:[service=db OR NOT muted]
Matches data points with service=db tag, or any data point without the muted tag. Test Verification:
const tags_a = [_][]const u8{"service=db"};        // Matches (has service=db)
const tags_b = [_][]const u8{"muted=false"};       // Matches (no "muted" tag)
const tags_c = [_][]const u8{"muted"};             // Does NOT match (has "muted" tag)

Complex Multi-Region Query

MIN:latency:[region=us-west AND NOT host=test]:[1h,now]
Finds minimum latency in us-west region, excluding test hosts, over the last hour.

Multiple ORs

COUNT:requests:[region=eu OR region=us OR region=asia]
Counts requests from any of the three regions.

Tag Parsing Rules

Space-Separated Tokens

Tags and operators are separated by spaces:
[tag1 AND tag2]  # Valid
[tag1AND tag2]   # Invalid - missing spaces

Case Insensitivity for Operators

Operators are case-insensitive:
[tag1 AND tag2]   # Valid
[tag1 and tag2]   # Valid
[tag1 And tag2]   # Valid
Tag names are case-sensitive:
[env=prod]  # Different from [ENV=prod]

Whitespace Handling

Extra whitespace is ignored:
[  tag1   AND   tag2  ]  # Valid, equivalent to [tag1 AND tag2]

Error Cases

Missing Tag After Operator

[foo AND]  # Error: InvalidTags
Operators (except unary NOT) require a tag on both sides.

Missing Brackets

foo AND bar  # Error: InvalidTags
Tag expressions must be enclosed in square brackets.

Operator at End

[tag1 OR tag2 AND]  # Error: InvalidTags
Expressions cannot end with a binary operator.

Implementation Details

Tag Token Structure

Internally, tags are parsed into tokens:
pub const TagToken = union(enum) {
    tag: []const u8,
    op: TagOp,
};
Example parsing of [site=eu AND env=prod OR region=west]:
  1. TagToken{ .tag = "site=eu" }
  2. TagToken{ .op = .and_op }
  3. TagToken{ .tag = "env=prod" }
  4. TagToken{ .op = .or_op }
  5. TagToken{ .tag = "region=west" }

Maximum Tags

Slung supports up to 32 tag tokens (tags + operators combined) per query:
const MAX_TAG_TOKENS = 32;
Exceeding this limit returns error.TooManyTags.

Tag Matching Algorithm

The matchesTags function evaluates the parsed tag expression against a data point’s tags:
  1. Start with the first operand (tag or NOT expression)
  2. For each operator, consume the next operand
  3. Apply the operator (AND/OR) to combine results
  4. Return the final boolean result
NOT Handling:
  • Unary NOT negates the following operand
  • Binary NOT is converted to AND NOT internally

Query Syntax

Complete query DSL overview

Aggregations

Aggregation operations

Build docs developers (and LLMs) love