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

Instrumentation hook is not called in standalone output #49897

Open
1 task done
madebyherzblut opened this issue May 17, 2023 · 23 comments
Open
1 task done

Instrumentation hook is not called in standalone output #49897

madebyherzblut opened this issue May 17, 2023 · 23 comments
Labels
bug Issue was opened via the bug report template. Instrumentation Related to Next.js Instrumentation. Output (export/standalone) Related to the the output option in `next.config.js`.

Comments

@madebyherzblut
Copy link

madebyherzblut commented May 17, 2023

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: x64
      Version: Darwin Kernel Version 22.4.0: Mon Mar  6 21:00:17 PST 2023; root:xnu-8796.101.5~3/RELEASE_X86_64
    Binaries:
      Node: 18.16.0
      npm: 9.5.1
      Yarn: 1.22.19
      pnpm: 8.5.0
    Relevant packages:
      next: 13.4.3-canary.1
      eslint-config-next: N/A
      react: 18.2.0
      react-dom: 18.2.0
      typescript: N/A

Which area(s) of Next.js are affected? (leave empty if unsure)

Standalone mode (output: "standalone")

Link to the code that reproduces this issue

https://github.com/madebyherzblut/next-instrumentation-standalone

To Reproduce

  1. Create a new Next project using create-next-app
  2. Enable the instrumentationHook and standalone output in next.config.js
  3. Build the project using next build
  4. Run the server with .next/standalone/server.js

Describe the Bug

The instrumentation hook is executed with next dev, but not in standalone mode. Based on the example provided in #48262 I could trace the issue back to changes between [email protected] and [email protected]. If the hook is called it should output "Instrumenting nodejs runtime" in the examples below:

$ pnpm add [email protected]
[…]
$ NODE_ENV=production pnpm run build && node .next/standalone/server.js

[…]

Listening on port 3000 url: http://localhost:3000
Instrumenting nodejs runtime                                                # Correct
                                                                                                                                                                                     
$ rm -Rf .next node_modules
$ pnpm add [email protected]
[…]
$ NODE_ENV=production pnpm run build && node .next/standalone/server.js

[…]

Listening on port 3000 url: http://localhost:3000                 # Missing output from hook
                                                                                                                                                                                      
$ pnpm run dev

[…]

event - compiled client and server successfully in 256 ms (326 modules)
Instrumenting nodejs runtime

$ pnpm add next@canary
Packages: +4 -3
++++---

dependencies:
- next 13.3.5-canary.9
+ next 13.4.3-canary.1

Progress: resolved 28, reused 20, downloaded 0, added 4, done
Done in 3.7s
$ NODE_ENV=production pnpm run build && node .next/standalone/server.js

[…]

Listening on port 3000 url: http://localhost:3000             # Missing output from hook
                                                                                         
$ pnpm run dev

> [email protected] dev /Users/chris/Development/next-instrumentation-standalone
> next dev

- ready started server on 0.0.0.0:3000, url: http://localhost:3000
- warn You have enabled experimental feature (instrumentationHook) in next.config.js.
- warn Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.

- event compiled client and server successfully in 1770 ms (304 modules)
- wait compiling...
- wait compiling /instrumentation (client and server)...
- event compiled client and server successfully in 287 ms (319 modules)
Instrumenting nodejs runtime                                            # Correct in `dev` mode

Expected Behavior

The instrumentation hook should be executed in standalone outputs.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

@madebyherzblut madebyherzblut added the bug Issue was opened via the bug report template. label May 17, 2023
@github-actions github-actions bot added the Output (export/standalone) Related to the the output option in `next.config.js`. label May 17, 2023
@tomsseisums
Copy link

Works for me on v13.4.2. The hook seems to not be called on launching the server, but on handling each request:

$ PORT=4200 node .next/standalone/server.js
- info Loaded env from [...]/.next/standalone/.env
Listening on port 4200 url: http://localhost:4200
register instrumentation: nodejs
- info Loaded env from [...]/.next/standalone/.env
register instrumentation: nodejs
register instrumentation: edge
- info Loaded env from [...]/.next/standalone/.env
register instrumentation: nodejs

@madebyherzblut
Copy link
Author

Thanks @tomsseisums, I can confirm that it runs when handling a request. When I read the documentation, I thought there is only one server instance. So is this expected behavior?

If you export a function named register from this file, we will call that function whenever a new Next.js server instance is bootstrapped. When your register function is deployed, it will be called on each cold boot (but exactly once in each environment).
https://nextjs.org/docs/app/building-your-application/optimizing/instrumentation

@kemengwang
Copy link

i have the same problem

@maliesa96
Copy link

same problem as well

@jviall
Copy link

jviall commented Aug 25, 2023

I believe I'm also experiencing this. I use standalone mode; register() function is called when using next dev, but when I deploy to Vercel, there's no sign of it ever running. Using Next 13.4.19.

Only caveat to this is that I'm not sure that vercel deploys both respecting the standalone output? So perhaps my issue is something different.

@MeghdadHadidi
Copy link

Has anyone found any workaround for this? I've already tried canary version, no chance.
I've also found this article which is following a different approach, but it stopped working for me even in local environment

@dannyDNS
Copy link

dannyDNS commented Sep 30, 2023

This is still an issue.

It seems that if you disable swcMinify in next.config.js, instrumentation works with standalone builds.

@Aaqu
Copy link

Aaqu commented Oct 2, 2023

This is still an issue.

It seems that if you disable swcMinify in next.config.js, instrumentation works with standalone builds.

swcMinify: false not work for me, instrumentation starts when open http://localhost:3000 (Next.js 13.5.4-canary.8)

