Skip to content

Commit c407726

Browse files
committed
add target_id fetching from auth, fix clickhouse oom by spilling to disk
1 parent a47501f commit c407726

File tree

1 file changed

+42
-6
lines changed

1 file changed

+42
-6
lines changed

scripts/seed-traces/seed-traces-bulk.ts

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,24 @@ const __dirname = path.dirname(__filename);
1010
const args = process.argv.slice(2);
1111
const targetSlug = args[0];
1212

13+
async function resolveTargetId(slug: string, authUrl: string, token: string): Promise<string> {
14+
const response = await got.get(`${authUrl}/otel-auth`, {
15+
headers: {
16+
'X-Hive-Target-Ref': slug,
17+
Authorization: `Bearer ${token}`,
18+
},
19+
throwHttpErrors: false,
20+
});
21+
22+
if (response.statusCode !== 200) {
23+
const body = JSON.parse(response.body);
24+
throw new Error(`Failed to resolve target: ${body.message || response.body}`);
25+
}
26+
27+
const body = JSON.parse(response.body) as { targetId: string };
28+
return body.targetId;
29+
}
30+
1331
if (!targetSlug || targetSlug.startsWith('--')) {
1432
console.error('Error: TARGET_SLUG is required as the first argument');
1533
console.error('');
@@ -19,6 +37,8 @@ if (!targetSlug || targetSlug.startsWith('--')) {
1937
console.error(' target_slug Target slug in format: org/project/target (required)');
2038
console.error('');
2139
console.error('Options:');
40+
console.error(' --token=TOKEN Authorization token for the auth endpoint (required)');
41+
console.error(' --auth=URL Auth endpoint URL (default: http://localhost:3001)');
2242
console.error(' --count=N Total number of traces to generate (default: 6)');
2343
console.error(' Supports: 1000, 10k, 500k, 1m');
2444
console.error(' --days=N Number of days to scatter traces across (default: 1)');
@@ -30,16 +50,16 @@ if (!targetSlug || targetSlug.startsWith('--')) {
3050
console.error('');
3151
console.error('Examples:');
3252
console.error(
33-
' pnpm seed:traces the-guild/my-project/production # 6 traces, last 24h',
53+
' pnpm seed:traces the-guild/my-project/production --token=abc123',
3454
);
3555
console.error(
36-
' pnpm seed:traces the-guild/my-project/production --count=1k # 1,000 traces, last 24h',
56+
' pnpm seed:traces the-guild/my-project/production --token=abc123 --count=1k',
3757
);
3858
console.error(
39-
' pnpm seed:traces the-guild/my-project/production --count=10k --days=7 # 10,000 traces over 7 days',
59+
' pnpm seed:traces the-guild/my-project/production --token=abc123 --count=10k --days=7',
4060
);
4161
console.error(
42-
' pnpm seed:traces the-guild/my-project/production --count=1m --clickhouse=http://user:pass@remote:8123',
62+
' pnpm seed:traces the-guild/my-project/production --token=abc123 --auth=http://remote:8082',
4363
);
4464
process.exit(1);
4565
}
@@ -70,6 +90,16 @@ const timeRangeDays = ((val: number) => (!Number.isNaN(val) ? val : 1))(
7090
parseNumber(getArgValue('days', '1')),
7191
);
7292
const clickhouseUrl = getArgValue('clickhouse', 'http://test:test@localhost:8123');
93+
const authUrl = getArgValue('auth', 'http://localhost:3001');
94+
const authToken = getArgValue('token', '');
95+
96+
if (!authToken) {
97+
console.error('Error: --token is required');
98+
console.error('');
99+
console.error('Usage: pnpm seed:traces <target_slug> --token=YOUR_TOKEN [options]');
100+
process.exit(1);
101+
}
102+
73103
const numSamples = 6; // We have 6 sample traces
74104
const duplicateFactor = Math.ceil(totalTraceCount / numSamples);
75105

@@ -391,6 +421,8 @@ async function executeClickHouseQuery(query: string) {
391421
searchParams: {
392422
default_format: 'JSON',
393423
wait_end_of_query: '1',
424+
// Enable external sorting to avoid memory limits when using window functions
425+
max_bytes_before_external_sort: '500000000', // 500MB before spilling to disk
394426
},
395427
headers: {
396428
Accept: 'application/json',
@@ -401,6 +433,10 @@ async function executeClickHouseQuery(query: string) {
401433
}
402434

403435
async function seedTraces() {
436+
console.log('Resolving target ID...');
437+
const targetId = await resolveTargetId(targetSlug, authUrl, authToken);
438+
console.log(`Resolved target ID: ${targetId}`);
439+
404440
console.log('Loading trace samples...');
405441
const traceSamples = await loadTraceSamples();
406442
console.log(`Loaded ${traceSamples.length} trace samples`);
@@ -415,7 +451,7 @@ async function seedTraces() {
415451
for (let i = 0; i < traceSamples.length; i++) {
416452
const sample = traceSamples[i];
417453
const timestamp = generateTimestamp(i, totalTraces);
418-
const spans = convertOTELToClickHouse(sample, timestamp, targetSlug);
454+
const spans = convertOTELToClickHouse(sample, timestamp, targetId);
419455
uniqueSpans.push(...spans);
420456

421457
// Capture the trace ID (first span's trace ID)
@@ -459,7 +495,7 @@ async function seedTraces() {
459495

460496
// Process in chunks to avoid ClickHouse memory limits
461497
// Each chunk duplicates all 6 traces by a batch of duplicate indices
462-
const chunkSize = 5000; // Duplicate 5k times per chunk (creates ~30k traces per chunk)
498+
const chunkSize = 1000; // Duplicate 5k times per chunk (creates ~30k traces per chunk)
463499
const numChunks = Math.ceil(actualDuplicates / chunkSize);
464500

465501
for (let chunkIndex = 0; chunkIndex < numChunks; chunkIndex++) {

0 commit comments

Comments
 (0)