Coder Social home page Coder Social logo

evanderkoogh / otel-cf-workers Goto Github PK

View Code? Open in Web Editor NEW
187.0 8.0 36.0 353 KB

An OpenTelemetry compatible library for instrumenting and exporting traces for Cloudflare Workers

License: BSD 3-Clause "New" or "Revised" License

TypeScript 100.00%
cloudflare observability otel workers

otel-cf-workers's People

Contributors

ankcorn avatar cometkim avatar danifoldi avatar evanderkoogh avatar github-actions[bot] avatar hansottowirtz avatar jahands avatar lboynton avatar plantfansam avatar rdooley avatar rtbenfield avatar schniz avatar willie avatar yacinehmito avatar yauhenchakhlou avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

otel-cf-workers's Issues

for wrangler 3.7, the trace API call is not working

the trace API is not called on the fetch
==> is not returning success or failure, and it seem like the fetch is not called at all.

  ==>     BTW, if make the same request via POSTMAN, it works.  (with the same body)

image

[Feature request] Support for websocket (and hibernation API)

After investigating more #14 (comment), it looks like this module doesn't support yet Websockets and using the DO storage in a websocket handler throws the error:

Cannot read properties of undefined (reading 'sampling') 

Probably because it's not wrapped in the async context.

It'd be great if this module could support the Websocket API with event handlers but also the new Hibernation API.

Bug when trying to access undefined env vars

First, thanks for the library!

Now, one issue I've found is that because it wraps env, I can no longer try to access env vars that haven't been set. If I do I get the following error:

Cannot read properties of undefined (reading 'getWithMetadata')

This is coming from this line. This should be quite straight-forward to fix simply by returning false if it's undefined. I'll raise a PR if I get some time.

Support for custom propagators?

Hi! I am interested in first-classing support for custom propagators. As I read it, you cannot specify this in the config, as the library hard-codes a w3c propagator here. A couple questions, then:

  • Am I right that there's no way to explicitly configure this in the library?
  • If I'm right, would you be open to a patch that adds support? I'd be happy to contribute.

CF browser rendering breaks when using instrumentDO

I have a Durable Object in which I run Cloudflare's browser rendering beta. When wrapping the DO with instrumentDO the call to puppeteer.launch(this.env.BROWSER) crashes with the following error:

