Skip to content

Instantly share code, notes, and snippets.

@HuakunShen
Last active September 25, 2025 14:20
Show Gist options
  • Select an option

  • Save HuakunShen/60354f49c3b9c866a9bb08e8792d568a to your computer and use it in GitHub Desktop.

Select an option

Save HuakunShen/60354f49c3b9c866a9bb08e8792d568a to your computer and use it in GitHub Desktop.
effect
import { Cause, Effect, Layer, Logger } from "effect";
import { NodeRuntime } from "@effect/platform-node";
import { DevTools } from "@effect/experimental";
import { NodeSdk } from "@effect/opentelemetry";
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
import { BatchLogRecordProcessor } from "@opentelemetry/sdk-logs";
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
import { trace, context } from "@opentelemetry/api";
// Function to simulate a task with possible subtasks
const task = (
name: string,
delay: number,
children: ReadonlyArray<Effect.Effect<void>> = []
) =>
Effect.gen(function* () {
yield* Effect.log(name);
yield* Effect.sleep(`${delay} millis`);
for (const child of children) {
yield* child;
}
yield* Effect.sleep(`${delay} millis`);
}).pipe(Effect.withSpan(name));
const poll = task("/poll", 1);
// Create a program with tasks and subtasks
const program = task("client", 2, [
task("/api", 3, [
task("/authN", 4, [task("/authZ", 5)]),
task("/payment Gateway", 6, [task("DB", 7), task("Ext. Merchant", 8)]),
task("/dispatch", 9, [
task("/dispatch/search", 10),
Effect.all([poll, poll, poll], { concurrency: "inherit" }),
task("/pollDriver/{id}", 11),
]),
]),
]);
const NodeSdkLive = NodeSdk.layer(() => ({
resource: { serviceName: "example" },
spanProcessor: new BatchSpanProcessor(new OTLPTraceExporter()),
logRecordProcessor: new BatchLogRecordProcessor(new OTLPLogExporter()),
}));
Effect.runPromise(
program.pipe(
Effect.provide(NodeSdkLive),
Effect.provide(Logger.pretty),
Effect.catchAllCause(Effect.logError)
)
);
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { ConsoleSpanExporter, BatchSpanProcessor } from '@opentelemetry/sdk-trace-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
import { diag, trace, context, createContextKey } from '@opentelemetry/api';
import { logs, SeverityNumber } from '@opentelemetry/api-logs';
import { LoggerProvider, ConsoleLogRecordExporter } from '@opentelemetry/sdk-logs';
// Create the OpenTelemetry SDK instance
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter(),
spanProcessors: [new BatchSpanProcessor(new OTLPTraceExporter())],
logRecordProcessor: new BatchLogRecordProcessor(new OTLPLogExporter()),
instrumentations: [getNodeAutoInstrumentations()],
});
// Initialize the SDK
sdk.start();
// Get the tracer
const tracer = trace.getTracer('example-service');
// Get the logger
const logger = logs.getLoggerProvider().getLogger('example-service');
// Function to simulate a task with logging and tracing
const taskWithTrace = async (name: string, delay: number, children: Array<() => Promise<void>> = []) => {
return tracer.startActiveSpan(`${name}`, async (span) => {
try {
// Create a log record with trace context
logger.emit({
timestamp: Date.now(),
severityNumber: SeverityNumber.INFO,
severityText: 'INFO',
body: name,
attributes: {
'service.name': 'example',
'traceId': span.spanContext().traceId,
'spanId': span.spanContext().spanId,
'traceFlags': span.spanContext().traceFlags,
}
});
console.log(`[${new Date().toISOString()}] INFO: ${name} (traceId: ${span.spanContext().traceId})`);
// Simulate work
await new Promise(resolve => setTimeout(resolve, delay));
// Execute child tasks
for (const child of children) {
await child();
}
// More simulated work
await new Promise(resolve => setTimeout(resolve, delay));
} finally {
span.end();
}
});
};
const program = async () => {
const pollTask = () => taskWithTrace('/poll', 1);
// Create a program with tasks and subtasks
await taskWithTrace('client', 2, [
() => taskWithTrace('/api', 3, [
() => taskWithTrace('/authN', 4, [() => taskWithTrace('/authZ', 5)]),
() => taskWithTrace('/payment Gateway', 6, [
() => taskWithTrace('DB', 7),
() => taskWithTrace('Ext. Merchant', 8)
]),
() => taskWithTrace('/dispatch', 9, [
() => taskWithTrace('/dispatch/search', 10),
() => taskWithTrace('/pollDriver/{id}', 11),
]),
]),
]);
};
// Run the program
program()
.then(async () => {
console.log('Program completed');
// Allow some time for logs and traces to be exported
await new Promise(resolve => setTimeout(resolve, 2000));
await sdk.shutdown();
})
.catch(async (error) => {
console.error('Program failed:', error);
await sdk.shutdown();
process.exit(1);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment