tsqtsq aims to make hard-coded PromQL queries easier to read and maintain. Wide-ranging changes and common "query snippets" have varying approaches and often impact query readability. By introducing typed, templated queries, changing common expressions and debugging becomes much easier.
Consider the following use cases:
The library in this directory is an effort to reduce the potential toil involved in refactoring tasks like those mentioned above.
string - just like the string literals and template strings we used before.container!="" as a default matcher for requests/limits but only if the container label is not passed a value (this avoids matching against the confusing pod-level cgroup metrics).import { promql, Expression } from 'tsqtsq';
sum
promql.sum({ expr: 'test_metric{foo="bar"}', by: ['foo', 'bar', 'baz'] });
becomes
sum by (foo, bar, baz) (test_metric{foo="bar"})
rate
promql.rate({ expr: 'test_metric{bar="baz"}', interval: '5m' });
becomes
test_metric(foo{bar="baz"}[5m])
label manipulation
promql.label_replace({ expr: 'test_metric{foo="bar"}', newLabel: 'baz', existingLabel: 'foo' });
becomes
label_replace(test_metric{foo="bar"}, "baz", "$1", "foo", "(.*)")
aggregation over time
promql.sum_over_time({ expr: 'test_metric{foo="bar"}' });
becomes
sum_over_time((test_metric{foo="bar"})[$__range:])
simple offset
promql.offset({ units: { d: 42 } });
becomes
offset 42d
complex offset
promql.offset({ units: { y: 2, d: 1, h: 42, m: 2, s: 3 } });
becomes
offset 2y1d42h2m3s
arithmetic binary ops
promql.div({ left: 'http_requests_total', right: 'http_requests_duration_seconds' });
becomes
http_requests_total / http_requests_duration_seconds
vector matching with on
promql.div({
left: 'http_requests_total{job="api"}',
right: 'http_requests_total{job="api"}',
on: ['instance'],
groupLeft: [],
});
becomes
http_requests_total{job="api"} / on (instance) group_left http_requests_total{job="api"}
composing with rate
promql.div({
left: promql.rate({ expr: 'http_requests_total{code="200"}' }),
right: promql.rate({ expr: 'http_requests_total' }),
on: ['instance'],
groupLeft: ['job'],
});
becomes
rate(http_requests_total{code="200"}[$__rate_interval]) / on (instance) group_left (job) rate(http_requests_total[$__rate_interval])
Expression classThe Expression class can be used to compose reusable PromQL expressions to be further used with the promql library.
new Expression({
metric: 'test_metric',
values: {
arg1: 'foo',
arg2: 'bar'
},
defaultOperator: MatchingOperator.regexMatch,
defaultSelectors: [{ label: 'baz', operator: MatchingOperator.notEqual, value: '' }],
}).toString(),
becomes
test_metric{baz!="", arg1=~"foo", arg2=~"bar"}
which can then be used with a promql method
promql.max({
by: 'baz',
expr: new Expression({
metric: 'test_metric',
values: {
arg1: 'foo',
arg2: 'bar',
},
defaultOperator: MatchingOperator.regexMatch,
defaultSelectors: [{ label: 'baz', operator: MatchingOperator.notEqual, value: '' }],
}).toString(),
});
becomes
max by (baz) (test_metric{baz!="", arg1=~"foo", arg2=~"bar"})
see promql.ts for all available methods.