TypeError: Invalid URL string.
    at Object.apply (file:///private/var/folders/7y/mzdgqpln5w58j8cb5zf09nn80000gn/T/tmp-35961-0Gm7slF7r3UZ/worker.js:18343:20)
    at proxyHandler.apply (file:///private/var/folders/7y/mzdgqpln5w58j8cb5zf09nn80000gn/T/tmp-35961-0Gm7slF7r3UZ/worker.js:16921:22)
    at PuppeteerWorkers.launch (file:///private/var/folders/7y/mzdgqpln5w58j8cb5zf09nn80000gn/T/tmp-35961-0Gm7slF7r3UZ/worker.js:13744:32)

I managed to create a very hacky solution by patching this package in the following way:

node_modules/@microlabs/otel-cf-workers/dist/esm/wrap.js

export function wrap(item, handler, autoPassthrough = true) {
    if (isWrapped(item) || !isProxyable(item)) {
        return item;
    }
    const proxyHandler = Object.assign({}, handler);
    proxyHandler.get = (target, prop, receiver) => {
+	if (prop ==='BROWSER') return target.BROWSER
        if (prop === unwrapSymbol) {
            return item;
        }

This works for me for now, but I suspect there is a much better way to solve this in a first hand way.

faas.execution semantic attribute with CF-Ray

Would you be interested in incorporating the CF-Ray header from Cloudflare into the span attributes of fetchHandler? The semantic attributes package offers faas.execution, which seems fitting for this and is what I have used previously. The JSDoc describes the attribute as "The execution ID of the current function execution.".

It's not difficult to add this in userland either, but it's been so successful for correlation with LogPush jobs that I thought incorporating it by default might help others 🙂

const attributes = {
	[SemanticAttributes.FAAS_TRIGGER]: 'http',
	[SemanticAttributes.FAAS_COLDSTART]: cold_start,
+ 	[SemanticAttributes.FAAS_EXECUTION]: request.headers.get('cf-ray') ?? undefined,
}

I'm happy to raise a PR for this if it would be fitting for the package.

KV instrumentation improvements

Hi 👋,

I've noticed some small inconsistencies with the KV instrumentation; all but get and getWithMetadata contain a kv. prefix for all attributes, and they are missing here:

get(argArray) {
const attrs: Attributes = {
'kv.key': argArray[0],
}
const opts = argArray[1]
if (typeof opts === 'string') {
attrs['type'] = opts
} else if (typeof opts === 'object') {
attrs['type'] = opts.type
attrs['cacheTtl'] = opts.cacheTtl
}
return attrs
},
getWithMetadata(argArray, result) {
const attrs = this.get(argArray, result)
attrs['withMetadata'] = true
return attrs
},

Additionally, list and getWithMetadata now return a cache status (WIP docs: https://maddy-make-kv-product-tile.cloudflare-docs-7ou.pages.dev/kv/platform/observability/, types: https://workers-types.pages.dev/#KVNamespaceListResult.cacheStatus ). It could be nice to replace all calls to get with getWithMetadata, return only the value of get was requested, but keep the cache attribute for telemetry.

@changesets/cli should be dev dependency

Hi, currently updating from rc9 to rc10 adds a whole load of new dependencies. As I understand it, @changesets/cli is only needed to create releases of this package so should not be needed for consumers of the package.

[Bug] Miniflare 3 Uncaught (async) RangeError: Maximum call stack size exceeded

Minimal reproduction repository - https://github.com/AdiRishi/worker-wrangler3-otel-test

In order to produce the error, hit the / (root route).

Error - Uncaught (async) RangeError: Maximum call stack size exceeded

[mf:inf] Ready on http://127.0.0.1:8787/
[mf:inf] GET / 200 OK (18ms)
✘ [ERROR] Uncaught (in promise) RangeError: Maximum call stack size exceeded

  private _getContextManager(): ContextManager {
  ^
      at ContextAPI2._getContextManager
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@opentelemetry/api/src/api/context.ts:90:2)
      at ContextAPI2.active
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@opentelemetry/api/src/api/context.ts:60:16)
      at getActiveConfig
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/config.ts:117:24)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:133:24)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)
      at checkedFetch
  (/private/var/folders/__/f61lsp8x76551yjyz09hv0800000gp/T/tmp-40750-tWTIkkwORzHD/checked-fetch.js:22:19)
      at apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:19)
      at proxyHandler.apply
  (/Users/arishi/playground/cloudflare/worker-otel/node_modules/@microlabs/otel-cf-workers/src/instrumentation/common.ts:25:18)


✘ [ERROR] Uncaught (async) RangeError: Maximum call stack size exceeded

[Bug] Wrangler 2 TypeError: defaults?.fetch?.bind is not a function

Minimal recreation repository - https://github.com/AdiRishi/worker-wrangler2-otel-test

Steps to recreate

  1. Clone the repository
  2. Run yarn install
  3. Run yarn dev , the error should be visible in the console

Package Versions

  • wrangler 2.20.0
  • miniflare 2.13.0

Error

[mf:err] TypeError: defaults?.fetch?.bind is not a function
    at Miniflare.#reload (/Users/arishi/playground/cloudflare/worker-wrangler2-otel-test/node_modules/@miniflare/core/src/index.ts:810:48)
    at Miniflare.getPlugins (/Users/arishi/playground/cloudflare/worker-wrangler2-otel-test/node_modules/@miniflare/core/src/index.ts:1033:5)
    at createServer (/Users/arishi/playground/cloudflare/worker-wrangler2-otel-test/node_modules/@miniflare/http-server/src/index.ts:362:19)
    at startServer (/Users/arishi/playground/cloudflare/worker-wrangler2-otel-test/node_modules/@miniflare/http-server/src/index.ts:469:18)
    at main (file:///Users/arishi/playground/cloudflare/worker-wrangler2-otel-test/node_modules/wrangler/miniflare-dist/index.mjs:6374:22)
    at file:///Users/arishi/playground/cloudflare/worker-wrangler2-otel-test/node_modules/wrangler/miniflare-dist/index.mjs:6442:1

includeTraceContext is always set to true despite override

It seems that despite overriding fetch.includeTraceContext in the config function, the traceparent header is always set on outgoing fetch calls.

I tracked this down to this line in parseConfig that uses || true rather than ?? true to coalesce the value. It also appears that retrieving this value here in instrumentFetcher does not invoke the function, resulting in the value always being truthy for function use cases.

I'm happy to raise a PR to address these two spots if you're open to contributions 🙂

Thanks for publishing this library. The automatic instrumentation of Cloudflare bindings is well done 🥇

option to skip context propagation for incoming requests

Description

We have a Worker that receives HTTP requests from our users' code which may be instrumented with their own OpenTelemetry tracing. In this scenario, we will receive the W3C Trace Context headers with traces that we do not own. It would be great if we could opt-out of the inbound context propagation that done here in executeFetchHandler. We can currently opt-out of the outbound fetch propagation with includeTraceContext, but not inbound.

Workarounds

This could be worked around by adding another fetch around the instrument(handler, config) that deletes incoming trace headers before their reach the instrumentation. This is a bit unintuitive though.

Proposal

I could envision this being a similar API surface to includeTraceContext that would allow for using a boolean or function that returns a boolean. That way it could be based on particular characteristics of the incoming request. For example, a Worker may be receiving requests from other internal services and from external services and may propagate context from internal services only.

I am happy to write a bit more about this idea or raise a PR. I wanted to first check if this is addressed in other ways or if it is something that would be a good addition to the configuration options.

[Feature Request] Support multiple exporter targets

Motivation

When evaluating different monitoring and tracing products in the market it is very useful to be able to be able to send the metrics to multiple different sources without major code changes.

Currently I have to pick and choose which workers send traces to which destination. In an ideal world, we could just send the same traces to multiple targets.

Config proposal

This might be a good way to expose the new setting. Accept an array of exporter targets in the config function.

Potential config structure

const config: ResolveConfigFn = (env: Env, _trigger) => {
    return {
        exporter: [
            {
                url: 'https://api.honeycomb.io/v1/traces',
                headers: { 'x-honeycomb-team': env.HONEYCOMB_API_KEY },
            },
            {
                url: 'https://api.axiom.co',
                headers: { authorization: env.AXIOM_API_KEY, 'x-axiom-dataset': env.AXIOM_DATASET },
            }
        ],
        service: { name: 'greetings' },
    }
}

Performance considerations

If my understanding of how this library works is correct, this shouldn't impact performance significantly? The requests to the telemetry targets are done in ctx.waitUntil so they wouldn't block the main request from returning.

Types are not properly exposed

I just attempted to use this package with Deno, using esm.sh to get it from npm, and the types were not available.

I ran diagnostics from arethetypeswrong and here are the results:

  "@microlabs/otel-cf-workers"
node10
node16 (from CJS) 👺 Masquerading as ESM / ⚠️ ESM (dynamic import only) / 🥴 Internal resolution error
node16 (from ESM) 🥴 Internal resolution error
bundler

👺 Masquerading as ESM

Import resolved to an ESM type declaration file, but a CommonJS JavaScript file.

⚠️ ESM (dynamic import only)

A require call resolved to an ESM JavaScript file, which is an error in Node and some bundlers. CommonJS consumers will need to use a dynamic import.

🥴 Internal resolution error

Import found in a type declaration file failed to resolve. Either this indicates that runtime resolution errors will occur, or (more likely) the types misrepresent the contents of the JavaScript files.

Error loading `ts-checked-fsm` when using vitest and miniflare

Testing an app using vitest with environment: 'miniflare' getting the following error from the ts-checked-fsm dependency

SyntaxError: Named export 'stateMachine' not found. The requested module 'ts-checked-fsm' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'ts-checked-fsm';
const { stateMachine } = pkg;

[Feature Request] install it conditionally

At the moment, it looks like it's impossible to conditionally instrument the worker (if a config prop is set), it makes it hard to disable it during tests with miniflare (also not sure it works with miniflare?)

Missing spans

Reproduction: https://github.com/mattfysh/worker_do_otel

Looking into an issue with spans not appearing in honeycomb

The first is 100% reproducible, where if you make any number of followup request from Worker A to Worker B, only the spans from the initial call to Worker B appear. In this instance, honeycomb does not display the "Missing spans" warning.

image

The second is intermittent but highly-reproducible, where some spans from Worker B may appear as missing. In this instance, honeycomb displays the "Missing spans" warning.

You should be able to reproduce by deploying the linked repo, but let me know if you run into any issues or are unable to see the issue. I've also listed some smaller tangential issues in the repo readme.

fetchHandler span does not follow OTEL conventions?

This came up in a review when I showed someone who is more knowledgeable than me on this subject a project using this library. Wondered what your thoughts were.

The Open Telemetry convention for HTTP spans says the following:

HTTP spans MUST follow the overall guidelines for span names. HTTP server span names SHOULD be {http.request.method} {http.route} if there is a (low-cardinality) http.route available. HTTP server span names SHOULD be {http.method} if there is no (low-cardinality) http.route available. HTTP client spans have no http.route attribute since client-side instrumentation is not generally aware of the "route", and therefore HTTP client spans SHOULD use {http.method}. Instrumentation MUST NOT default to using URI path as span name, but MAY provide hooks to allow custom logic to override the default span name.

Currently the library sets the span name to fetchHandler, whereas the convention suggests it should be the HTTP method as it's an HTTP client. It's easy to change this with a post processor function but do you think the library should follow these conventions?

Make it work with Miniflare 2.14.0

Because of how miniflare handles the default export from modules the Proxy returned by wrap.ts is passing through the bind call. And that makes the proxy be bypassed by miniflare.

https://github.com/cloudflare/miniflare/blob/7e4d906e19cc69cd3446512bfeb7f8aee3a2bda7/packages/core/src/index.ts#L813-L814

Fixed this in a fork adding a case for 'bind' here

proxyHandler.get = (target, prop, receiver) => {
if (prop === unwrapSymbol) {
	  return item
  } else if(prop === 'bind') {
	  return () => receiver
  } else {
	  if (handler.get) {
		  return handler.get(target, prop, receiver)
	  } else if (autoPassthrough) {
		  return passthroughGet(target, prop)
	  }
  }
}

As I am not sure if that is the proper solution to the problem I will not submit a PR yet.

Error when instrumenting a worker using Launch Darkly's edge SDK

I'm using Launch Darkly's edge SDK in a Cloudflare worker. When I add instrumentation to the app I see an error triggered when fetching a Launch Darkly flag (which is stored in a KV store).

{"name":"TypeError","message":"Cannot read properties of undefined (reading 'Symbol(unwrap)')","stack":"TypeError: Cannot read properties of undefined (reading 'Symbol(unwrap)')\n    at isWrapped (worker.js:15817:16)\n    at wrap (worker.js:15820:7)\n    at instrumentKVFn (worker.js:16563:10)\n    at Object.get (worker.js:16570:14)\n    at proxyHandler.get (worker.js:15829:25)\n    at JSON.stringify (<anonymous>)\n    at createOptions (worker.js:13348:105)\n    at new LDClient (worker.js:13358:28)\n    at init (worker.js:13399:10)\n    at init2 (worker.js:13432:10)"}

Here's a minimal repository that reproduces the issue. Follow the readme and you should be able to reproduce the issue. Thanks!

RemixJS compatibility issues

I see an error that looks like

service core:user:remix-cloudflare-workers: Uncaught ReferenceError: Buffer is not defined

when I add instrumentation to a Remix app. I've created a minimal example to reproduce. I see this error whether or not I use the node_compat flag in wrangler.toml. Any help would be appreciated.

TypeError in tracer.ts when getActiveConfig() returns undefined

I have not attempted a simple repro so I don't know the root cause of this, but this error occurs in my worker reliably:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'sampling')                                                                                                                               
                                                                                                                                                                                                                                  
  const sampler = getActiveConfig().sampling.headSampler                                                                                                                                                                          
                                    ^
      at startSpan (src/tracer.ts:47:36)
      at startActiveSpan (src/tracer.ts:88:20)
      at apply (../src/instrumentation/do-storage.ts:72:17)
      at proxyHandler.apply (../src/instrumentation/wrap.ts:27:18)
      at  (C:\Users\palp\AppData\Local\Temp\tmp-35572-Q5UGGZxJVrjs/src/billing.ts:81:39)

I was able to resolve it by modifying getActiveConfig to return a default value instead of undefined, but this may or may not be appropriate/desired behavior.
main...palp:otel-cf-workers:main

cannot get this working with New Relic

I've been unable to get this working with New Relic. This is my config.

const config: ResolveConfigFn = (env: Env, _trigger) => {
    return {
        exporter: {
            // new relic
            url: 'https://otlp.nr-data.net:4318/v1/traces',
            headers: { 'api-key': env.NR_API_KEY },
        },
        service: { name: env.NR_SERVICE_NAME },
    }
}

and this is the error:

[mf:inf] Updated and ready on http://127.0.0.1:8787/
WARNING: known issue with `fetch()` requests to custom HTTPS ports in published Workers:
 - https://otlp.nr-data.net:4318/ - the custom port will be ignored when the Worker is published using the `wrangler deploy` command.

[mf:inf] GET / 200 OK (20ms)
Error sending spans to exporter: OTLPExporterError: Exception during export: Error: Network connection lost.
    at new OTLPExporterError2 (worker.js:2746:24)
    at worker.js:2845:15 {
  name: OTLPExporterError,
  data: Error: Network connection lost.,
  code: undefined,
  stack: OTLPExporterError: Exception during export: Error:…ror2 (worker.js:2746:24)
    at worker.js:2845:15,
  message: Exception during export: Error: Network connection lost.
}

I have the .dev.vars file with the secret set. I also tried set the value directly in code. Same error. I get the same error with no api-key header or complete gibberish as an api-key header value.

This configuration, which is similar, works fine with Jaeger and SigNoz running on localhost.

const config: ResolveConfigFn = (env: Env, _trigger) => {
    return {
        exporter: {
            url: 'http://localhost:4318/v1/traces',
        },
        service: { name: env.NR_SERVICE_NAME },
    }
}

I've updated the issue here from our discussion from discord. https://discord.com/channels/595317990191398933/1093094892080738394/1139831369107767406

Service worker syntax

More of a question than an issue, does it work with service worker syntax?

addEventListener('fetch', event => {
  event.respondWith(new Response('Hello'));
});

If so, could there be an example on how it should be implemented?

HTTP span name isn’t compliant with the OTel spec

          Just documenting the `HTTP_ROUTE` and span name behavior from upstream
  • they pull the route off the rpcMetadata here
  • and set the span name based on this (if defined) here
  • and here is a route they set during the test which is checked here

Gonna revert the route/span name stuff for now in the interest of having a cleaner PR here, but just wanted to document this somewhere with some links for a convenient reference point.

Originally posted by @rdooley in #53 (comment)

Missing passThroughOnException on ExecutionContext

The ctx argument passed to fetch is missing passThroughOnException

When I add this logging inside the instrumented fetch handler (e.g. here or here):

console.log('handler.fetch ctx', ctx, 'waitUntil?', ctx.waitUntil, 'passThroughOnException?', ctx.passThroughOnException)

I see

handler.fetch ctx Proxy(ExecutionContext) waitUntil? Proxy(Function) passThroughOnException? undefined

I also didn't see any references to passThroughOnException in this repo. Perhaps it's intentional, but I believe it's expected/required.

Docs on Using BatchTraceSpanProcessor?

I am a little concerned that #43 and this follow-on commit may have broken things for users, but I'm also hopeful that some docs might clear things up. Wanted to surface this in case any other users encounter the same issue.

Here's the state of affairs: #43 and the follow-on commit added the ability to specify 1+ span processors for use by the SDK. When I try to pass the BatchTraceSpanProcessor in my config resolution function like so:

export const ResolveTraceConfigFn: ResolveConfigFn = (env: Env, _trigger) => {
	return {
		exporter: new ConsoleSpanExporter,
		service: {...},
		spanProcessors: [new MyCoolSpanProcessor(), new BatchTraceSpanProcessor()],
	}
}

I see the following when run my code in wrangler:

service core:user:example: Uncaught Error: Dynamic require of "node:buffer" is not supported
  at index.js:12:9
  at index.js:3965:25 in ../otel-cf-workers-example/node_modules/@microlabs/otel-cf-workers/dist/cjs/buffer.js
  at index.js:18:50 in __require2
  at index.js:14350:18 in ../otel-cf-workers-example/node_modules/@microlabs/otel-cf-workers/dist/cjs/index.js
  at index.js:18:50 in __require2
  at index.js:14369:29 in ../otel-cf-workers-example/dist/ResolveConfig.js
  at index.js:18:50 in __require2
  at index.js:14428:18 in ../otel-cf-workers-example/dist/index.js
  at index.js:18:50 in __require2

I believe the error stems from this open workerd issue, which suggests that you must import NodeJS runtime APIs, rather than require them. If that's the case, then applications using this library would need to use the esm dist directory rather than the cjs one, since the cjs export includes the line const node_buffer_1 = require("node:buffer"); (whereas the esm dist directory uses import { Buffer } from 'node:buffer';).

This does not happen in 1.0.0-rc.7, where we used to instantiate the BatchTraceSpanProcessor within this library itself.

Side note: is it possible to add a comment about why we're importing Buffer from node:buffer here and adding it to the globalThis?

I'll update this issue with my findings!

Browser Rendering API Breaks When Instrumenting

TypeError: Invalid URL string. at Object.apply (worker.js:7500:20) at proxyHandler.apply (worker.js:6232:22) at PuppeteerWorkers.launch (worker.js:21848:32) at sendLiveNotifications (worker.js:21866:48) at scheduled (worker.js:21965:15) at worker.js:7619:13 at AsyncLocalStorageContextManager.with (worker.js:6467:36) at ContextAPI2.with (worker.js:3730:53) at WorkerTracer.startActiveSpan (worker.js:6686:24) at executeScheduledHandler (worker.js:7615:27)

The API is in beta, but it does break and when I remove the instrument line, it works, so I assume there's something funky going on with the Otel library and they aren't playing nice together.

DurableObjectStorage list with no args throws runtime error

Description

When using an instrumented Durable Object, calling storage.list() without supplying any arguments will throw TypeError: Cannot set properties of undefined (setting 'do.storage.number_of_results').

This is caused by the instrumentation of DurableObjectStorage attempting to mutate the first argument, which does not exist in this case.

Workaround

The workaround for this is simply to pass an empty object like storage.list({}).

Split up README into seperate docs

Right now especially the configuration section explains a lot of how Open Telemetry works to explain what to configure and how.

This can all be put into a separate doc that we can refer to, so we can keep the config section clean.

New service bindings support triggers errors when service bindings not in use

Version: 1.0.0-rc.13

I am not using service bindings, and get this error with the latest rc.13.

TypeError: Cannot read properties of undefined (reading 'connect')
    at isServiceBinding (index.js:5800:20)
    at Object.get (index.js:5812:18)
    at proxyHandler.get (index.js:4763:25)
    at Object.fetch (index.js:6300:78)
    at fetch (index.js:6222:25)
    at index.js:5902:30
    at AsyncLocalStorageContextManager.with (index.js:5008:36)
    at ContextAPI2.with (index.js:2194:53)
    at WorkerTracer.startActiveSpan (index.js:5225:24)
    at executeFetchHandler (index.js:5900:27) {
  stack: TypeError: Cannot read properties of undefined (re…24)
    at executeFetchHandler (index.js:5900:27),
  message: Cannot read properties of undefined (reading 'connect')

`TypeError: Illegal invocation` when intrumenting calls to CF cache

When using Cloudflare's kv-asset-handler, there are instances where the auto-instrumentation results in Illegal invocation errors, causing the request to be cancelled in the CF Workers environment. More specifically, when setting the bypassCache: false flag in the params of the getAssetFromKV() call is when this can be reproduced consistently when there are multiple items in cache.

Repro branch - URL pointing to the file with the interesting bits: https://github.com/proofzero/rollupid/blob/spike/otel-cf-workers-repro/apps/passport/server.ts

Steps to run locally:

  1. Go to /apps/passport
  2. Rename .dev.vars.example to .dev.vars (no need to populate with values)
  3. yarn && yarn start

No issues locally; when workers is deployed to CF and hard-refreshed in the browser a few times (likely to cause some cache hits/misses), you'll see TypeError: Illegal invocation logs in wrangler tail.

Pages function support

Reading through the docs and issues I don't find any mention of Cloudflare Pages. Would it be possible to use this library for functions?

We use Pages instead of Workers at my job because of simplicity and automatic branch previews. I know that compiled pages are just a worker behind the scenes, so I'm wondering if I could somehow shoehorn it into my project.

I've been trying to use the official cloudflare pages plugin, but I'm not getting any logs or custom data through to Honeycomb so I started looking at alternatives.

ESM interoperability question

Hi!
I am really not very experienced in JS/TS, especially in its complicated module systems.

However, I'd like to bring one concern here. I have issues in using this library for my ESM JavaScript project.
When I try to run unit tests using Mocha, after importing the library I get a runtime error, saying it cannot resolve one of the dependencies:

> npx mocha

Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'xxx\node_modules\@microlabs\otel-cf-workers\dist\sampling' imported from xxx\node_modules\@microlabs\otel-cf-workers\dist\index.js        
    at new NodeError (node:internal/errors:393:5)
    at finalizeResolution (node:internal/modules/esm/resolve:323:11)
    at moduleResolve (node:internal/modules/esm/resolve:916:10)
    at defaultResolve (node:internal/modules/esm/resolve:1124:11)
    at nextResolve (node:internal/modules/esm/loader:163:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:841:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:76:40)
    at link (node:internal/modules/esm/module_job:75:36)

The reason is that ./dist has index.js which contains CommonJS-compatible imports (without the .js extention) but it is not compatible with ESM. Most probably, TypeScript does some magic resolving modules w/o extensions. However, if we look at the guide for TypeScript,
https://www.typescriptlang.org/docs/handbook/esm-node.html
it mentions that either one should use ESM-compatible syntax:

// ./bar.ts
import { helper } from "./foo.js"; // works in ESM & CJS
helper();

or have ESM & CommonJS separated by export index files at package.json:

...
"exports": {
        ".": {
            // Entry-point for `import "my-package"` in ESM
            "import": "./esm/index.js",
            // Entry-point for `require("my-package") in CJS
            "require": "./commonjs/index.cjs",
        },
    },
    // CJS fall-back for older versions of Node.js
    "main": "./commonjs/index.cjs",
...

Now, my question is, is it something which be introduced in this library?

I know that as a workaround, I can use some bundler and run my unit tests after building the code, but I guess my proposal may be a more "right" thing to do.

Apologize in advance, if this proposal contains some obvious errors or misunderstanding from my side.

Thanks for the great library!

'Fetcher is not defined' when accessing string environment variable in handler

Repro at https://github.com/etinquis/cf-otel.

Run with docker-compose up -d --build.
Hit the exposed port, result:
image

Log:

[mf:err] ReferenceError: Fetcher is not defined
2023-09-16 11:56:13     at isFetcher (/app/node_modules/@microlabs/otel-cf-workers/src/instrumentation/env.ts:21:25)
2023-09-16 11:56:13     at Object.get (/app/node_modules/@microlabs/otel-cf-workers/src/instrumentation/env.ts:34:15)
2023-09-16 11:56:13     at proxyHandler.get (/app/node_modules/@microlabs/otel-cf-workers/src/wrap.ts:23:20)
2023-09-16 11:56:13     at fetch (/app/src/index.ts:36:27)
2023-09-16 11:56:13     at null.<anonymous> (/app/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:137:37)
2023-09-16 11:56:13     at AsyncLocalStorageContextManager.with (/app/node_modules/@microlabs/otel-cf-workers/src/context.ts:241:34)
2023-09-16 11:56:13     at ContextAPI2.with (/app/node_modules/@opentelemetry/api/src/api/context.ts:77:42)
2023-09-16 11:56:13     at WorkerTracer.startActiveSpan (/app/node_modules/@microlabs/otel-cf-workers/src/tracer.ts:93:22)
2023-09-16 11:56:13     at executeFetchHandler (/app/node_modules/@microlabs/otel-cf-workers/src/instrumentation/fetch.ts:135:25)
2023-09-16 11:56:13     at AsyncLocalStorageContextManager.with (/app/node_modules/@microlabs/otel-cf-workers/src/context.ts:241:34)
[mf:inf] GET /favicon.ico 500 Internal Server Error (36ms)

Expected (uncommenting https://github.com/etinquis/cf-otel/blob/b3c3d698ab6a858243730823f1d181ad011ca6f6/src/index.ts#L51C36-L51C36):
image

Unable to use ConsoleSpanExporter

As briefly discussed on Discord, I was hoping to be able to conditionally use the ConsoleSpanExporter in local development and not send traces to an external source. It seems like this should be possible since ExportConfig allows you to pass in a SpanExporter instance here, but doing the following:

import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base';

const config: ResolveConfigFn = (env: Env, trigger) => {
    return {
        exporter: new ConsoleSpanExporter(),
        service: {
            name: name,
            version: version,
        },
    };
};

export default instrument(handler, config);

Results in this error:

Error reporting spans to exporter: TypeError: Cannot read properties of undefined (reading 'url')
    at checkedFetch (index.js:34:75)
    at OTLPExporter.send (index.js:6454:25)
    at index.js:6440:14
    at new Promise (<anonymous>)
    at OTLPExporter._export (index.js:6438:12)
    at OTLPExporter.export (index.js:6431:10)
    at index.js:6946:22
    at new Promise (<anonymous>)
    at Object.startExport (index.js:6945:21)
    at nextState (index.js:180:148

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.