flush()

Manually flush pending spans to Respan

Overview

flush() forces immediate export of all pending spans to Respan without closing the tracer. The JavaScript SDK automatically drains pending spans on normal Node.js process exit, so short-lived scripts do not need a final flush() only to make their last trace appear. Use flush() when your code needs an explicit export checkpoint while the process is still running.

Signature

1async flush(): Promise<void>

Basic Usage

1import { RespanTelemetry } from '@respan/tracing';
2
3const respanAi = new RespanTelemetry({
4 apiKey: process.env.RESPAN_API_KEY,
5 appName: 'my-app'
6});
7
8await respanAi.initialize();
9
10await respanAi.withWorkflow(
11 { name: 'my_workflow' },
12 async () => {
13 return await processData();
14 }
15);
16
17// Manually checkpoint spans while the tracer stays active
18await respanAi.getClient().flush();
19console.log('Spans sent to Respan');

Explicit Export Checkpoints

1async function main() {
2 const respanAi = new RespanTelemetry({
3 apiKey: process.env.RESPAN_API_KEY,
4 appName: 'batch-job'
5 });
6
7 await respanAi.initialize();
8
9 try {
10 await respanAi.withWorkflow(
11 { name: 'batch_processing' },
12 async () => {
13 for (let i = 0; i < 100; i++) {
14 await processBatch(i);
15 }
16 return 'complete';
17 }
18 );
19 } finally {
20 // Checkpoint spans before validating or reading trace data
21 await respanAi.getClient().flush();
22 console.log('All traces flushed');
23 }
24}
25
26main().catch(console.error);

Periodic Flushing

1await respanAi.withWorkflow(
2 { name: 'long_running_job' },
3 async () => {
4 for (let i = 0; i < 1000; i++) {
5 await respanAi.withTask(
6 { name: `batch_${i}` },
7 async () => {
8 return await processBatch(i);
9 }
10 );
11
12 // Flush every 100 batches
13 if (i % 100 === 0) {
14 await respanAi.getClient().flush();
15 console.log(`Flushed after batch ${i}`);
16 }
17 }
18
19 return 'complete';
20 }
21);

Serverless Functions

Serverless runtimes can freeze or reuse the process before Node.js reaches normal process exit. Flush before returning when the trace must be exported within the invocation window.

1// AWS Lambda handler
2export async function handler(event: any) {
3 const respanAi = new RespanTelemetry({
4 apiKey: process.env.RESPAN_API_KEY,
5 appName: 'lambda-function'
6 });
7
8 await respanAi.initialize();
9
10 try {
11 const result = await respanAi.withWorkflow(
12 { name: 'lambda_execution' },
13 async () => {
14 return await processEvent(event);
15 }
16 );
17
18 // Flush before Lambda freezes
19 await respanAi.getClient().flush();
20
21 return {
22 statusCode: 200,
23 body: JSON.stringify(result)
24 };
25 } catch (error) {
26 // Flush even on error
27 await respanAi.getClient().flush();
28 throw error;
29 }
30}

Express Middleware

1import express from 'express';
2
3const app = express();
4
5const respanAi = new RespanTelemetry({
6 apiKey: process.env.RESPAN_API_KEY,
7 appName: 'api-server'
8});
9
10await respanAi.initialize();
11
12app.post('/api/important', async (req, res) => {
13 try {
14 const result = await respanAi.withWorkflow(
15 { name: 'critical_operation' },
16 async () => {
17 return await processCriticalRequest(req.body);
18 }
19 );
20
21 // Flush immediately for critical operations
22 await respanAi.getClient().flush();
23
24 res.json({ success: true, result });
25 } catch (error) {
26 await respanAi.getClient().flush();
27 res.status(500).json({ error: error.message });
28 }
29});
30
31// Explicit drain for this signal path
32process.on('SIGTERM', async () => {
33 console.log('Flushing traces before shutdown...');
34 await respanAi.getClient().flush();
35 process.exit(0);
36});

Testing

1import { describe, it, beforeAll, afterAll } from '@jest/globals';
2
3describe('My Service', () => {
4 let respanAi: RespanTelemetry;
5
6 beforeAll(async () => {
7 respanAi = new RespanTelemetry({
8 apiKey: process.env.RESPAN_API_KEY,
9 appName: 'test-suite'
10 });
11 await respanAi.initialize();
12 });
13
14 afterAll(async () => {
15 // Flush all test traces
16 await respanAi.getClient().flush();
17 });
18
19 it('should process data', async () => {
20 await respanAi.withWorkflow(
21 { name: 'test_workflow' },
22 async () => {
23 const result = await processData();
24 expect(result).toBeDefined();
25 }
26 );
27 });
28});

With shutdown()

For complete cleanup, use shutdown() instead of flush(). shutdown() flushes and then closes the tracer.

1// Flush only (tracer stays active)
2await respanAi.getClient().flush();
3
4// Shutdown (flush + close tracer)
5await respanAi.shutdown();

Best Practices

  • Do not add a final flush() to short-lived Node.js scripts only for normal process exit; the SDK drains pending spans automatically
  • Use flush() for explicit checkpoints, tests that read exported traces before exit, critical operations, and serverless invocations that may freeze before process exit
  • Use shutdown() when you want complete cleanup and to close the tracer
  • Flush is automatically called periodically when batching is enabled
  • Awaiting flush() waits for export to complete
  • In long-running processes, prefer shutdown() over flush() when the process is done tracing