将 APM 添加到 NuxtJS 项目的最佳方法是什么

What is the best way to add APM to NuxtJS project

在 Nuxtjs 项目中 configure/enable Elastic APM 代理的正确方法是什么?

我推荐了 this documentation 自定义 NodeJS 应用程序。关键要点是:

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.

我在 nuxt.config.js 中添加了以下片段,但 APM 代理未启动或工作。我在应用程序日志中没有看到任何错误。

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

还有其他方法吗?

根据我所见,似乎没有一种“正确”的方法可以使用常用的 nuxt 命令行应用程序来执行此操作。问题似乎是,虽然 nuxt.config.js 是用户第一次有机会添加一些 javascript,但 nuxt 命令行应用程序会在这个配置文件之前引导 Node 的 HTTP 框架required。这意味着弹性代理(或任何 APM 代理)没有机会连接到模块。

Nuxt 团队的 current recommendations 似乎是

  1. 通过-r

    手动调用nuxt
         {
           "scripts": {
             "start": "node -r elastic-apm-node node_modules/nuxt/.bin/nuxt"
           }
         }  
    
  2. 跳过 nuxtuse NuxtJS programmatically 作为您选择的框架中的中间件

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

基于 Alan Storm 的回答(来自 Nuxt 团队),我做了一些修改但使它起作用:

  • 我创建了一个名为 nodeApm.js 的文件,并在其中添加了以下代码:
    const nodeApm = require('elastic-apm-node')
    
    if (!nodeApm.isStarted()) { ... // configuration magic }
    
  • 我在脚本部分添加了:
    "start": "node -r ./nodeApm.js node_modules/nuxt/.bin/nuxt"
    

我们设法使用自定义 Nuxt 模块实现了此功能,该模块明确要求 Node 模块在启动 APM 模块后进行检测。

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.com/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
          }
        }
      }
    };

所有答案都已过时并且从一开始就不正确 (17.02.2022)

要使其正常工作,请执行以下步骤:

1.) 在您的根目录中创建一个 nodeApm.js,内容如下:

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

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

2.) 使用环境变量来存储您的配置。例如:

ELASTIC_APM_SERVICE_NAME=NUXT_PRODUCTION
ELASTIC_APM_SECRET_TOKEN=yoursecrettokenhere

3.) 编辑您的 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",
...

!请注意,在 ~2022 年 node_modules bin 文件夹中丢失了“.”。在目录名

!在所有其他答案中,人们忘记了末尾的开始参数

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