Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(otel): Add OpenTelemetry middleware #901

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

dahlia
Copy link

@dahlia dahlia commented Dec 22, 2024

This middleware addresses honojs/hono#1864. For usage, see also the README file.

Comment on lines +13 to +14
const PACKAGE_NAME = '@hono/otel'
const PACKAGE_VERSION = '0.1.0'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to eliminate the duplication with the metadata in package.json, but couldn't think of a good way to do it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It must get the version number from package.json since Changesets will change the number when the PR is merged automatically.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, as I'm not familiar with packaging JavaScript packages, I have no idea how can I extract the version number from package.json file. Actually, I tried to import it like:

import metadata from '../package.json' with { type: 'json' }

const PACKAGE_NAME = metadata.name
const PACKAGE_VERSION = metadata.version

… but it didn't work due to the following errors from tsc:

src/index.ts(12,22): error TS2732: Cannot find module '../package.json'. Consider using '--resolveJsonModule' to import module with '.json' extension.
src/index.ts(12,40): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext' or 'nodenext'.

Could you give me some idea for this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about trying to use the following tsconfig.json?

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "rootDir": "./src",
    "outDir": "./dist",
    "module": "ESNext",
    "resolveJsonModule": true
  },
  "include": [
    "src/**/*.ts"
  ],
}

@GewoonJaap
Copy link

Does this also work with cloudflare workers? After install the node-sdk of opentelemetry I am getting startup errors. Looks like that package isn't supported with cloudflare workers

@dahlia
Copy link
Author

dahlia commented Dec 25, 2024

Does this also work with cloudflare workers? After install the node-sdk of opentelemetry I am getting startup errors. Looks like that package isn't supported with cloudflare workers

I have no idea either, but @microlabs/otel-cf-workers instead of @opentelemetry/sdk-node might work with Cloudflare Workers?

@GewoonJaap
Copy link

Ah okay. Yeah I made an issue there about Hono compatibility. Looks like Hono exposes things a bit different than the default Cloudflare worker endpoint stuff.

const tracer = tracerProvider.getTracer(PACKAGE_NAME, PACKAGE_VERSION)
const route = c.req.matchedRoutes[c.req.matchedRoutes.length - 1]
await tracer.startActiveSpan(
`${c.req.method} ${route.path}`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is c.req.path not good instead of route.path?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yeah, it's intended! According to OpenTelemetry's Semantic Conventions for HTTP Spans:

HTTP span names SHOULD be {method} {target} if there is a (low-cardinality) target available. If there is no (low-cardinality) {target} available, HTTP span names SHOULD be {method}.

The following guidelines for span names will help you understand what we mean by “low-cardinality”:

The span name concisely identifies the work represented by the Span, for example, an RPC method name, a function name, or the name of a subtask or stage within a larger computation. The span name SHOULD be the most general string that identifies a
(statistically) interesting class of Spans, rather than individual Span instances while still being human-readable. That is, "get_user" is a reasonable name, while "get_user/314159", where "314159" is a user ID, is not a good name due to its high cardinality. Generality SHOULD be prioritized over human-readability.

For example, here are potential span names for an endpoint that gets a
hypothetical account information:

Span Name Guidance
get Too general
get_account/42 Too specific
get_account Good, and account_id=42 would make a nice Span attribute
get_account/{accountId} Also good (using the "HTTP route")

@yusukebe
Copy link
Member

yusukebe commented Jan 6, 2025

Hi @dahlia !

Sorry for the late reply. This is good. I've left the comments and one question. What platforms can this middleware run on? It does not work on Cloudflare Workers, but are there runtimes it does not work on? I think you have to write notes about it on README.

Copy link

changeset-bot bot commented Jan 6, 2025

⚠️ No Changeset found

Latest commit: c797f1f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants