chore: add loadtest observability setup
This commit is contained in:
119
scripts/run-otelcol.mjs
Normal file
119
scripts/run-otelcol.mjs
Normal file
@@ -0,0 +1,119 @@
|
||||
import {spawn} from 'node:child_process';
|
||||
import {mkdirSync, writeFileSync} from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
const [, , rawMode = 'debug', ...args] = process.argv;
|
||||
const mode = rawMode.trim();
|
||||
const printConfigOnly = args.includes('--print-config');
|
||||
|
||||
const supportedModes = new Set(['debug', 'rider']);
|
||||
if (!supportedModes.has(mode)) {
|
||||
console.error('[otelcol] mode must be one of: debug, rider');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const otlpHttpEndpoint = readEnv('OTELCOL_OTLP_HTTP_ENDPOINT', '127.0.0.1:4318');
|
||||
const otlpGrpcEndpoint = readEnv('OTELCOL_OTLP_GRPC_ENDPOINT', '127.0.0.1:4317');
|
||||
const riderEndpoint = readEnv('RIDER_OTLP_GRPC_ENDPOINT', '127.0.0.1:17011');
|
||||
const debugVerbosity = readEnv('OTELCOL_DEBUG_VERBOSITY', 'detailed');
|
||||
const otelcolBin = readEnv('OTELCOL_BIN', 'otelcol-contrib');
|
||||
|
||||
const configText = buildConfig(mode);
|
||||
const configDir = path.resolve('.codex-temp', 'otelcol');
|
||||
const configPath = path.join(configDir, `genarrative-${mode}.yaml`);
|
||||
mkdirSync(configDir, {recursive: true});
|
||||
writeFileSync(configPath, configText, 'utf8');
|
||||
|
||||
console.log(`[otelcol] wrote ${configPath}`);
|
||||
console.log(`[otelcol] receiving OTLP HTTP at http://${otlpHttpEndpoint}`);
|
||||
console.log(`[otelcol] receiving OTLP gRPC at ${otlpGrpcEndpoint}`);
|
||||
if (mode === 'rider') {
|
||||
console.log(`[otelcol] forwarding traces/metrics/logs to Rider OTLP gRPC at ${riderEndpoint}`);
|
||||
}
|
||||
console.log(
|
||||
'[otelcol] api-server env: GENARRATIVE_OTEL_ENABLED=true OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318'
|
||||
);
|
||||
|
||||
if (printConfigOnly) {
|
||||
console.log(configText);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const child = spawn(otelcolBin, ['--config', configPath], {
|
||||
cwd: process.cwd(),
|
||||
env: process.env,
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
const stopChild = () => {
|
||||
if (!child.killed) {
|
||||
child.kill();
|
||||
}
|
||||
};
|
||||
|
||||
for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
|
||||
process.on(signal, () => {
|
||||
stopChild();
|
||||
process.exit(130);
|
||||
});
|
||||
}
|
||||
|
||||
process.on('exit', stopChild);
|
||||
|
||||
child.on('error', (error) => {
|
||||
console.error(`[otelcol] failed to start ${otelcolBin}: ${error.message}`);
|
||||
console.error('[otelcol] install otelcol-contrib and make sure it is on PATH, or set OTELCOL_BIN.');
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
child.on('exit', (code, signal) => {
|
||||
if (signal) {
|
||||
console.error(`[otelcol] exited by signal: ${signal}`);
|
||||
process.exit(1);
|
||||
}
|
||||
process.exit(code ?? 0);
|
||||
});
|
||||
|
||||
function readEnv(key, fallback) {
|
||||
const value = process.env[key]?.trim();
|
||||
return value ? value : fallback;
|
||||
}
|
||||
|
||||
function buildConfig(selectedMode) {
|
||||
const exporters =
|
||||
selectedMode === 'rider'
|
||||
? ` otlp/rider:
|
||||
endpoint: ${riderEndpoint}
|
||||
tls:
|
||||
insecure: true
|
||||
debug:
|
||||
verbosity: ${debugVerbosity}`
|
||||
: ` debug:
|
||||
verbosity: ${debugVerbosity}`;
|
||||
|
||||
const pipelineExporters = selectedMode === 'rider' ? '[otlp/rider, debug]' : '[debug]';
|
||||
|
||||
return `receivers:
|
||||
otlp:
|
||||
protocols:
|
||||
grpc:
|
||||
endpoint: ${otlpGrpcEndpoint}
|
||||
http:
|
||||
endpoint: ${otlpHttpEndpoint}
|
||||
|
||||
exporters:
|
||||
${exporters}
|
||||
|
||||
service:
|
||||
pipelines:
|
||||
traces:
|
||||
receivers: [otlp]
|
||||
exporters: ${pipelineExporters}
|
||||
metrics:
|
||||
receivers: [otlp]
|
||||
exporters: ${pipelineExporters}
|
||||
logs:
|
||||
receivers: [otlp]
|
||||
exporters: ${pipelineExporters}
|
||||
`;
|
||||
}
|
||||
Reference in New Issue
Block a user