devenv: better loki environment (#49383)

* devenv: rename loki to loki-promtail

* devenv: new loki devenv entry with fake data generation
This commit is contained in:
Gábor Farkas
2022-05-25 11:01:17 +02:00
committed by GitHub
parent b07904fe56
commit ebc20849bd
6 changed files with 133 additions and 10 deletions
+107
View File
@@ -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();