@wisdomstar94
Copy link

wisdomstar94 commented Oct 17, 2023

I'm having the same problem.
When running with standalone, the register function is not called when it boots. :(
My current Next.js version is 13.5.5

@h0wXD
Copy link

h0wXD commented Oct 18, 2023

Ran into the same problem with same behavior as @Aaqu reported. Using Next.js v13.5.4

Using workaround for now when using docker:
Dockerfile

RUN chmod +x ./start.sh
CMD ["./start.sh"]

start.sh

#!/bin/bash
sleep 10 && curl "http://$(hostname):3000/" &> /dev/null &
node ".next/standalone/server.js"

@evanshortiss
Copy link

This bug is also present in 14.0.1. Works fine with next dev, but next build && node .next/standalone/server.js fails to call the register function until a request is received.

@Starefossen
Copy link

Starefossen commented Nov 7, 2023

@jankaifer @sophiebits @feedthejim @huozhi instrumentation.js is missing in standalone mode even though #48615 was merged 😢

@rchubatov
Copy link

rchubatov commented Nov 22, 2023

Thanks @tomsseisums, I can confirm that it runs when handling a request. When I read the documentation, I thought there is only one server instance. So is this expected behavior?

If you export a function named register from this file, we will call that function whenever a new Next.js server instance is bootstrapped. When your register function is deployed, it will be called on each cold boot (but exactly once in each environment).
https://nextjs.org/docs/app/building-your-application/optimizing/instrumentation


There seems to be a bug as the correct behavior should be (from the docs):

When your register function is deployed, it will be called on each cold boot (but exactly once in each environment).

A simple workaround is to create some flag variable (or several) in instrumentation.ts and check if the register function has been called:

let isHookRegisteredInNode = false;
let isHookRegisteredInEdge = false;

export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs' && isHookRegisteredInNode === false) {
    // to do something...
    isHookRegisteredInNode = true;
  }
  
  if (process.env.NEXT_RUNTIME === 'edge' && isHookRegisteredInEdge === false) {
    // to do something...
    isHookRegisteredInEdge = true;
  }
}

This way register will be called only once per environment on the first request. And when the bug is fixed, our code will still work. It might help to init opentelemetry or whatever properly.

@aNyMoRe0505
Copy link

Hello everyone, I'd like to ask if you're experiencing this issue only in standalone mode.
I'm using version 14.0.3, and even with the normal next build && next start, I encounter the same problem.
The register function is only called after receiving the request but works fine with next dev
Is anyone else facing similar issues?

@paschaldev
Copy link

@aNyMoRe0505 I'm experiencing the same issue. I chose to start a Queue worker using the instrumentation.ts file, but this doesn't work after deployment. The register is not called at all even when I make a request.

Everything works smoothly locally

@rrigoni
Copy link

rrigoni commented Dec 7, 2023

Any update on this? I'm experiencing the exact same issue. The only workaround is to not use the standalone export mode.

@Aaqu
Copy link

Aaqu commented Dec 7, 2023

Any update on this? I'm experiencing the exact same issue. The only workaround is to not use the standalone export mode.

vercel will not sell if standalone mode has implement properly...

@daveyjones
Copy link

I've created a separate issue for those experiencing similar issues without standalone mode enabled.

#59999

@AntonAndreevichMoroz
Copy link

I am using the latest version 14.0.5-canary.58 and am also facing this problem. The instrumentation call after assembly is not called when the server starts, but when the route is first called. In dev mode, as expected, instrumentation exits when the server starts.

@Aaqu
Copy link

Aaqu commented Feb 14, 2024

still same problem in Next.js 14.1.1-canary.52

@Aaqu
Copy link

Aaqu commented Mar 27, 2024

instrumentation seems to work in Next.js 14.2.0-canary.44 🎉 more in #63536

next.config.mjs

const nextConfig = {
  output: "standalone",
  compiler: {
    removeConsole: false,
  },
  experimental: {
    instrumentationHook: true
  }
};

export default nextConfig;

src/app/api/boot/boot.ts

const bootedServices = {
  service1: false,
};

export const bootHandler = async () => {
  if (!bootedServices.service1) {
    console.log("🐸 api/boot => SERVICE1");
    bootedServices.service1 = true;

    // your code here
  }
 return bootedServices;
};

src/app/api/boot/route.ts

export async function GET() {
  const bootedServices = await bootHandler();
  return NextResponse.json({ bootedServices });
}

export const dynamic = "force-dynamic";

src/instrumentation.ts

export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    console.log('nodejs');
    setTimeout(async () => {
      await fetch('http://0.0.0.0:3000/api/boot', {cache:"no-store"});
    }, 3000);
  }
}

*tested in docker with file .npmrc includs node-linker=hoisted
**code inspiration roneymaia -> code

@balazsorban44 balazsorban44 added the Instrumentation Related to Next.js Instrumentation. label Apr 19, 2024
@Aaqu
Copy link

Aaqu commented May 9, 2024

It's not working for us still in Next.js 14.2.3. Instrumentation hook is not included in standalone output. It's very strange that this issue is still open. It's been 1 year:)

You have a example? I test my example from instrumentation, work on Next.js 14.2.3 with docker

@leonidasqq
Copy link

You have a example? I test my code from instrumentation, work on Next.js 14.2.3 with docker

It turned out that we had some issues with opentelemetry library. Your example worked for us. We can confirm that latest version is working with standalone output and instrumentation 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. Instrumentation Related to Next.js Instrumentation. Output (export/standalone) Related to the the output option in `next.config.js`.
Projects
None yet
Development

No branches or pull requests