inngest 3.48.0 → 3.48.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # inngest
2
2
 
3
+ ## 3.48.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1205](https://github.com/inngest/inngest-js/pull/1205) [`8ca992e9`](https://github.com/inngest/inngest-js/commit/8ca992e913d1d41c5704dfd7b0d262848b9fb84f) Thanks [@Linell](https://github.com/Linell)! - Include client headers, such as `x-inngest-env` in trace exports.
8
+
3
9
  ## 3.48.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -21,7 +21,6 @@ Read the <a href="https://www.inngest.com/docs?ref=github-inngest-js-readme">doc
21
21
  <p>
22
22
 
23
23
  <a href="https://www.npmjs.com/package/inngest"><img src="https://img.shields.io/npm/v/inngest" /></a>
24
- <a href="https://jsr.io/@inngest/sdk"><img src="https://jsr.io/badges/@inngest/sdk" /></a>
25
24
  <br/>
26
25
  <a href="https://www.inngest.com/discord"><img src="https://img.shields.io/discord/842170679536517141?label=discord" /></a>
27
26
  <a href="https://twitter.com/inngest"><img src="https://img.shields.io/twitter/follow/inngest?style=social" /></a>
@@ -64,12 +63,6 @@ Install Inngest:
64
63
  npm install inngest
