Last active
September 25, 2025 14:20
-
-
Save HuakunShen/60354f49c3b9c866a9bb08e8792d568a to your computer and use it in GitHub Desktop.
effect
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) | |
| ) | |
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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