最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - What is the best way to add APM to NuxtJS project - Stack Overflow

programmeradmin1浏览0评论

What is the right way to configure/enable an Elastic APM agent in a Nuxtjs project?

I referred this documentation for a custom NodeJS app. The key takeaway was:

It’s important that the agent is started before you require any other modules in your Node.js application - i.e. before http and before your router etc.

I added the following snippet in nuxt.config.js, but the APM agent is not started or working. I do not see any errors in the app logs.

var apm = require('elastic-apm-node').start({
  serviceName: 'nuxt-app',
  serverUrl: 'http://ELK_APM_SERVER:8200'
})

Is there any other way to do this?

What is the right way to configure/enable an Elastic APM agent in a Nuxtjs project?

I referred this documentation for a custom NodeJS app. The key takeaway was:

It’s important that the agent is started before you require any other modules in your Node.js application - i.e. before http and before your router etc.

I added the following snippet in nuxt.config.js, but the APM agent is not started or working. I do not see any errors in the app logs.

var apm = require('elastic-apm-node').start({
  serviceName: 'nuxt-app',
  serverUrl: 'http://ELK_APM_SERVER:8200'
})

Is there any other way to do this?

Share Improve this question edited Dec 28, 2020 at 22:58 Shankar asked Dec 28, 2020 at 22:19 ShankarShankar 2,8453 gold badges30 silver badges58 bronze badges 2
  • 1 There's a number of different ways to run a nuxt application (static site, server rendered, dev mode, start/prod mode) -- could you update your question with information on how you're starting your nuxt application? – Alana Storm Commented Dec 29, 2020 at 17:32
  • @AlanStorm At the time of posting the question, the project was server rendered with "nuxt start" in NodeJS. – Shankar Commented Dec 30, 2020 at 23:29
Add a ment  | 

4 Answers 4

Reset to default 4

We managed to get this working using a custom Nuxt module which explicitly requires the Node modules to instrument after it has initiated the APM module.

modules/elastic-apm.js:

    const apm = require('elastic-apm-node');
    const defu = require('defu');
    
    module.exports = function() {
      this.nuxt.hook('ready', async(nuxt) => {
        const runtimeConfig = defu(nuxt.options.privateRuntimeConfig, nuxt.options.publicRuntimeConfig);
        const config = (runtimeConfig.elastic && runtimeConfig.elastic.apm) || {};
    
        if (!config.serverUrl) {
          return;
        }
    
        if (!apm.isStarted())  {
          await apm.start(config);
    
          // Now explicitly require the modules we want APM to hook into, as otherwise
          // they would not be instrumented.
          //
          // Docs: https://www.elastic.co/guide/en/apm/agent/nodejs/master/custom-stack.html
          // Modules: https://github./elastic/apm-agent-nodejs/tree/master/lib/instrumentation/modules
          require('http');
          require('http2');
          require('https');
        }
      });
    }

nuxt.config.js:

    module.exports = {
      // Must be in modules, not buildModules
      modules: ['~/modules/elastic-apm'],
      
      publicRuntimeConfig: {
        elastic: {
          apm: {
            serverUrl: process.env.ELASTIC_APM_SERVER_URL,
            serviceName: 'my-nuxt-app',
            usePathAsTransactionName: true // prevent "GET unknown route" transactions
          }
        }
      }
    };

All the answers are outdated and from beginning incorrect (17.02.2022)

To make it work follow these steps:

1.) Create a nodeApm.js in your root dir with the following content:

const nodeApm = require('elastic-apm-node')

if (!nodeApm.isStarted()) { 
    nodeApm.start()
}

2.) Use environment variables to store your config. For example:

ELASTIC_APM_SERVICE_NAME=NUXT_PRODUCTION
ELASTIC_APM_SECRET_TOKEN=yoursecrettokenhere

3.) Edit your package.json

"scripts": {
    // if you want apm also on dev to test, add it also here
    "dev": "node -r ./nodeApm.js node_modules/nuxt/bin/nuxt",
    ...
    "start": "node -r ./nodeApm.js node_modules/nuxt/bin/nuxt start",
...

! Be awere that in ~2022 the node_modules bin folder has lost the "." in the directory name

! In all othere anwsers people forget the start parameter at the end

"start": "node -r ./nodeApm.js node_modules/nuxt/bin/nuxt start",

Based on what I've seen it looks like there isn't a "right" way to do this with the stock nuxt mand line application. The problem seems to be that while nuxt.config.js is the first time a user has a chance to add some javascript, that the nuxt mand line application bootstraps the Node's HTTP frameworks before this config file is required. This means the elastic agent (or any APM agent) doesn't have a chance to hook into the modules.

The current remendations from the Nuxt team appears to be

  1. Invoke nuxt manually via -r

         {
           "scripts": {
             "start": "node -r elastic-apm-node node_modules/nuxt/.bin/nuxt"
           }
         }  
    
  2. Skip nuxt and use NuxtJS programmatically as a middleware in your framework of choice

         const { loadNuxt } = require('nuxt')
         const nuxtPromise = loadNuxt('start')
         app.use((req, res) => { nuxtPromise.then(nuxt => nuxt.render(req, res)) })
    

Based on Alan Storm answer (from Nuxt team) I made it work but with a little modification:

  • I created a file named nodeApm.js where I added the following code:
    const nodeApm = require('elastic-apm-node')
    
    if (!nodeApm.isStarted()) { ... // configuration magic }
    
  • In script sections I added:
    "start": "node -r ./nodeApm.js node_modules/nuxt/.bin/nuxt"
    
发布评论

评论列表(0)

  1. 暂无评论