devenv: better loki environment (#49383)

* devenv: rename loki to loki-promtail

* devenv: new loki devenv entry with fake data generation
pull/49629/head
Gábor Farkas 3 years ago committed by GitHub
parent b07904fe56
commit ebc20849bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 0
      devenv/docker/blocks/loki-promtail/README.md
  2. 14
      devenv/docker/blocks/loki-promtail/docker-compose.yaml
  3. 0
      devenv/docker/blocks/loki-promtail/promtail-config.yaml
  4. 3
      devenv/docker/blocks/loki/data/Dockerfile
  5. 107
      devenv/docker/blocks/loki/data/data.js
  6. 19
      devenv/docker/blocks/loki/docker-compose.yaml

@ -0,0 +1,14 @@
# datasource URL: http://localhost:3100/
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
promtail:
image: grafana/promtail:latest
volumes:
- ./docker/blocks/loki-promtail/promtail-config.yaml:/etc/promtail/docker-config.yaml
- /var/log:/var/log
- ../data/log:/var/log/grafana
command:
-config.file=/etc/promtail/docker-config.yaml

@ -0,0 +1,3 @@
FROM node:16-alpine
COPY data.js /home/node/data.js

@ -0,0 +1,107 @@
const http = require('http');
if (process.argv.length !== 3) {
throw new Error('invalid command line: use node sendLogs.js LOKIC_BASE_URL');
}
const LOKI_BASE_URL = process.argv[2];
// helper function, do a http request
async function jsonRequest(data, method, url, expectedStatusCode) {
return new Promise((resolve, reject) => {
const req = http.request(
{
protocol: url.protocol,
host: url.hostname,
port: url.port,
path: `${url.pathname}${url.search}`,
method,
headers: { 'content-type': 'application/json' },
},
(res) => {
if (res.statusCode !== expectedStatusCode) {
reject(new Error(`Invalid response: ${res.statusCode}`));
} else {
resolve();
}
}
);
req.on('error', (err) => reject(err));
req.write(JSON.stringify(data));
req.end();
});
}
// helper function, choose a random element from an array
function chooseRandomElement(items) {
const index = Math.trunc(Math.random() * items.length);
return items[index];
}
// helper function, sleep for a duration
async function sleep(duration) {
return new Promise((resolve) => {
setTimeout(resolve, duration);
});
}
async function lokiSendLogLine(timestampMs, line, tags) {
// we keep nanosecond-timestamp in a string because
// as a number it would be too large
const timestampNs = `${timestampMs}000000`;
const data = {
streams: [
{
stream: tags,
values: [[timestampNs, line]],
},
],
};
const url = new URL(LOKI_BASE_URL);
url.pathname = '/loki/api/v1/push';
await jsonRequest(data, 'POST', url, 204);
}
function getRandomLogLine(counter) {
const randomText = `${Math.trunc(Math.random() * 1000 * 1000 * 1000)}`;
const maybeAnsiText = Math.random() < 0.5 ? 'with ANSI \u001b[31mpart of the text\u001b[0m' : '';
return JSON.stringify({
_entry: `log text ${maybeAnsiText} [${randomText}]`,
counter: counter.toString(),
float: Math.random() > 0.2 ? (100 * Math.random()).toString() : 'NaN',
label: chooseRandomElement(['val1', 'val2', 'val3']),
level: chooseRandomElement(['info', 'info', 'error']),
});
}
const SLEEP_ANGLE_STEP = Math.PI / 200;
let sleepAngle = 0;
function getNextSineWaveSleepDuration() {
sleepAngle += SLEEP_ANGLE_STEP;
return Math.trunc(1000 * Math.abs(Math.sin(sleepAngle)));
}
async function main() {
const tags = {
place: 'moon',
};
for (let step = 0; step < 300; step++) {
await sleep(getNextSineWaveSleepDuration());
const timestampMs = new Date().getTime();
const line = getRandomLogLine(step + 1);
lokiSendLogLine(timestampMs, line, tags);
}
}
// when running in docker, we catch the needed stop-signal, to shutdown fast
process.on('SIGTERM', () => {
console.log('shutdown requested');
process.exit(0);
});
main();

@ -1,14 +1,13 @@
# datasource URL: http://localhost:3100/
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
promtail:
image: grafana/promtail:latest
volumes:
- ./docker/blocks/loki/promtail-config.yaml:/etc/promtail/docker-config.yaml
- /var/log:/var/log
- ../data/log:/var/log/grafana
command:
-config.file=/etc/promtail/docker-config.yaml
data:
build: docker/blocks/loki/data
command: node /home/node/data.js http://loki:3100
depends_on:
- loki
# when loki starts, there might be some time while it is not
# accepting requests, so we allow data.js to restart on failure.
restart: "on-failure"
Loading…
Cancel
Save