Skip to content

Commit

Permalink
fix: keep context within main renderer and error renderer (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
huang-julien authored Jan 23, 2025
1 parent 8dc0e9b commit 93a1530
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 17 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ interface NitroRuntimeHooks {

`defineTracedEventHandler`
- Wrap your event handler with the span assigned to your event. This avoid loosing the context for opentelemetry.
The main renderer and error renderer doesn't need to be wrapped with `defineTracedEventHandler`

## Development

Expand Down
52 changes: 35 additions & 17 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,50 @@ import MagicString from 'magic-string'
import { getPresetFile, isPresetEntry } from './presets'
import { normalize } from "pathe"
import type { Nuxt } from "@nuxt/schema"
import { fileURLToPath } from 'node:url'
import defu from 'defu'

async function module(nitro: Nitro) {
nitro.options.alias['#nitro-opentelemetry/init'] = await getPresetFile(nitro)

if(isPresetEntry(nitro)) {
if (isPresetEntry(nitro)) {
nitro.options.alias['#nitro-entry-file'] = nitro.options.entry
nitro.options.entry = await getPresetFile(nitro)
}

nitro.hooks.hook('rollup:before', (nitro, rollupConfig) => {
if (!rollupConfig.plugins) rollupConfig.plugins = [];
const plugins = rollupConfig.plugins
if(Array.isArray(plugins)) {
if (Array.isArray(plugins)) {
rollupConfig.plugins = plugins.filter((plugin) => {
if( plugin && 'name' in plugin) {
if (plugin && 'name' in plugin) {
// workaround for while waiting for configurable impound settings in nuxt
return plugin.name!== 'impound'
return plugin.name !== 'impound'
}
return true
});
}

(rollupConfig.plugins as Plugin[]).push({
(rollupConfig.plugins as Plugin[]).push({
name: 'inject-init-plugin',
async transform(code, id) {
const normalizedId = normalize(id)
// transform nitro entry file but there's probably a better way
if (normalizedId.includes('runtime/entries') || this.getModuleInfo(id)?.isEntry ) {
const normalizedId = normalize(id)
// transform nitro entry file but there's probably a better way
if (normalizedId.includes('runtime/entries') || this.getModuleInfo(id)?.isEntry) {
const s = new MagicString(code)
s.prepend(`import '#nitro-opentelemetry/init';`)

return {
code: s.toString(),
map: s.generateMap({ hires: true }),
moduleSideEffects: true
}
}
}
// @todo find another way to mark it as side effect :/
if (normalizedId === nitro.options.alias['#nitro-opentelemetry/init']) {
const s = new MagicString(code)
return {
moduleSideEffects: true,
moduleSideEffects: true,
code: s.toString(),
map: s.generateMap({ hires: true }),
}
Expand All @@ -62,6 +64,22 @@ async function module(nitro: Nitro) {
nitro.options.imports.presets.push(presets)
}

if (nitro.options.renderer) {
nitro.options.alias['#nitro-renderer'] = nitro.options.renderer
nitro.options.renderer = fileURLToPath(new URL('runtime/renderer/renderer', import.meta.url))
nitro.options.externals = defu(nitro.options.externals, {
inline: [nitro.options.renderer]
})
}

if (nitro.options.errorHandler) {
nitro.options.alias['#nitro-error-handler'] = nitro.options.errorHandler
nitro.options.errorHandler = fileURLToPath(new URL('runtime/renderer/error', import.meta.url))
nitro.options.externals = defu(nitro.options.externals, {
inline: [nitro.options.errorHandler]
})
}

nitro.options.plugins.push(await resolvePath('nitro-opentelemetry/runtime/plugin', {
extensions: ['.mjs', '.ts']
}))
Expand All @@ -70,11 +88,11 @@ async function module(nitro: Nitro) {
// Dual compatibility with Nuxt and Nitro Modules
export default function moduleWithCompat(arg1: unknown, arg2: unknown) {
if ((arg2 as Nuxt)?.options?.nitro) {
(arg2 as Nuxt).hooks.hookOnce("nitro:config", (nitroConfig) => {
nitroConfig.modules = nitroConfig.modules || [];
nitroConfig.modules.push(module);
});
(arg2 as Nuxt).hooks.hookOnce("nitro:config", (nitroConfig) => {
nitroConfig.modules = nitroConfig.modules || [];
nitroConfig.modules.push(module);
});
} else {
module(arg1 as Nitro);
module(arg1 as Nitro);
}
}
}
8 changes: 8 additions & 0 deletions src/runtime/renderer/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { context } from "@opentelemetry/api";
import { NitroErrorHandler } from "nitropack";
// @ts-ignore - alias
import errorRenderer from "#nitro-error-handler";

export default <NitroErrorHandler>((error, event) => {
return context.with(event.otel.ctx, (errorRenderer as NitroErrorHandler), undefined, error, event)
})
8 changes: 8 additions & 0 deletions src/runtime/renderer/renderer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { context } from '@opentelemetry/api';
// @ts-ignore - alias
import renderer from "#nitro-renderer"
import { eventHandler } from "h3"

export default eventHandler((e) => {
return context.with(e.otel.ctx, renderer, undefined, e)
})

0 comments on commit 93a1530

Please sign in to comment.