Menu

Important: This documentation is about an older version. It's relevant only to the release noted, many of the features and functions have been updated or replaced. Please view the current version.

Open source

Use k6 to load test log queries

When designing a test scenario for load testing the read path of a Loki installation, it is important to know what types of queries you expect.

Supported query types

Loki has 5 types of queries:

  • instant query
  • range query
  • labels query
  • label values query
  • series query

In a real-world use-case, such as querying Loki using it as a Grafana datasource, all of these queries are used. Each of them has a different API endpoint. The xk6-loki extension provides a Javascript API for all these query types.

Instant query

Instant queries can be executed using the function instantQuery(query, limit) on the loki.Client instance:

Javascript example code fragment:

JavaScript
export default () => {
  client.instantQuery(`rate({app="my-app-name"} | logfmt | level="error" [5m])`);
}

Range query

Range queries can be executed using the function rangeQuery(query, duration, limit) on the loki.Client instance:

Javascript example code fragment:

JavaScript
export default () => {
  client.rangeQuery(`{app="my-app-name"} | logfmt | level="error"`, "15m");
}

Labels query

Labels queries can be executed using the function labelsQuery(duration) on the loki.Client instance:

Javascript example code fragment:

JavaScript
export default () => {
  client.labelsQuery("10m");
}

Label values query

Label values queries can be executed using the function labelValuesQuery(label, duration) on the loki.Client instance:

Javascript example code fragment:

JavaScript
export default () => {
  client.labelValuesQuery("app", "10m");
}

Series query

Series queries can be executed using the function seriesQuery(matcher, range) on the loki.Client instance:

Javascript example code fragment:

JavaScript
export default () => {
  client.seriesQuery(`match[]={app=~"loki-.*"}`, "10m");
}

Metrics

The extension collects metrics that are printed in the end-of-test summary in addition to the built-in metrics. These metrics are collected only for instant and range queries.

namedescription
loki_bytes_processed_per_secondamount of bytes processed by Loki per second
loki_bytes_processed_totaltotal amount of bytes processed by Loki
loki_lines_processed_per_secondamount of lines processed by Loki per second
loki_lines_processed_totaltotal amount of lines processed by Loki

Labels pool

With the xk6-loki extension, you can use the field labels on the Config object. It contains label names and values that are generated in a reproducible manner. Use the same labels cardinality configuration for both write and read testing.

Javascript example code fragment:

JavaScript
const labelCardinality = {
  "app": 5,
  "namespace": 2,
};
const conf = new loki.Config(BASE_URL, 10000, 1.0, labelCardinality);
const client = new loki.Client(conf);

function randomChoice(items) {
  return items[Math.floor(Math.random() * items.length)];
}

export default() {
  let app = randomChoice(conf.labels.app);
  let namespace = randomChoice(conf.labels.namespace);
  client.rangeQuery(`{app="${app}", namespace="${namespace}"} | logfmt | level="error"`, "15m");
}

Alternatively, you can define your own pool of label names and values, and then randomly select labels from your pool instead of a generated pool.

Javascript example

A more complex example of a read scenario can be found in xk6-loki repository. The test file read-scenario.js can be resused and extended for your needs.

It allows you to configure ratios for each type of query and the ratios of time ranges.

Javascript example:

JavaScript
const queryTypeRatioConfig = [
  {
    ratio: 0.1,
    item: readLabels
  },
  {
    ratio: 0.15,
    item: readLabelValues
  },
  {
    ratio: 0.05,
    item: readSeries
  },
  {
    ratio: 0.5,
    item: readRange
  },
  {
    ratio: 0.2,
    item: readInstant
  },
];

This configuration would execute approximately

  • 10% labels requests
  • 15% label values requests
  • 5% requests for series
  • 50% range queries
  • 20% instant queries

during a test run.