65
64
  ```
66
65
 
67
- Or get it from [JSR](https://jsr.io/@inngest/sdk):
68
-
69
- ```bash
70
- deno add jsr:@inngest/sdk
71
- ```
72
-
73
66
  ### Writing functions
74
67
 
75
68
  Write serverless functions and background jobs right in your own code:
@@ -149,7 +149,10 @@ var InngestSpanProcessor = class InngestSpanProcessor {
149
149
  processorDebug("batcher lazily accessed; creating new batcher with URL", url);
150
150
  resolve(new __opentelemetry_sdk_trace_base.BatchSpanProcessor(new __opentelemetry_exporter_trace_otlp_http.OTLPTraceExporter({
151
151
  url: url.href,
152
- headers: { Authorization: `Bearer ${app["inngestApi"]["signingKey"]}` }
152
+ headers: {
153
+ ...app["headers"],
154
+ Authorization: `Bearer ${app["inngestApi"]["signingKey"]}`
155
+ }
153
156
  })));
154
157
  } catch (err) {
155
158
  reject(err);
@@ -1 +1 @@
1
- {"version":3,"file":"processor.cjs","names":["debugPrefix","_resourceAttributes: Resource | undefined","#traceParents","appId: string | undefined","functionId: string | undefined","traceRef: string | undefined","TraceStateKey","osDetector","envDetector","hostDetector","processDetector","serviceInstanceIdDetector","#batcher","getAsyncCtx","url: URL","defaultInngestApiBaseUrl","devServerHost","defaultDevServerHost","devServerAvailable","BatchSpanProcessor","OTLPTraceExporter","#spanCleanup","#spansToExport","Attribute","debug"],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":["import type { Span } from \"@opentelemetry/api\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport {\n detectResources,\n envDetector,\n hostDetector,\n osDetector,\n processDetector,\n type Resource,\n serviceInstanceIdDetector,\n} from \"@opentelemetry/resources\";\nimport {\n BatchSpanProcessor,\n type ReadableSpan,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace-base\";\nimport Debug from \"debug\";\nimport {\n defaultDevServerHost,\n defaultInngestApiBaseUrl,\n} from \"../../../helpers/consts.ts\";\nimport { devServerAvailable } from \"../../../helpers/devserver.ts\";\nimport { devServerHost } from \"../../../helpers/env.ts\";\nimport type { Inngest } from \"../../Inngest.ts\";\nimport { getAsyncCtx } from \"../als.ts\";\nimport { clientProcessorMap } from \"./access.ts\";\nimport { Attribute, debugPrefix, TraceStateKey } from \"./consts.ts\";\n\nconst processorDebug = Debug(`${debugPrefix}:InngestSpanProcessor`);\n\n/**\n * A set of resource attributes that are used to identify the Inngest app and\n * the function that is being executed. This is used to store the resource\n * attributes for the spans that are exported to the Inngest endpoint, and cache\n * them for later use.\n */\nlet _resourceAttributes: Resource | undefined;\n\n/**\n * A set of information about an execution that's used to set attributes on\n * userland spans sent to Inngest for proper indexing.\n */\nexport type ParentState = {\n traceparent: string;\n runId: string;\n appId: string | undefined;\n functionId: string | undefined;\n traceRef: string | undefined;\n};\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n *\n * THIS IS THE INTERNAL IMPLEMENTATION OF THE SPAN PROCESSOR AND SHOULD NOT BE\n * USED BY USERS DIRECTLY. USE THE {@link PublicInngestSpanProcessor} CLASS\n * INSTEAD.\n */\nexport class InngestSpanProcessor implements SpanProcessor {\n /**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n *\n * It is optional here as this is the private constructor and only used\n * internally; we set `app` elsewhere as when we create the processor (as\n * early as possible when the process starts) we don't necessarily have the\n * app available yet.\n *\n * So, internally we can delay setting ths until later.\n */\n app?: Inngest.Like,\n ) {\n if (app) {\n clientProcessorMap.set(app as Inngest.Any, this);\n }\n }\n\n /**\n * A `BatchSpanProcessor` that is used to export spans to the Inngest\n * endpoint. This is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n */\n #batcher: Promise<BatchSpanProcessor> | undefined;\n\n /**\n * A set of spans used to track spans that we care about, so that we can\n * export them to the OTel endpoint.\n *\n * If a span falls out of reference, it will be removed from this set as we'll\n * never get a chance to export it or remove it anyway.\n */\n #spansToExport = new WeakSet<Span>();\n\n /**\n * A map of span IDs to their parent state, which includes a block of\n * information that can be used and pushed back to the Inngest endpoint to\n * ingest spans.\n */\n #traceParents = new Map<string, ParentState>();\n\n /**\n * A registry used to clean up items from the `traceParents` map when spans\n * fall out of reference. This is used to avoid memory leaks in the case where\n * a span is not exported, remains unended, and is left in memory before being\n * GC'd.\n */\n #spanCleanup = new FinalizationRegistry<string>((spanId) => {\n if (spanId) {\n this.#traceParents.delete(spanId);\n }\n });\n\n /**\n * In order to only capture a subset of spans, we need to declare the initial\n * span that we care about and then export its children.\n *\n * Call this method (ideally just before execution starts) with that initial\n * span to trigger capturing all following children as well as initialize the\n * batcher.\n */\n public declareStartingSpan({\n span,\n runId,\n traceparent,\n tracestate,\n }: {\n span: Span;\n runId: string;\n traceparent: string | undefined;\n tracestate: string | undefined;\n }): void {\n // Upsert the batcher ready for later. We do this here to bootstrap it with\n // the correct async context as soon as we can. As this method is only\n // called just before execution, we know we're all set up.\n //\n // Waiting to call this until we actually need the batcher would mean that\n // we might not have the correct async context set up, as we'd likely be in\n // some span lifecycle method that doesn't have the same chain of execution.\n void this.ensureBatcherInitialized();\n\n // If we don't have a traceparent, then we can't track this span. This is\n // likely a span that we don't care about, so we can ignore it.\n if (!traceparent) {\n return processorDebug(\n \"no traceparent found for span\",\n span.spanContext().spanId,\n \"so skipping it\",\n );\n }\n\n // We also attempt to use `tracestate`. The values we fetch from these\n // should be optional, as it's likely the Executor won't need us to parrot\n // them back in later versions.\n let appId: string | undefined;\n let functionId: string | undefined;\n let traceRef: string | undefined;\n\n if (tracestate) {\n try {\n const entries = Object.fromEntries(\n tracestate.split(\",\").map((kv) => kv.split(\"=\") as [string, string]),\n );\n\n appId = entries[TraceStateKey.AppId];\n functionId = entries[TraceStateKey.FunctionId];\n traceRef = entries[TraceStateKey.TraceRef];\n } catch (err) {\n processorDebug(\n \"failed to parse tracestate\",\n tracestate,\n \"so skipping it;\",\n err,\n );\n }\n }\n\n // This is a span that we care about, so let's make sure it and its\n // children are exported.\n processorDebug.extend(\"declareStartingSpan\")(\n \"declaring:\",\n span.spanContext().spanId,\n \"for traceparent\",\n traceparent,\n );\n\n // Set a load of attributes on this span so that we can nicely identify\n // runtime, paths, etc. Only this span will have these attributes.\n span.setAttributes(InngestSpanProcessor.resourceAttributes.attributes);\n\n this.trackSpan(\n {\n appId,\n functionId,\n runId,\n traceparent,\n traceRef,\n },\n span,\n );\n }\n\n /**\n * A getter for retrieving resource attributes for the current process. This\n * is used to set the resource attributes for the spans that are exported to\n * the Inngest endpoint, and cache them for later use.\n */\n static get resourceAttributes(): Resource {\n if (!_resourceAttributes) {\n _resourceAttributes = detectResources({\n detectors: [\n osDetector,\n envDetector,\n hostDetector,\n processDetector,\n serviceInstanceIdDetector,\n ],\n });\n }\n\n return _resourceAttributes;\n }\n\n /**\n * The batcher is a singleton that is used to export spans to the OTel\n * endpoint. It is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n *\n * The batcher is only referenced once we've found a span we're interested in,\n * so this should always have everything it needs on the app by then.\n */\n private ensureBatcherInitialized(): Promise<BatchSpanProcessor> {\n if (!this.#batcher) {\n this.#batcher = new Promise(async (resolve, reject) => {\n try {\n // We retrieve the app from the async context, so we must make sure\n // that this function is called from the correct chain.\n const store = await getAsyncCtx();\n if (!store) {\n throw new Error(\n \"No async context found; cannot create batcher to export traces\",\n );\n }\n\n const app = store.app as Inngest.Any;\n\n // Fetch the URL for the Inngest endpoint using the app's config.\n let url: URL;\n const path = \"/v1/traces/userland\";\n if (app.apiBaseUrl) {\n url = new URL(path, app.apiBaseUrl);\n } else {\n url = new URL(path, defaultInngestApiBaseUrl);\n\n if (app[\"mode\"] && app[\"mode\"].isDev && app[\"mode\"].isInferred) {\n const devHost = devServerHost() || defaultDevServerHost;\n const hasDevServer = await devServerAvailable(\n devHost,\n app[\"fetch\"],\n );\n if (hasDevServer) {\n url = new URL(path, devHost);\n }\n } else if (app[\"mode\"]?.explicitDevUrl) {\n url = new URL(path, app[\"mode\"].explicitDevUrl.href);\n }\n }\n\n processorDebug(\n \"batcher lazily accessed; creating new batcher with URL\",\n url,\n );\n\n const exporter = new OTLPTraceExporter({\n url: url.href,\n\n headers: {\n Authorization: `Bearer ${app[\"inngestApi\"][\"signingKey\"]}`,\n },\n });\n\n resolve(new BatchSpanProcessor(exporter));\n } catch (err) {\n reject(err);\n }\n });\n }\n\n return this.#batcher;\n }\n\n /**\n * Mark a span as being tracked by this processor, meaning it will be exported\n * to the Inggest endpoint when it ends.\n */\n private trackSpan(parentState: ParentState, span: Span): void {\n const spanId = span.spanContext().spanId;\n\n this.#spanCleanup.register(span, spanId, span);\n this.#spansToExport.add(span);\n this.#traceParents.set(spanId, parentState);\n\n span.setAttribute(Attribute.InngestTraceparent, parentState.traceparent);\n span.setAttribute(Attribute.InngestRunId, parentState.runId);\n\n // Setting app ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.appId) {\n span.setAttribute(Attribute.InngestAppId1, parentState.appId);\n span.setAttribute(Attribute.InngestAppId2, parentState.appId);\n }\n\n // Setting function ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.functionId) {\n span.setAttribute(Attribute.InngestFunctionId, parentState.functionId);\n }\n\n if (parentState.traceRef) {\n span.setAttribute(Attribute.InngestTraceRef, parentState.traceRef);\n }\n }\n\n /**\n * Clean up any references to a span that has ended. This is used to avoid\n * memory leaks in the case where a span is not exported, remains unended, and\n * is left in memory before being GC'd.\n */\n private cleanupSpan(span: Span): void {\n const spanId = span.spanContext().spanId;\n\n // This span is no longer in use, so we can remove it from the cleanup\n // registry.\n this.#spanCleanup.unregister(span);\n this.#spansToExport.delete(span);\n this.#traceParents.delete(spanId);\n }\n\n /**\n * An implementation of the `onStart` method from the `SpanProcessor`\n * interface. This is called when a span is started, and is used to track\n * spans that are children of spans we care about.\n */\n onStart(span: Span): void {\n const debug = processorDebug.extend(\"onStart\");\n const spanId = span.spanContext().spanId;\n // 🤫 It seems to work\n const parentSpanId = (span as unknown as ReadableSpan).parentSpanContext\n ?.spanId;\n\n // The root span isn't captured here, but we can capture children of it\n // here.\n\n if (!parentSpanId) {\n // All spans that Inngest cares about will have a parent, so ignore this\n debug(\"no parent span ID for\", spanId, \"so skipping it\");\n\n return;\n }\n\n const parentState = this.#traceParents.get(parentSpanId);\n if (parentState) {\n // This span is a child of a span we care about, so add it to the list of\n // tracked spans so that we also capture its children\n debug(\n \"found traceparent\",\n parentState,\n \"in span ID\",\n parentSpanId,\n \"so adding\",\n spanId,\n );\n\n this.trackSpan(parentState, span);\n }\n }\n\n /**\n * An implementation of the `onEnd` method from the `SpanProcessor` interface.\n * This is called when a span ends, and is used to export spans to the Inngest\n * endpoint.\n */\n onEnd(span: ReadableSpan): void {\n const debug = processorDebug.extend(\"onEnd\");\n const spanId = span.spanContext().spanId;\n\n try {\n if (this.#spansToExport.has(span as unknown as Span)) {\n if (!this.#batcher) {\n return debug(\n \"batcher not initialized, so failed exporting span\",\n spanId,\n );\n }\n\n debug(\"exporting span\", spanId);\n return void this.#batcher.then((batcher) => batcher.onEnd(span));\n }\n\n debug(\"not exporting span\", spanId, \"as we don't care about it\");\n } finally {\n this.cleanupSpan(span as unknown as Span);\n }\n }\n\n /**\n * An implementation of the `forceFlush` method from the `SpanProcessor`\n * interface. This is called to force the processor to flush any spans that\n * are currently in the batcher. This is used to ensure that spans are\n * exported to the Inngest endpoint before the process exits.\n *\n * Notably, we call this in the `beforeResponse` middleware hook to ensure\n * that spans for a run as exported as soon as possible and before the\n * serverless process is killed.\n */\n async forceFlush(): Promise<void> {\n const flushDebug = processorDebug.extend(\"forceFlush\");\n flushDebug(\"force flushing batcher\");\n\n return this.#batcher\n ?.then((batcher) => batcher.forceFlush())\n .catch((err) => {\n flushDebug(\"error flushing batcher\", err, \"ignoring\");\n });\n }\n\n async shutdown(): Promise<void> {\n processorDebug.extend(\"shutdown\")(\"shutting down batcher\");\n\n return this.#batcher?.then((batcher) => batcher.shutdown());\n }\n}\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\nexport class PublicInngestSpanProcessor extends InngestSpanProcessor {\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n */\n app: Inngest.Like,\n ) {\n super(app);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"processor.cjs","names":["debugPrefix","_resourceAttributes: Resource | undefined","#traceParents","appId: string | undefined","functionId: string | undefined","traceRef: string | undefined","TraceStateKey","osDetector","envDetector","hostDetector","processDetector","serviceInstanceIdDetector","#batcher","getAsyncCtx","url: URL","defaultInngestApiBaseUrl","devServerHost","defaultDevServerHost","devServerAvailable","BatchSpanProcessor","OTLPTraceExporter","#spanCleanup","#spansToExport","Attribute","debug"],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":["import type { Span } from \"@opentelemetry/api\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport {\n detectResources,\n envDetector,\n hostDetector,\n osDetector,\n processDetector,\n type Resource,\n serviceInstanceIdDetector,\n} from \"@opentelemetry/resources\";\nimport {\n BatchSpanProcessor,\n type ReadableSpan,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace-base\";\nimport Debug from \"debug\";\nimport {\n defaultDevServerHost,\n defaultInngestApiBaseUrl,\n} from \"../../../helpers/consts.ts\";\nimport { devServerAvailable } from \"../../../helpers/devserver.ts\";\nimport { devServerHost } from \"../../../helpers/env.ts\";\nimport type { Inngest } from \"../../Inngest.ts\";\nimport { getAsyncCtx } from \"../als.ts\";\nimport { clientProcessorMap } from \"./access.ts\";\nimport { Attribute, debugPrefix, TraceStateKey } from \"./consts.ts\";\n\nconst processorDebug = Debug(`${debugPrefix}:InngestSpanProcessor`);\n\n/**\n * A set of resource attributes that are used to identify the Inngest app and\n * the function that is being executed. This is used to store the resource\n * attributes for the spans that are exported to the Inngest endpoint, and cache\n * them for later use.\n */\nlet _resourceAttributes: Resource | undefined;\n\n/**\n * A set of information about an execution that's used to set attributes on\n * userland spans sent to Inngest for proper indexing.\n */\nexport type ParentState = {\n traceparent: string;\n runId: string;\n appId: string | undefined;\n functionId: string | undefined;\n traceRef: string | undefined;\n};\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n *\n * THIS IS THE INTERNAL IMPLEMENTATION OF THE SPAN PROCESSOR AND SHOULD NOT BE\n * USED BY USERS DIRECTLY. USE THE {@link PublicInngestSpanProcessor} CLASS\n * INSTEAD.\n */\nexport class InngestSpanProcessor implements SpanProcessor {\n /**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n *\n * It is optional here as this is the private constructor and only used\n * internally; we set `app` elsewhere as when we create the processor (as\n * early as possible when the process starts) we don't necessarily have the\n * app available yet.\n *\n * So, internally we can delay setting ths until later.\n */\n app?: Inngest.Like,\n ) {\n if (app) {\n clientProcessorMap.set(app as Inngest.Any, this);\n }\n }\n\n /**\n * A `BatchSpanProcessor` that is used to export spans to the Inngest\n * endpoint. This is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n */\n #batcher: Promise<BatchSpanProcessor> | undefined;\n\n /**\n * A set of spans used to track spans that we care about, so that we can\n * export them to the OTel endpoint.\n *\n * If a span falls out of reference, it will be removed from this set as we'll\n * never get a chance to export it or remove it anyway.\n */\n #spansToExport = new WeakSet<Span>();\n\n /**\n * A map of span IDs to their parent state, which includes a block of\n * information that can be used and pushed back to the Inngest endpoint to\n * ingest spans.\n */\n #traceParents = new Map<string, ParentState>();\n\n /**\n * A registry used to clean up items from the `traceParents` map when spans\n * fall out of reference. This is used to avoid memory leaks in the case where\n * a span is not exported, remains unended, and is left in memory before being\n * GC'd.\n */\n #spanCleanup = new FinalizationRegistry<string>((spanId) => {\n if (spanId) {\n this.#traceParents.delete(spanId);\n }\n });\n\n /**\n * In order to only capture a subset of spans, we need to declare the initial\n * span that we care about and then export its children.\n *\n * Call this method (ideally just before execution starts) with that initial\n * span to trigger capturing all following children as well as initialize the\n * batcher.\n */\n public declareStartingSpan({\n span,\n runId,\n traceparent,\n tracestate,\n }: {\n span: Span;\n runId: string;\n traceparent: string | undefined;\n tracestate: string | undefined;\n }): void {\n // Upsert the batcher ready for later. We do this here to bootstrap it with\n // the correct async context as soon as we can. As this method is only\n // called just before execution, we know we're all set up.\n //\n // Waiting to call this until we actually need the batcher would mean that\n // we might not have the correct async context set up, as we'd likely be in\n // some span lifecycle method that doesn't have the same chain of execution.\n void this.ensureBatcherInitialized();\n\n // If we don't have a traceparent, then we can't track this span. This is\n // likely a span that we don't care about, so we can ignore it.\n if (!traceparent) {\n return processorDebug(\n \"no traceparent found for span\",\n span.spanContext().spanId,\n \"so skipping it\",\n );\n }\n\n // We also attempt to use `tracestate`. The values we fetch from these\n // should be optional, as it's likely the Executor won't need us to parrot\n // them back in later versions.\n let appId: string | undefined;\n let functionId: string | undefined;\n let traceRef: string | undefined;\n\n if (tracestate) {\n try {\n const entries = Object.fromEntries(\n tracestate.split(\",\").map((kv) => kv.split(\"=\") as [string, string]),\n );\n\n appId = entries[TraceStateKey.AppId];\n functionId = entries[TraceStateKey.FunctionId];\n traceRef = entries[TraceStateKey.TraceRef];\n } catch (err) {\n processorDebug(\n \"failed to parse tracestate\",\n tracestate,\n \"so skipping it;\",\n err,\n );\n }\n }\n\n // This is a span that we care about, so let's make sure it and its\n // children are exported.\n processorDebug.extend(\"declareStartingSpan\")(\n \"declaring:\",\n span.spanContext().spanId,\n \"for traceparent\",\n traceparent,\n );\n\n // Set a load of attributes on this span so that we can nicely identify\n // runtime, paths, etc. Only this span will have these attributes.\n span.setAttributes(InngestSpanProcessor.resourceAttributes.attributes);\n\n this.trackSpan(\n {\n appId,\n functionId,\n runId,\n traceparent,\n traceRef,\n },\n span,\n );\n }\n\n /**\n * A getter for retrieving resource attributes for the current process. This\n * is used to set the resource attributes for the spans that are exported to\n * the Inngest endpoint, and cache them for later use.\n */\n static get resourceAttributes(): Resource {\n if (!_resourceAttributes) {\n _resourceAttributes = detectResources({\n detectors: [\n osDetector,\n envDetector,\n hostDetector,\n processDetector,\n serviceInstanceIdDetector,\n ],\n });\n }\n\n return _resourceAttributes;\n }\n\n /**\n * The batcher is a singleton that is used to export spans to the OTel\n * endpoint. It is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n *\n * The batcher is only referenced once we've found a span we're interested in,\n * so this should always have everything it needs on the app by then.\n */\n private ensureBatcherInitialized(): Promise<BatchSpanProcessor> {\n if (!this.#batcher) {\n this.#batcher = new Promise(async (resolve, reject) => {\n try {\n // We retrieve the app from the async context, so we must make sure\n // that this function is called from the correct chain.\n const store = await getAsyncCtx();\n if (!store) {\n throw new Error(\n \"No async context found; cannot create batcher to export traces\",\n );\n }\n\n const app = store.app as Inngest.Any;\n\n // Fetch the URL for the Inngest endpoint using the app's config.\n let url: URL;\n const path = \"/v1/traces/userland\";\n if (app.apiBaseUrl) {\n url = new URL(path, app.apiBaseUrl);\n } else {\n url = new URL(path, defaultInngestApiBaseUrl);\n\n if (app[\"mode\"] && app[\"mode\"].isDev && app[\"mode\"].isInferred) {\n const devHost = devServerHost() || defaultDevServerHost;\n const hasDevServer = await devServerAvailable(\n devHost,\n app[\"fetch\"],\n );\n if (hasDevServer) {\n url = new URL(path, devHost);\n }\n } else if (app[\"mode\"]?.explicitDevUrl) {\n url = new URL(path, app[\"mode\"].explicitDevUrl.href);\n }\n }\n\n processorDebug(\n \"batcher lazily accessed; creating new batcher with URL\",\n url,\n );\n\n const exporter = new OTLPTraceExporter({\n url: url.href,\n\n headers: {\n ...app[\"headers\"],\n Authorization: `Bearer ${app[\"inngestApi\"][\"signingKey\"]}`,\n },\n });\n\n resolve(new BatchSpanProcessor(exporter));\n } catch (err) {\n reject(err);\n }\n });\n }\n\n return this.#batcher;\n }\n\n /**\n * Mark a span as being tracked by this processor, meaning it will be exported\n * to the Inggest endpoint when it ends.\n */\n private trackSpan(parentState: ParentState, span: Span): void {\n const spanId = span.spanContext().spanId;\n\n this.#spanCleanup.register(span, spanId, span);\n this.#spansToExport.add(span);\n this.#traceParents.set(spanId, parentState);\n\n span.setAttribute(Attribute.InngestTraceparent, parentState.traceparent);\n span.setAttribute(Attribute.InngestRunId, parentState.runId);\n\n // Setting app ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.appId) {\n span.setAttribute(Attribute.InngestAppId1, parentState.appId);\n span.setAttribute(Attribute.InngestAppId2, parentState.appId);\n }\n\n // Setting function ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.functionId) {\n span.setAttribute(Attribute.InngestFunctionId, parentState.functionId);\n }\n\n if (parentState.traceRef) {\n span.setAttribute(Attribute.InngestTraceRef, parentState.traceRef);\n }\n }\n\n /**\n * Clean up any references to a span that has ended. This is used to avoid\n * memory leaks in the case where a span is not exported, remains unended, and\n * is left in memory before being GC'd.\n */\n private cleanupSpan(span: Span): void {\n const spanId = span.spanContext().spanId;\n\n // This span is no longer in use, so we can remove it from the cleanup\n // registry.\n this.#spanCleanup.unregister(span);\n this.#spansToExport.delete(span);\n this.#traceParents.delete(spanId);\n }\n\n /**\n * An implementation of the `onStart` method from the `SpanProcessor`\n * interface. This is called when a span is started, and is used to track\n * spans that are children of spans we care about.\n */\n onStart(span: Span): void {\n const debug = processorDebug.extend(\"onStart\");\n const spanId = span.spanContext().spanId;\n // 🤫 It seems to work\n const parentSpanId = (span as unknown as ReadableSpan).parentSpanContext\n ?.spanId;\n\n // The root span isn't captured here, but we can capture children of it\n // here.\n\n if (!parentSpanId) {\n // All spans that Inngest cares about will have a parent, so ignore this\n debug(\"no parent span ID for\", spanId, \"so skipping it\");\n\n return;\n }\n\n const parentState = this.#traceParents.get(parentSpanId);\n if (parentState) {\n // This span is a child of a span we care about, so add it to the list of\n // tracked spans so that we also capture its children\n debug(\n \"found traceparent\",\n parentState,\n \"in span ID\",\n parentSpanId,\n \"so adding\",\n spanId,\n );\n\n this.trackSpan(parentState, span);\n }\n }\n\n /**\n * An implementation of the `onEnd` method from the `SpanProcessor` interface.\n * This is called when a span ends, and is used to export spans to the Inngest\n * endpoint.\n */\n onEnd(span: ReadableSpan): void {\n const debug = processorDebug.extend(\"onEnd\");\n const spanId = span.spanContext().spanId;\n\n try {\n if (this.#spansToExport.has(span as unknown as Span)) {\n if (!this.#batcher) {\n return debug(\n \"batcher not initialized, so failed exporting span\",\n spanId,\n );\n }\n\n debug(\"exporting span\", spanId);\n return void this.#batcher.then((batcher) => batcher.onEnd(span));\n }\n\n debug(\"not exporting span\", spanId, \"as we don't care about it\");\n } finally {\n this.cleanupSpan(span as unknown as Span);\n }\n }\n\n /**\n * An implementation of the `forceFlush` method from the `SpanProcessor`\n * interface. This is called to force the processor to flush any spans that\n * are currently in the batcher. This is used to ensure that spans are\n * exported to the Inngest endpoint before the process exits.\n *\n * Notably, we call this in the `beforeResponse` middleware hook to ensure\n * that spans for a run as exported as soon as possible and before the\n * serverless process is killed.\n */\n async forceFlush(): Promise<void> {\n const flushDebug = processorDebug.extend(\"forceFlush\");\n flushDebug(\"force flushing batcher\");\n\n return this.#batcher\n ?.then((batcher) => batcher.forceFlush())\n .catch((err) => {\n flushDebug(\"error flushing batcher\", err, \"ignoring\");\n });\n }\n\n async shutdown(): Promise<void> {\n processorDebug.extend(\"shutdown\")(\"shutting down batcher\");\n\n return this.#batcher?.then((batcher) => batcher.shutdown());\n }\n}\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\nexport class PublicInngestSpanProcessor extends InngestSpanProcessor {\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n */\n app: Inngest.Like,\n ) {\n super(app);\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"processor.d.cts","names":[],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AAucA;;;;;;cAzYa,oBAAA,YAAgC;;;;;;;;;;;;;;;;;;;;;;QAqBnC,OAAA,CAAQ;;;;;;;;;;;;;;;UAyDR;;;;;;;;;;mCAgFyB;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAyInB;;;;;;cAuCF;;;;;;;;;;;gBAiCQ;cAWF;;;;;;;;;;cAeP,0BAAA,SAAmC,oBAAA;;;;;;OAMvC,OAAA,CAAQ"}
1
+ {"version":3,"file":"processor.d.cts","names":[],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AAwcA;;;;;;cA1Ya,oBAAA,YAAgC;;;;;;;;;;;;;;;;;;;;;;QAqBnC,OAAA,CAAQ;;;;;;;;;;;;;;;UAyDR;;;;;;;;;;mCAgFyB;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA0InB;;;;;;cAuCF;;;;;;;;;;;gBAiCQ;cAWF;;;;;;;;;;cAeP,0BAAA,SAAmC,oBAAA;;;;;;OAMvC,OAAA,CAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"processor.d.ts","names":[],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AAucA;;;;;;cAzYa,oBAAA,YAAgC;;;;;;;;;;;;;;;;;;;;;;QAqBnC,OAAA,CAAQ;;;;;;;;;;;;;;;UAyDR;;;;;;;;;;mCAgFyB;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAyInB;;;;;;cAuCF;;;;;;;;;;;gBAiCQ;cAWF;;;;;;;;;;cAeP,0BAAA,SAAmC,oBAAA;;;;;;OAMvC,OAAA,CAAQ"}
1
+ {"version":3,"file":"processor.d.ts","names":[],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AAwcA;;;;;;cA1Ya,oBAAA,YAAgC;;;;;;;;;;;;;;;;;;;;;;QAqBnC,OAAA,CAAQ;;;;;;;;;;;;;;;UAyDR;;;;;;;;;;mCAgFyB;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA0InB;;;;;;cAuCF;;;;;;;;;;;gBAiCQ;cAWF;;;;;;;;;;cAeP,0BAAA,SAAmC,oBAAA;;;;;;OAMvC,OAAA,CAAQ"}
@@ -147,7 +147,10 @@ var InngestSpanProcessor = class InngestSpanProcessor {
147
147
  processorDebug("batcher lazily accessed; creating new batcher with URL", url);
148
148
  resolve(new BatchSpanProcessor(new OTLPTraceExporter({
149
149
  url: url.href,
150
- headers: { Authorization: `Bearer ${app["inngestApi"]["signingKey"]}` }
150
+ headers: {
151
+ ...app["headers"],
152
+ Authorization: `Bearer ${app["inngestApi"]["signingKey"]}`
153
+ }
151
154
  })));
152
155
  } catch (err) {
153
156
  reject(err);
@@ -1 +1 @@
1
- {"version":3,"file":"processor.js","names":["Debug","_resourceAttributes: Resource | undefined","#traceParents","appId: string | undefined","functionId: string | undefined","traceRef: string | undefined","#batcher","url: URL","#spanCleanup","#spansToExport","debug"],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":["import type { Span } from \"@opentelemetry/api\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport {\n detectResources,\n envDetector,\n hostDetector,\n osDetector,\n processDetector,\n type Resource,\n serviceInstanceIdDetector,\n} from \"@opentelemetry/resources\";\nimport {\n BatchSpanProcessor,\n type ReadableSpan,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace-base\";\nimport Debug from \"debug\";\nimport {\n defaultDevServerHost,\n defaultInngestApiBaseUrl,\n} from \"../../../helpers/consts.ts\";\nimport { devServerAvailable } from \"../../../helpers/devserver.ts\";\nimport { devServerHost } from \"../../../helpers/env.ts\";\nimport type { Inngest } from \"../../Inngest.ts\";\nimport { getAsyncCtx } from \"../als.ts\";\nimport { clientProcessorMap } from \"./access.ts\";\nimport { Attribute, debugPrefix, TraceStateKey } from \"./consts.ts\";\n\nconst processorDebug = Debug(`${debugPrefix}:InngestSpanProcessor`);\n\n/**\n * A set of resource attributes that are used to identify the Inngest app and\n * the function that is being executed. This is used to store the resource\n * attributes for the spans that are exported to the Inngest endpoint, and cache\n * them for later use.\n */\nlet _resourceAttributes: Resource | undefined;\n\n/**\n * A set of information about an execution that's used to set attributes on\n * userland spans sent to Inngest for proper indexing.\n */\nexport type ParentState = {\n traceparent: string;\n runId: string;\n appId: string | undefined;\n functionId: string | undefined;\n traceRef: string | undefined;\n};\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n *\n * THIS IS THE INTERNAL IMPLEMENTATION OF THE SPAN PROCESSOR AND SHOULD NOT BE\n * USED BY USERS DIRECTLY. USE THE {@link PublicInngestSpanProcessor} CLASS\n * INSTEAD.\n */\nexport class InngestSpanProcessor implements SpanProcessor {\n /**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n *\n * It is optional here as this is the private constructor and only used\n * internally; we set `app` elsewhere as when we create the processor (as\n * early as possible when the process starts) we don't necessarily have the\n * app available yet.\n *\n * So, internally we can delay setting ths until later.\n */\n app?: Inngest.Like,\n ) {\n if (app) {\n clientProcessorMap.set(app as Inngest.Any, this);\n }\n }\n\n /**\n * A `BatchSpanProcessor` that is used to export spans to the Inngest\n * endpoint. This is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n */\n #batcher: Promise<BatchSpanProcessor> | undefined;\n\n /**\n * A set of spans used to track spans that we care about, so that we can\n * export them to the OTel endpoint.\n *\n * If a span falls out of reference, it will be removed from this set as we'll\n * never get a chance to export it or remove it anyway.\n */\n #spansToExport = new WeakSet<Span>();\n\n /**\n * A map of span IDs to their parent state, which includes a block of\n * information that can be used and pushed back to the Inngest endpoint to\n * ingest spans.\n */\n #traceParents = new Map<string, ParentState>();\n\n /**\n * A registry used to clean up items from the `traceParents` map when spans\n * fall out of reference. This is used to avoid memory leaks in the case where\n * a span is not exported, remains unended, and is left in memory before being\n * GC'd.\n */\n #spanCleanup = new FinalizationRegistry<string>((spanId) => {\n if (spanId) {\n this.#traceParents.delete(spanId);\n }\n });\n\n /**\n * In order to only capture a subset of spans, we need to declare the initial\n * span that we care about and then export its children.\n *\n * Call this method (ideally just before execution starts) with that initial\n * span to trigger capturing all following children as well as initialize the\n * batcher.\n */\n public declareStartingSpan({\n span,\n runId,\n traceparent,\n tracestate,\n }: {\n span: Span;\n runId: string;\n traceparent: string | undefined;\n tracestate: string | undefined;\n }): void {\n // Upsert the batcher ready for later. We do this here to bootstrap it with\n // the correct async context as soon as we can. As this method is only\n // called just before execution, we know we're all set up.\n //\n // Waiting to call this until we actually need the batcher would mean that\n // we might not have the correct async context set up, as we'd likely be in\n // some span lifecycle method that doesn't have the same chain of execution.\n void this.ensureBatcherInitialized();\n\n // If we don't have a traceparent, then we can't track this span. This is\n // likely a span that we don't care about, so we can ignore it.\n if (!traceparent) {\n return processorDebug(\n \"no traceparent found for span\",\n span.spanContext().spanId,\n \"so skipping it\",\n );\n }\n\n // We also attempt to use `tracestate`. The values we fetch from these\n // should be optional, as it's likely the Executor won't need us to parrot\n // them back in later versions.\n let appId: string | undefined;\n let functionId: string | undefined;\n let traceRef: string | undefined;\n\n if (tracestate) {\n try {\n const entries = Object.fromEntries(\n tracestate.split(\",\").map((kv) => kv.split(\"=\") as [string, string]),\n );\n\n appId = entries[TraceStateKey.AppId];\n functionId = entries[TraceStateKey.FunctionId];\n traceRef = entries[TraceStateKey.TraceRef];\n } catch (err) {\n processorDebug(\n \"failed to parse tracestate\",\n tracestate,\n \"so skipping it;\",\n err,\n );\n }\n }\n\n // This is a span that we care about, so let's make sure it and its\n // children are exported.\n processorDebug.extend(\"declareStartingSpan\")(\n \"declaring:\",\n span.spanContext().spanId,\n \"for traceparent\",\n traceparent,\n );\n\n // Set a load of attributes on this span so that we can nicely identify\n // runtime, paths, etc. Only this span will have these attributes.\n span.setAttributes(InngestSpanProcessor.resourceAttributes.attributes);\n\n this.trackSpan(\n {\n appId,\n functionId,\n runId,\n traceparent,\n traceRef,\n },\n span,\n );\n }\n\n /**\n * A getter for retrieving resource attributes for the current process. This\n * is used to set the resource attributes for the spans that are exported to\n * the Inngest endpoint, and cache them for later use.\n */\n static get resourceAttributes(): Resource {\n if (!_resourceAttributes) {\n _resourceAttributes = detectResources({\n detectors: [\n osDetector,\n envDetector,\n hostDetector,\n processDetector,\n serviceInstanceIdDetector,\n ],\n });\n }\n\n return _resourceAttributes;\n }\n\n /**\n * The batcher is a singleton that is used to export spans to the OTel\n * endpoint. It is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n *\n * The batcher is only referenced once we've found a span we're interested in,\n * so this should always have everything it needs on the app by then.\n */\n private ensureBatcherInitialized(): Promise<BatchSpanProcessor> {\n if (!this.#batcher) {\n this.#batcher = new Promise(async (resolve, reject) => {\n try {\n // We retrieve the app from the async context, so we must make sure\n // that this function is called from the correct chain.\n const store = await getAsyncCtx();\n if (!store) {\n throw new Error(\n \"No async context found; cannot create batcher to export traces\",\n );\n }\n\n const app = store.app as Inngest.Any;\n\n // Fetch the URL for the Inngest endpoint using the app's config.\n let url: URL;\n const path = \"/v1/traces/userland\";\n if (app.apiBaseUrl) {\n url = new URL(path, app.apiBaseUrl);\n } else {\n url = new URL(path, defaultInngestApiBaseUrl);\n\n if (app[\"mode\"] && app[\"mode\"].isDev && app[\"mode\"].isInferred) {\n const devHost = devServerHost() || defaultDevServerHost;\n const hasDevServer = await devServerAvailable(\n devHost,\n app[\"fetch\"],\n );\n if (hasDevServer) {\n url = new URL(path, devHost);\n }\n } else if (app[\"mode\"]?.explicitDevUrl) {\n url = new URL(path, app[\"mode\"].explicitDevUrl.href);\n }\n }\n\n processorDebug(\n \"batcher lazily accessed; creating new batcher with URL\",\n url,\n );\n\n const exporter = new OTLPTraceExporter({\n url: url.href,\n\n headers: {\n Authorization: `Bearer ${app[\"inngestApi\"][\"signingKey\"]}`,\n },\n });\n\n resolve(new BatchSpanProcessor(exporter));\n } catch (err) {\n reject(err);\n }\n });\n }\n\n return this.#batcher;\n }\n\n /**\n * Mark a span as being tracked by this processor, meaning it will be exported\n * to the Inggest endpoint when it ends.\n */\n private trackSpan(parentState: ParentState, span: Span): void {\n const spanId = span.spanContext().spanId;\n\n this.#spanCleanup.register(span, spanId, span);\n this.#spansToExport.add(span);\n this.#traceParents.set(spanId, parentState);\n\n span.setAttribute(Attribute.InngestTraceparent, parentState.traceparent);\n span.setAttribute(Attribute.InngestRunId, parentState.runId);\n\n // Setting app ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.appId) {\n span.setAttribute(Attribute.InngestAppId1, parentState.appId);\n span.setAttribute(Attribute.InngestAppId2, parentState.appId);\n }\n\n // Setting function ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.functionId) {\n span.setAttribute(Attribute.InngestFunctionId, parentState.functionId);\n }\n\n if (parentState.traceRef) {\n span.setAttribute(Attribute.InngestTraceRef, parentState.traceRef);\n }\n }\n\n /**\n * Clean up any references to a span that has ended. This is used to avoid\n * memory leaks in the case where a span is not exported, remains unended, and\n * is left in memory before being GC'd.\n */\n private cleanupSpan(span: Span): void {\n const spanId = span.spanContext().spanId;\n\n // This span is no longer in use, so we can remove it from the cleanup\n // registry.\n this.#spanCleanup.unregister(span);\n this.#spansToExport.delete(span);\n this.#traceParents.delete(spanId);\n }\n\n /**\n * An implementation of the `onStart` method from the `SpanProcessor`\n * interface. This is called when a span is started, and is used to track\n * spans that are children of spans we care about.\n */\n onStart(span: Span): void {\n const debug = processorDebug.extend(\"onStart\");\n const spanId = span.spanContext().spanId;\n // 🤫 It seems to work\n const parentSpanId = (span as unknown as ReadableSpan).parentSpanContext\n ?.spanId;\n\n // The root span isn't captured here, but we can capture children of it\n // here.\n\n if (!parentSpanId) {\n // All spans that Inngest cares about will have a parent, so ignore this\n debug(\"no parent span ID for\", spanId, \"so skipping it\");\n\n return;\n }\n\n const parentState = this.#traceParents.get(parentSpanId);\n if (parentState) {\n // This span is a child of a span we care about, so add it to the list of\n // tracked spans so that we also capture its children\n debug(\n \"found traceparent\",\n parentState,\n \"in span ID\",\n parentSpanId,\n \"so adding\",\n spanId,\n );\n\n this.trackSpan(parentState, span);\n }\n }\n\n /**\n * An implementation of the `onEnd` method from the `SpanProcessor` interface.\n * This is called when a span ends, and is used to export spans to the Inngest\n * endpoint.\n */\n onEnd(span: ReadableSpan): void {\n const debug = processorDebug.extend(\"onEnd\");\n const spanId = span.spanContext().spanId;\n\n try {\n if (this.#spansToExport.has(span as unknown as Span)) {\n if (!this.#batcher) {\n return debug(\n \"batcher not initialized, so failed exporting span\",\n spanId,\n );\n }\n\n debug(\"exporting span\", spanId);\n return void this.#batcher.then((batcher) => batcher.onEnd(span));\n }\n\n debug(\"not exporting span\", spanId, \"as we don't care about it\");\n } finally {\n this.cleanupSpan(span as unknown as Span);\n }\n }\n\n /**\n * An implementation of the `forceFlush` method from the `SpanProcessor`\n * interface. This is called to force the processor to flush any spans that\n * are currently in the batcher. This is used to ensure that spans are\n * exported to the Inngest endpoint before the process exits.\n *\n * Notably, we call this in the `beforeResponse` middleware hook to ensure\n * that spans for a run as exported as soon as possible and before the\n * serverless process is killed.\n */\n async forceFlush(): Promise<void> {\n const flushDebug = processorDebug.extend(\"forceFlush\");\n flushDebug(\"force flushing batcher\");\n\n return this.#batcher\n ?.then((batcher) => batcher.forceFlush())\n .catch((err) => {\n flushDebug(\"error flushing batcher\", err, \"ignoring\");\n });\n }\n\n async shutdown(): Promise<void> {\n processorDebug.extend(\"shutdown\")(\"shutting down batcher\");\n\n return this.#batcher?.then((batcher) => batcher.shutdown());\n }\n}\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\nexport class PublicInngestSpanProcessor extends InngestSpanProcessor {\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n */\n app: Inngest.Like,\n ) {\n super(app);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"processor.js","names":["Debug","_resourceAttributes: Resource | undefined","#traceParents","appId: string | undefined","functionId: string | undefined","traceRef: string | undefined","#batcher","url: URL","#spanCleanup","#spansToExport","debug"],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":["import type { Span } from \"@opentelemetry/api\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport {\n detectResources,\n envDetector,\n hostDetector,\n osDetector,\n processDetector,\n type Resource,\n serviceInstanceIdDetector,\n} from \"@opentelemetry/resources\";\nimport {\n BatchSpanProcessor,\n type ReadableSpan,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace-base\";\nimport Debug from \"debug\";\nimport {\n defaultDevServerHost,\n defaultInngestApiBaseUrl,\n} from \"../../../helpers/consts.ts\";\nimport { devServerAvailable } from \"../../../helpers/devserver.ts\";\nimport { devServerHost } from \"../../../helpers/env.ts\";\nimport type { Inngest } from \"../../Inngest.ts\";\nimport { getAsyncCtx } from \"../als.ts\";\nimport { clientProcessorMap } from \"./access.ts\";\nimport { Attribute, debugPrefix, TraceStateKey } from \"./consts.ts\";\n\nconst processorDebug = Debug(`${debugPrefix}:InngestSpanProcessor`);\n\n/**\n * A set of resource attributes that are used to identify the Inngest app and\n * the function that is being executed. This is used to store the resource\n * attributes for the spans that are exported to the Inngest endpoint, and cache\n * them for later use.\n */\nlet _resourceAttributes: Resource | undefined;\n\n/**\n * A set of information about an execution that's used to set attributes on\n * userland spans sent to Inngest for proper indexing.\n */\nexport type ParentState = {\n traceparent: string;\n runId: string;\n appId: string | undefined;\n functionId: string | undefined;\n traceRef: string | undefined;\n};\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n *\n * THIS IS THE INTERNAL IMPLEMENTATION OF THE SPAN PROCESSOR AND SHOULD NOT BE\n * USED BY USERS DIRECTLY. USE THE {@link PublicInngestSpanProcessor} CLASS\n * INSTEAD.\n */\nexport class InngestSpanProcessor implements SpanProcessor {\n /**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n *\n * It is optional here as this is the private constructor and only used\n * internally; we set `app` elsewhere as when we create the processor (as\n * early as possible when the process starts) we don't necessarily have the\n * app available yet.\n *\n * So, internally we can delay setting ths until later.\n */\n app?: Inngest.Like,\n ) {\n if (app) {\n clientProcessorMap.set(app as Inngest.Any, this);\n }\n }\n\n /**\n * A `BatchSpanProcessor` that is used to export spans to the Inngest\n * endpoint. This is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n */\n #batcher: Promise<BatchSpanProcessor> | undefined;\n\n /**\n * A set of spans used to track spans that we care about, so that we can\n * export them to the OTel endpoint.\n *\n * If a span falls out of reference, it will be removed from this set as we'll\n * never get a chance to export it or remove it anyway.\n */\n #spansToExport = new WeakSet<Span>();\n\n /**\n * A map of span IDs to their parent state, which includes a block of\n * information that can be used and pushed back to the Inngest endpoint to\n * ingest spans.\n */\n #traceParents = new Map<string, ParentState>();\n\n /**\n * A registry used to clean up items from the `traceParents` map when spans\n * fall out of reference. This is used to avoid memory leaks in the case where\n * a span is not exported, remains unended, and is left in memory before being\n * GC'd.\n */\n #spanCleanup = new FinalizationRegistry<string>((spanId) => {\n if (spanId) {\n this.#traceParents.delete(spanId);\n }\n });\n\n /**\n * In order to only capture a subset of spans, we need to declare the initial\n * span that we care about and then export its children.\n *\n * Call this method (ideally just before execution starts) with that initial\n * span to trigger capturing all following children as well as initialize the\n * batcher.\n */\n public declareStartingSpan({\n span,\n runId,\n traceparent,\n tracestate,\n }: {\n span: Span;\n runId: string;\n traceparent: string | undefined;\n tracestate: string | undefined;\n }): void {\n // Upsert the batcher ready for later. We do this here to bootstrap it with\n // the correct async context as soon as we can. As this method is only\n // called just before execution, we know we're all set up.\n //\n // Waiting to call this until we actually need the batcher would mean that\n // we might not have the correct async context set up, as we'd likely be in\n // some span lifecycle method that doesn't have the same chain of execution.\n void this.ensureBatcherInitialized();\n\n // If we don't have a traceparent, then we can't track this span. This is\n // likely a span that we don't care about, so we can ignore it.\n if (!traceparent) {\n return processorDebug(\n \"no traceparent found for span\",\n span.spanContext().spanId,\n \"so skipping it\",\n );\n }\n\n // We also attempt to use `tracestate`. The values we fetch from these\n // should be optional, as it's likely the Executor won't need us to parrot\n // them back in later versions.\n let appId: string | undefined;\n let functionId: string | undefined;\n let traceRef: string | undefined;\n\n if (tracestate) {\n try {\n const entries = Object.fromEntries(\n tracestate.split(\",\").map((kv) => kv.split(\"=\") as [string, string]),\n );\n\n appId = entries[TraceStateKey.AppId];\n functionId = entries[TraceStateKey.FunctionId];\n traceRef = entries[TraceStateKey.TraceRef];\n } catch (err) {\n processorDebug(\n \"failed to parse tracestate\",\n tracestate,\n \"so skipping it;\",\n err,\n );\n }\n }\n\n // This is a span that we care about, so let's make sure it and its\n // children are exported.\n processorDebug.extend(\"declareStartingSpan\")(\n \"declaring:\",\n span.spanContext().spanId,\n \"for traceparent\",\n traceparent,\n );\n\n // Set a load of attributes on this span so that we can nicely identify\n // runtime, paths, etc. Only this span will have these attributes.\n span.setAttributes(InngestSpanProcessor.resourceAttributes.attributes);\n\n this.trackSpan(\n {\n appId,\n functionId,\n runId,\n traceparent,\n traceRef,\n },\n span,\n );\n }\n\n /**\n * A getter for retrieving resource attributes for the current process. This\n * is used to set the resource attributes for the spans that are exported to\n * the Inngest endpoint, and cache them for later use.\n */\n static get resourceAttributes(): Resource {\n if (!_resourceAttributes) {\n _resourceAttributes = detectResources({\n detectors: [\n osDetector,\n envDetector,\n hostDetector,\n processDetector,\n serviceInstanceIdDetector,\n ],\n });\n }\n\n return _resourceAttributes;\n }\n\n /**\n * The batcher is a singleton that is used to export spans to the OTel\n * endpoint. It is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n *\n * The batcher is only referenced once we've found a span we're interested in,\n * so this should always have everything it needs on the app by then.\n */\n private ensureBatcherInitialized(): Promise<BatchSpanProcessor> {\n if (!this.#batcher) {\n this.#batcher = new Promise(async (resolve, reject) => {\n try {\n // We retrieve the app from the async context, so we must make sure\n // that this function is called from the correct chain.\n const store = await getAsyncCtx();\n if (!store) {\n throw new Error(\n \"No async context found; cannot create batcher to export traces\",\n );\n }\n\n const app = store.app as Inngest.Any;\n\n // Fetch the URL for the Inngest endpoint using the app's config.\n let url: URL;\n const path = \"/v1/traces/userland\";\n if (app.apiBaseUrl) {\n url = new URL(path, app.apiBaseUrl);\n } else {\n url = new URL(path, defaultInngestApiBaseUrl);\n\n if (app[\"mode\"] && app[\"mode\"].isDev && app[\"mode\"].isInferred) {\n const devHost = devServerHost() || defaultDevServerHost;\n const hasDevServer = await devServerAvailable(\n devHost,\n app[\"fetch\"],\n );\n if (hasDevServer) {\n url = new URL(path, devHost);\n }\n } else if (app[\"mode\"]?.explicitDevUrl) {\n url = new URL(path, app[\"mode\"].explicitDevUrl.href);\n }\n }\n\n processorDebug(\n \"batcher lazily accessed; creating new batcher with URL\",\n url,\n );\n\n const exporter = new OTLPTraceExporter({\n url: url.href,\n\n headers: {\n ...app[\"headers\"],\n Authorization: `Bearer ${app[\"inngestApi\"][\"signingKey\"]}`,\n },\n });\n\n resolve(new BatchSpanProcessor(exporter));\n } catch (err) {\n reject(err);\n }\n });\n }\n\n return this.#batcher;\n }\n\n /**\n * Mark a span as being tracked by this processor, meaning it will be exported\n * to the Inggest endpoint when it ends.\n */\n private trackSpan(parentState: ParentState, span: Span): void {\n const spanId = span.spanContext().spanId;\n\n this.#spanCleanup.register(span, spanId, span);\n this.#spansToExport.add(span);\n this.#traceParents.set(spanId, parentState);\n\n span.setAttribute(Attribute.InngestTraceparent, parentState.traceparent);\n span.setAttribute(Attribute.InngestRunId, parentState.runId);\n\n // Setting app ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.appId) {\n span.setAttribute(Attribute.InngestAppId1, parentState.appId);\n span.setAttribute(Attribute.InngestAppId2, parentState.appId);\n }\n\n // Setting function ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.functionId) {\n span.setAttribute(Attribute.InngestFunctionId, parentState.functionId);\n }\n\n if (parentState.traceRef) {\n span.setAttribute(Attribute.InngestTraceRef, parentState.traceRef);\n }\n }\n\n /**\n * Clean up any references to a span that has ended. This is used to avoid\n * memory leaks in the case where a span is not exported, remains unended, and\n * is left in memory before being GC'd.\n */\n private cleanupSpan(span: Span): void {\n const spanId = span.spanContext().spanId;\n\n // This span is no longer in use, so we can remove it from the cleanup\n // registry.\n this.#spanCleanup.unregister(span);\n this.#spansToExport.delete(span);\n this.#traceParents.delete(spanId);\n }\n\n /**\n * An implementation of the `onStart` method from the `SpanProcessor`\n * interface. This is called when a span is started, and is used to track\n * spans that are children of spans we care about.\n */\n onStart(span: Span): void {\n const debug = processorDebug.extend(\"onStart\");\n const spanId = span.spanContext().spanId;\n // 🤫 It seems to work\n const parentSpanId = (span as unknown as ReadableSpan).parentSpanContext\n ?.spanId;\n\n // The root span isn't captured here, but we can capture children of it\n // here.\n\n if (!parentSpanId) {\n // All spans that Inngest cares about will have a parent, so ignore this\n debug(\"no parent span ID for\", spanId, \"so skipping it\");\n\n return;\n }\n\n const parentState = this.#traceParents.get(parentSpanId);\n if (parentState) {\n // This span is a child of a span we care about, so add it to the list of\n // tracked spans so that we also capture its children\n debug(\n \"found traceparent\",\n parentState,\n \"in span ID\",\n parentSpanId,\n \"so adding\",\n spanId,\n );\n\n this.trackSpan(parentState, span);\n }\n }\n\n /**\n * An implementation of the `onEnd` method from the `SpanProcessor` interface.\n * This is called when a span ends, and is used to export spans to the Inngest\n * endpoint.\n */\n onEnd(span: ReadableSpan): void {\n const debug = processorDebug.extend(\"onEnd\");\n const spanId = span.spanContext().spanId;\n\n try {\n if (this.#spansToExport.has(span as unknown as Span)) {\n if (!this.#batcher) {\n return debug(\n \"batcher not initialized, so failed exporting span\",\n spanId,\n );\n }\n\n debug(\"exporting span\", spanId);\n return void this.#batcher.then((batcher) => batcher.onEnd(span));\n }\n\n debug(\"not exporting span\", spanId, \"as we don't care about it\");\n } finally {\n this.cleanupSpan(span as unknown as Span);\n }\n }\n\n /**\n * An implementation of the `forceFlush` method from the `SpanProcessor`\n * interface. This is called to force the processor to flush any spans that\n * are currently in the batcher. This is used to ensure that spans are\n * exported to the Inngest endpoint before the process exits.\n *\n * Notably, we call this in the `beforeResponse` middleware hook to ensure\n * that spans for a run as exported as soon as possible and before the\n * serverless process is killed.\n */\n async forceFlush(): Promise<void> {\n const flushDebug = processorDebug.extend(\"forceFlush\");\n flushDebug(\"force flushing batcher\");\n\n return this.#batcher\n ?.then((batcher) => batcher.forceFlush())\n .catch((err) => {\n flushDebug(\"error flushing batcher\", err, \"ignoring\");\n });\n }\n\n async shutdown(): Promise<void> {\n processorDebug.extend(\"shutdown\")(\"shutting down batcher\");\n\n return this.#batcher?.then((batcher) => batcher.shutdown());\n }\n}\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\nexport class PublicInngestSpanProcessor extends InngestSpanProcessor {\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n */\n app: Inngest.Like,\n ) {\n super(app);\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inngest",
3
- "version": "3.48.0",
3
+ "version": "3.48.1",
4
4
  "description": "Official SDK for Inngest.com. Inngest is the reliability layer for modern applications. Inngest combines durable execution, events, and queues into a zero-infra platform with built-in observability.",
5
5
  "main": "./index.cjs",
6
6
  "module": "./index.js",
@@ -24,8 +24,7 @@
24
24
  "lint": "biome check",
25
25
  "lint:fix": "biome check --fix",
26
26
  "postversion": "pnpm run build",
27
- "release": "pnpm run test && pnpm run build && cross-env DIST_DIR=dist node ../../scripts/release/publish.js && pnpm dlx jsr publish --allow-slow-types --allow-dirty",
28
- "release:version": "node ../../scripts/release/jsrVersion.js",
27
+ "release": "pnpm run test && pnpm run build && cross-env DIST_DIR=dist node ../../scripts/release/publish.js",
29
28
  "dev": "pnpm install && concurrently --names Build,Lint --prefix-colors \"green.inverse,magenta.inverse\" --handle-input \"pnpm run dev:build\" \"pnpm run dev:lint\"",
30
29
  "dev:build": "nodemon -w src -e ts -i version.ts --delay 300ms -x 'pnpm run build'",
31
30
  "dev:lint": "nodemon -w src -e ts -i version.ts --delay 300ms -x 'pnpm run lint'",
package/version.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  //#region src/version.ts
3
- const version = "3.48.0";
3
+ const version = "3.48.1";
4
4
 
5
5
  //#endregion
6
6
  exports.version = version;
package/version.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"version.cjs","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Generated by genversion.\nexport const version = \"3.48.0\";\n"],"mappings":";;AACA,MAAa,UAAU"}
1
+ {"version":3,"file":"version.cjs","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Generated by genversion.\nexport const version = \"3.48.1\";\n"],"mappings":";;AACA,MAAa,UAAU"}
package/version.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/version.d.ts
2
- declare const version = "3.48.0";
2
+ declare const version = "3.48.1";
3
3
  //#endregion
4
4
  export { version };
5
5
  //# sourceMappingURL=version.d.cts.map
package/version.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/version.d.ts
2
- declare const version = "3.48.0";
2
+ declare const version = "3.48.1";
3
3
  //#endregion
4
4
  export { version };
5
5
  //# sourceMappingURL=version.d.ts.map
package/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/version.ts
2
- const version = "3.48.0";
2
+ const version = "3.48.1";
3
3
 
4
4
  //#endregion
5
5
  export { version };
package/version.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Generated by genversion.\nexport const version = \"3.48.0\";\n"],"mappings":";AACA,MAAa,UAAU"}
1
+ {"version":3,"file":"version.js","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Generated by genversion.\nexport const version = \"3.48.1\";\n"],"mappings":";AACA,MAAa,UAAU"}