谷歌云跟踪在 Express 中不起作用

cri*_*lla 0 google-app-engine gcloud stackdriver google-cloud-stackdriver

我正在尝试在托管于谷歌云平台的 MERN 项目中实现谷歌跟踪。

我已经按照 Google 提供的指南和示例进行操作,但我无法使其以任何方式工作。

import gCloudTrace from '@google-cloud/trace-agent';
// initialize gcloud trace
if (process.env.NODE_ENV === 'production') {
  console.log(`Starting google cloud trace...`);
  const tracer = gCloudTrace.start();
  console.log(JSON.stringify(tracer,null,2));
};

import express from 'express';
import apiRoute  from './api.js';
import indexRoute from './index/indexRoute.js';

try {

  // setup
  const host = process.env.HOST || '0.0.0.0';
  const port = process.env.PORT || 5050;
  const app = express();

  // routes
  app.use('/', indexRoute);
  app.use('/api', checkGloblalSettings, apiRoute);

  // create and run HTTP server
  app.listen(port, host, () => {
    console.log(`EXPRESS SERVER HTTP BACKEND UP AND RUNNING ON ${host} : ${port}`);
  });

  } catch(error) {
    globalErrorHandler(error);
};
Run Code Online (Sandbox Code Playgroud)

当我部署(谷歌应用程序引擎,flex env)时,一切都很好,所有路线都有效,但我在项目中找不到任何痕迹。我已经仔细检查了 gcloud 设置:Trace API 已启用,无需创建自定义凭据。

有什么建议吗?

cri*_*lla 5

我终于解决了这个问题。虽然问题中的代码看起来是正确的,但问题本质上在于 NodeJS 如何处理 ES6 import() 而不是 require()。

在整个 Google Trace 文档中,您只会找到包含 require() 的示例。这里有一个例子:

if (process.env.NODE_ENV === 'production') {
  require('@google-cloud/trace-agent').start();
}

const express = require('express');
const got = require('got');

const app = express();
const DISCOVERY_URL = 'https://www.googleapis.com/discovery/v1/apis';

// This incoming HTTP request should be captured by Trace
app.get('/', async (req, res) => {
  // This outgoing HTTP request should be captured by Trace
  try {
    const {body} = await got(DISCOVERY_URL, {responseType: 'json'});
    const names = body.items.map(item => item.name);
    res.status(200).send(names.join('\n')).end();
  } catch (err) {
    console.error(err);
    res.status(500).end();
  }
});

// Start the server
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}`);
  console.log('Press Ctrl+C to quit.');
});
Run Code Online (Sandbox Code Playgroud)

事实是,在使用 require 时,会尊重导入顺序(因此,如果您将 require('@ google-cloud/trace-agent').start(); 放在首位,一切正常),使用 import() 代码会运行导入 Express 模块后,也不会跟踪任何内容。

为了解决这个问题,我重新创建了 require 语法(这里是文档),然后使用 require() 一切都完美运行:

import { createRequire } from 'module';
const require = createRequire(import.meta.url);
if (process.env.NODE_ENV === 'production') {
  // [START trace_setup_nodejs_implicit]
  require('@google-cloud/trace-agent').start({
    logLevel: 2,
    flushDelaySeconds: 30,
    ignoreUrls: ['/_ah/health', '/api/status'],
    ignoreMethods: ['OPTIONS'],
    samplingRate: 10,
    bufferSize: 1000,
    onUncaughtException: 'ignore',
  });
  // [END trace_setup_nodejs_implicit]
};

const express = await require('express');
Run Code Online (Sandbox Code Playgroud)

我希望这可以为其他人服务并避免它给我带来的头痛:)