github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/docs/sources/clients/k6/query-scenario.md (about) 1 --- 2 title: Query testing 3 weight: 30 4 --- 5 # Query testing 6 7 When designing a test scenario for load testing the read path of a Loki 8 installation, it is important to know what types of queries you expect. 9 10 ## Supported query types 11 12 Loki has 5 types of queries: 13 14 * instant query 15 * range query 16 * labels query 17 * label values query 18 * series query 19 20 In a real-world use-case, such as querying Loki using it as a Grafana 21 datasource, all of these queries are used. Each of them has a different 22 [API]({{< relref "../../api/_index.md" >}}) endpoint. The xk6-loki extension 23 provides a [Javascript API](https://github.com/grafana/xk6-loki#javascript-api) 24 for all these query types. 25 26 27 ### Instant query 28 29 Instant queries can be executed using the function `instantQuery(query, limit)` 30 on the `loki.Client` instance: 31 32 **Javascript example code fragment:** 33 34 ```javascript 35 export default () => { 36 client.instantQuery(`rate({app="my-app-name"} | logfmt | level="error" [5m])`); 37 } 38 ``` 39 40 ### Range query 41 42 Range queries can be executed using the function `rangeQuery(query, duration, limit)` 43 on the `loki.Client` instance: 44 45 **Javascript example code fragment:** 46 47 ```javascript 48 export default () => { 49 client.rangeQuery(`{app="my-app-name"} | logfmt | level="error"`, "15m"); 50 } 51 ``` 52 53 ### Labels query 54 55 Labels queries can be executed using the function `labelsQuery(duration)` 56 on the `loki.Client` instance: 57 58 **Javascript example code fragment:** 59 60 ```javascript 61 export default () => { 62 client.labelsQuery("10m"); 63 } 64 ``` 65 66 ### Label values query 67 68 Label values queries can be executed using the function `labelValuesQuery(label, duration)` 69 on the `loki.Client` instance: 70 71 **Javascript example code fragment:** 72 73 ```javascript 74 export default () => { 75 client.labelValuesQuery("app", "10m"); 76 } 77 ``` 78 79 ### Series query 80 81 Series queries can be executed using the function `seriesQuery(matcher, range)` 82 on the `loki.Client` instance: 83 84 **Javascript example code fragment:** 85 86 ```javascript 87 export default () => { 88 client.seriesQuery(`match[]={app=~"loki-.*"}`, "10m"); 89 } 90 ``` 91 92 ## Metrics 93 94 The extension collects metrics that are printed in the 95 [end-of-test summary](https://k6.io/docs/results-visualization/end-of-test-summary/) in addition to the built-in metrics. 96 These metrics are collected only for instant and range queries. 97 98 | name | description | 99 |-----------------------------------|----------------------------------------------| 100 | `loki_bytes_processed_per_second` | amount of bytes processed by Loki per second | 101 | `loki_bytes_processed_total` | total amount of bytes processed by Loki | 102 | `loki_lines_processed_per_second` | amount of lines processed by Loki per second | 103 | `loki_lines_processed_total` | total amount of lines processed by Loki | 104 105 ## Labels pool 106 107 With the xk6-loki extension, you can use the field `labels` on the `Config` 108 object. It contains label names and values that are generated in a reproducible 109 manner. Use the same labels cardinality configuration for both `write` and 110 `read` testing. 111 112 **Javascript example code fragment:** 113 114 ```javascript 115 const labelCardinality = { 116 "app": 5, 117 "namespace": 2, 118 }; 119 const conf = new loki.Config(BASE_URL, 10000, 1.0, labelCardinality); 120 const client = new loki.Client(conf); 121 122 function randomChoice(items) { 123 return items[Math.floor(Math.random() * items.length)]; 124 } 125 126 export default() { 127 let app = randomChoice(conf.labels.app); 128 let namespace = randomChoice(conf.labels.namespace); 129 client.rangeQuery(`{app="${app}", namespace="${namespace}"} | logfmt | level="error"`, "15m"); 130 } 131 ``` 132 133 Alternatively, you can define your own pool of label names and values, 134 and then randomly select labels from your pool instead of a generated pool. 135 136 ## Javascript example 137 138 A more complex example of a read scenario can be found in xk6-loki repository. 139 The test file 140 [read-scenario.js](https://github.com/grafana/xk6-loki/blob/main/examples/read-scenario.js) 141 can be resused and extended for your needs. 142 143 It allows you to configure ratios for each type of query and the ratios of time 144 ranges. 145 146 **Javascript example:** 147 148 ```javascript 149 const queryTypeRatioConfig = [ 150 { 151 ratio: 0.1, 152 item: readLabels 153 }, 154 { 155 ratio: 0.15, 156 item: readLabelValues 157 }, 158 { 159 ratio: 0.05, 160 item: readSeries 161 }, 162 { 163 ratio: 0.5, 164 item: readRange 165 }, 166 { 167 ratio: 0.2, 168 item: readInstant 169 }, 170 ]; 171 ``` 172 173 This configuration would execute approximately 174 175 - 10% labels requests 176 - 15% label values requests 177 - 5% requests for series 178 - 50% range queries 179 - 20% instant queries 180 181 during a test run.