Node.js 收集器安裝

安裝 Node.js 收集器套件

附註: 如果您的應用程式只在 Kubernetes上執行,請考慮改用 Instana AutoTrace WebHook 方法。

安裝 Instana Node.js 收集器是一個簡單的兩步驟程序。 首先,透過下列方式在應用程式中安裝 npm 套件 @instana/collector :

npm install --save @instana/collector

CommonJS

既然已安裝收集器,則需要從應用程式內啟動它。 作法是要求 並起始設定 它作為應用程式中的第一個陳述式。 請注意這是 第一個陳述式 ,否則收集器將無法存取特定資訊。

require('@instana/collector')();

// All other require statements must be done after the collector is initialized.
// Note the () after the require statement of the collector which initializes it.


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

上面顯示的程式碼會使用預設配置選項來起始設定收集器。 您也可以在起始設定 Instana Node.js 收集器時傳入配置物件。 請參閱 配置頁面 ,以取得有效配置選項的清單,特別是 代理程式通訊 一節,以取得在受監視應用程式與 Instana 代理程式之間配置連線功能的詳細資料。

ECMAScript 模組

@instana/collector 安裝為相依關係時,您需要透過 --experimental-loaders 引數載入 Instana Node.js 收集器,以啟動應用程式的收集器。 如需相關資訊,請參閱 ECMAScript 模組

常見陷阱

不正確地整合收集器通常會導致失去可觀察性。 您的 Node.js 應用程式仍會顯示在 Instana 中,但追蹤只會部分運作。 將會追蹤部分呼叫,但其他呼叫將會遺失。

重要事項: 僅讓 require 陳述式作為應用程式中的第一個陳述式,並稍後呼叫 require('@instana/collector') 所匯出的函數,並不足夠。 亦即,不支援下列各項:

// WRONG!
require('@instana/collector'); // @instana/collector is not initialized

require('something');
require('another-thing');

...

也不是這樣的:

// WRONG!
const instana = require('@instana/collector');

require('something');
require('another-thing');

instana(); // TOO LATE!
...

相反地, require('@instana/collector') 匯出的函數必須在任何其他 requireimport 陳述式之前立即呼叫。 這可以在一個陳述式中完成,如上面所示 (請注意 require('@instana/collector')()中的第二對括弧) ,或在兩個連續陳述式中完成:

// Correct:
const instana = require('@instana/collector');
instana(); // this is fine

// Now all other modules can be required:
require('something');
require('another-thing');
...

當您使用 ECMAScript 模組 (ESM) 時,請勿在程式碼中匯入或要求收集器,如下所示:

import instana from '@instana/collector'
instana()
import { something, else } from 'some-module';

請改為使用 實驗性載入器旗標來載入收集器。

使用多個追蹤程式追蹤

不支援使用 Instana 及協力廠商追蹤器 (例如,同時使用 New Relic、Dynatrace 或 Datadog) 來追蹤單一 Node.js 應用程式。

光學

不支援在相同的 Node.js 應用程式中同時使用 OpenTelemetry SDK 及 Instana 收集器。 它可能會導致下列問題:

  • Instana 中遺漏通話
  • Instana 中有重複的資料
  • 中斷的檢測

不建議您在相同的 Node.js 應用程式中同時使用 OpenTelemetry SDK 及 Instana 收集器。 如果您想要使用 Opentelemetry SDK ,請參閱 Node.js OpenTelemetry 整合

進階部署實務範例

Kubernetes & OpenShift

Instana AutoTrace WebHook

附註: 此安裝方法目前位於「技術預覽」中。

Instana AutoTrace WebHook 是 Kubernetes Mutating WebHook Admission Controller 的實作,它會自動配置所有需求,以在整個 Kubernetes 叢集中執行 Node.js 應用程式。

如果您選擇在 Kubernetes 叢集上安裝 Instana AutoTrace WebHook ,則不需要執行任何手動步驟來追蹤在那些叢集裡執行的任何 Node.js 應用程式。

附註: 如果您使用 Instana AutoTrace Webhook ,且想要使用 Instana Node.js SDK ,請檢閱 搭配使用 API 與 AutoTrace WebHook 區段。

手動安裝

如果 Node.js 應用程式及 Instana 代理程式在 Kubernetes 叢集裡執行,請檢查 Kubernetes 網路存取權 上的說明文件,以取得此設定中必要配置的相關資訊。

Cloud Foundry

附註: 本節假設 Instana 代理程式目前正在 Cloud Foundry 基礎的 Diego Cell 上執行。 如果沒有在基礎 Diego Cell 上執行代理程式,則不支援監視 Cloud Foundry 應用程式。

如需如何設定 Instana 代理程式及相關 Cloud Foundry 或 Pivotal Platform 功能的相關資訊,請參閱 Cloud Foundry 及 Pivotal Platform 文件。

在 Cloud Foundry上,不需要在 cf push 層次及應用程式資訊清單上進行配置。 唯一必要的步驟是依照上述說明,將 @instana/collector 套件新增至 Cloud Foundry Node.js 應用程式。

Apigee Microgateway

如需如何搭配使用 Instana Node.js 收集器套件與 Apigee Microgateway (也稱為 edgemicro) 的相關資訊,請參閱 Apigee Microgateway 頁面

Next.js

對於 Next.js 應用程式,建議使用 安裝而不修改原始碼中說明的方法。

安裝而不修改原始碼

在某些情況下,您無法 (或不想) 修改受監視應用程式的原始碼。 對於這些實務範例,可以使用下列方法。 這也是使用 Webpack、Babel 或任何其他類型的 Bundler 或 transpiler 所建置的應用程式的偏好方法。 最後 (但並非最不重要) ,它是 Next.js 應用程式的建議方法。

此方法有兩種特性:

  1. @instana/collector 安裝為專案的 本端相依關係 ,或
  2. 在目標系統上安裝 @instana/collector 廣域

這兩種特性的詳細說明如下。

本端安裝作為相依關係

透過執行指令 npm install -- save @instana/collectoryarn add @instana/collector,將套件 @instana/collector 新增至專案的相依關係。 請 不要 新增陳述式 require('@instana/collector')(); 至您的程式碼。 事實上,您的 JavaScript 或 TypeScript 檔案都不需要提及任何 @instana 套件。

CommonJS

當您啟動 node 執行檔時,請設定環境變數 NODE_OPTIONS 或新增其他 --require 參數。

完成下列其中一個步驟:

  • 設定啟動 Node.js 程序的 節點選項 變數 之前 :

    NODE_OPTIONS="--require ./node_modules/@instana/collector/src/immediate"
    

    如果您使用 Docker建置應用程式,則需要透過將下列行新增至 Dockerfile (在最後一個 FROM 陳述式之後,以及啟動 node 程序的最終 CMDENTRYPOINT 之前) 來執行此動作:

    ENV NODE_OPTIONS="--require ./node_modules/@instana/collector/src/immediate"
    

    附註: src/immediate 組件很重要,因此請確保不會意外省略它。 路徑需要以 ./ 開始,因此 Node.js 知道它是相對路徑,而不是模組 ID。 路徑是根據現行工作目錄來評估。

  • 您可以將 --require 參數新增至啟動 Node.js的指令,而不是設定 NODE_OPTIONS 變數。 如果您通常透過執行類似 node app/index.js的動作來啟動應用程式,請新增其他 --require 指令行引數。 例如,將指令 node app/index.js 變更為下列:

    node --require ./node_modules/@instana/collector/src/immediate app/index.js
    

    附註: src/immediate 組件很重要,因此請確保不會意外省略它。 路徑必須以 ./開頭,因此 Node.js 知道它是相對路徑,而不是模組 ID。 路徑是根據現行工作目錄來評估。 如果這是使用 Docker建置並執行的應用程式,則您需要相應地修改 Dockerfile 中的最終 CMDENTRYPOINT

    如需 --require 參數的相關資訊,請參閱 Node.js 文件中的 -r , -- require module

以這種方式設定 NODE_OPTIONS 或新增 --require ,將在應用程式碼之前載入並起始設定 Node.js 收集器。

套件管理程式必須在目標系統上安裝 @instana/collector ,因此也會正確安裝其所有相依關係。 不建議執行 npm installyarn/yarn install (例如在建置系統上) ,然後將產生的 node_modules 資料夾複製到目標系統。 套件安裝步驟包括編譯原生附加程式,這需要在目標架構上以及正確的 Node.js 版本上進行。

ECMAScript 模組

遵循 前一節中的步驟,但使用下列引數而非 --require:

--experimental-loader /path/to/instana/node_modules/@instana/collector/esm-loader.mjs

附註

  • ECMAScript 支援是從 Node.js 收集器 2.14.0新增。
  • 實驗性載入器 可從節點 v16取得。
  • 載入器會自動起始設定 Instana Node.js 收集器。

廣域安裝

讓套件 @instana/collector 及其所有相依關係可在目標系統上的已知位置 (例如 /path/to/instana/node_modules/@instana/collector) 中使用。

例如,您可以在目標系統上執行指令 npm install -g @instana/collector 。 如果您使用 yarn 而非 npm ,請執行指令 yarn global add 而非 npm install -g。 如果您要將收集器安裝至容器化應用程式,則可以將此陳述式新增至 Dockerfile。 您需要知道 npm install -g 指令放置套件的位置,視作業系統而定。 如需 npm 放置已安裝套件的位置的相關資訊,請參閱 資料夾的 Node.js 說明文件。

CommonJS

當您啟動 node 執行檔時,請設定環境變數 NODE_OPTIONS ,或新增其他 --require 參數。

完成下列其中一個步驟:

  • 在啟動 Node.js 處理程序 之前 ,設定 NODE_OPTIONS 變數:

    NODE_OPTIONS="--require /path/to/instana/node_modules/@instana/collector/src/immediate"
    

    您需要將 /path/to/instana 取代為實際路徑。 如果您使用 Docker建置應用程式,則需要透過將下列行新增至 Dockerfile (在最後一個 FROM 陳述式之後,以及在啟動 node 程序的最終 CMDENTRYPOINT 之前的某個位置) 來執行此動作:

    ENV NODE_OPTIONS="--require /path/to/instana/node_modules/@instana/collector/src/immediate"
    

    附註: src/immediate 組件很重要,因此請確保不會意外省略它。 路徑必須以 /./ 開頭,以告知 Node.js 它是絕對或相對路徑,而不是模組 ID。

  • 取代 設定 節點選項 變數,您可以將 --require 參數新增至啟動 Node.js的指令。 如果您通常透過執行類似 node /path/to/app/的動作來啟動應用程式,請新增其他 --require 指令行引數。 例如,將指令 node /path/to/app 變更為下列:

    node --require /path/to/instana/node_modules/@instana/collector/src/immediate /path/to/app`.
    

    附註: src/immediate 組件很重要,因此請確保不會意外省略它。 路徑必須以 /./ 開頭,以告知 Node.js 它是絕對或相對路徑,而不是模組 ID。 如果這是使用 Docker建置並執行的應用程式,則您需要相應地修改 Dockerfile 中的最終 CMDENTRYPOINT

    如需 --require 參數的相關資訊,請參閱 Node.js 文件中的 -r , -- require module

以這種方式設定 NODE_OPTIONS 或新增 --require ,將在應用程式碼之前載入並起始設定 Node.js 收集器。

套件管理程式必須在目標系統上安裝 @instana/collector ,因此也會正確安裝其所有相依關係。 不建議@instana/collector 安裝在其他位置 (例如,在建置系統上) ,然後將套件複製到目標系統。 npm install 步驟包括編譯原生附加程式,這需要在目標架構及正確的 Node.js 版本上進行。

ECMAScript 模組

遵循 前一節中的步驟,但使用下列引數而非 --require:

--experimental-loader /path/to/instana/node_modules/@instana/collector/esm-loader.mjs

附註

  • 實驗性載入器目前與 Node.js v20不相容。
  • ECMAScript 支援是從 Node.js 收集器 2.14.0新增。
  • 實驗性載入器 可從節點 v16取得。

進階建置實務範例

連結器 (Webpack 及類似)

安裝而不修改原始碼中說明當您使用組合器 (例如 Webpack 或累積更新) 預先處理 Node.js 伺服器應用程式時,偏好的安裝方法。

或者,如果您也可以安裝 @instana/collector 作為一般相依關係。

在這兩種情況下,您都需要確保僅組合您自己的程式碼,而不是 node_modules 資料夾中相依關係的程式碼。 有兩個原因:

  • 模組 @instana/collector 不支援使用 Webpack 預先處理。 在其他問題中,程式碼中使用的動態 require 陳述式將無法正確解決。
  • 為了檢測 協力廠商程式庫, npm 套件 @instana/collector 會截取 Node.js的 require 處理程序。 但是如果那些程式庫在執行時期未載入,而是在建置時期與您自己的程式碼組合,則不會執行 require 程序,且不會套用檢測。 Instana 追蹤在這類設定中無法運作或局部運作。 (確切地說,追蹤僅適用於 Node.js 核心模組 (例如 http ) ,因為依預設會從組合中排除這些模組。)

因此,強烈建議您配置組合器,以便 node_modules 中的所有項目都排除在所有程式碼轉換之外。

您可以使用模組 webpack-node-externals 來達到此目的:

// your webpack.config.js:

const nodeExternals = require('webpack-node-externals');

module.exports = {
  ...
  // externals: nodeModules,
  externals: [nodeExternals()],
  ...
};

如果您是使用 Angular CLI (特別是搭配 Angular Universal/SSR) ,您應該將 "externalDependencies": ["@instana/collector"] (可能還有 @instana/collector 工具的其他程式庫) 新增至 angular.json 檔,以將它/它們從組合中排除 (請參閱 這裡)。

轉換器 (Babel 等)

使用 transpiler (例如 Babel、Traceur 或 TypeScript 編譯器 tsc) 時的偏好安裝方法在 安裝而不修改原始碼中有說明。

或者,您可以將 @instana/collector 安裝為一般相依關係,但不建議使用此方法。 它需要您密切注意您的 transpiler 如何處理 importrequire 陳述式。 如果您的 transpiler 處理 ES6 import 陳述式,則這是特定的匯入。 在這類設定中,將類似這樣的內容放在主要檔的頂端 將無法運作 :

import instana from '@instana/collector';

// THIS WILL NOT WORK because transpilers change the order of imports and statements.
instana();

import express from 'express';

為何不行? 根據 ES6 規格, 在執行模組主體之前評估所有匯入項目。 Babel 及其他轉換程式符合此規則,並在轉換原始檔時將 所有 匯入項目移至頂端。 將在匯入之後放置所有實際的陳述式。 因此,此範例中 express 的匯入將置於 instana(); 呼叫之前。 在您的已轉換檔案中,您最後會遇到類似如下的情況:

var _instana = _interopRequireDefault(require("@instana/collector"));

var _express = _interopRequireDefault(require("express"));

var _morgan = _interopRequireDefault(require("morgan"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

(0, _instana.default)(); // <- This is too late, since all other modules will already have been required.

...

如您所見, @instana/collector init 函數的實際呼叫是在轉換檔中的所有 require 陳述式之後。

相反地,您可以執行如下的動作:

// Put this import at the top of your main file. Only the import here,
// don't change this to "import instana from './instanaInit'"!
import './instanaInit';

// Now all the other imports can follow:
import express from 'express';
import morgan from 'morgan';

// The following statement is optional; it is only required if you want to use
// Instana's Node.js API (https://www.ibm.com/docs/en/instana-observability/current?topic=nodejs-instana-api):
// @ts-ignore (in case you are using TypeScript, to avoid 'Could not find a declaration file for '@instana/collector')
import instana from '@instana/collector';

檔案 instanaInit.js (如果您使用 TypeScript,則為 instanaInit.ts ) 應該只有下列一個陳述式:

require('@instana/collector')();

如此一來,當處理程序啟動時,即會立即呼叫 init 函數。

一般而言,當使用任何 transpiler 時,最好在整合 @instana/collector時檢查 transpiler 的輸出檔。

## 原生附加程式 {: #native-add-ons}

沒有原生附加程式的協助,部分資訊無法供 Node.js 程式使用。 具體而言, Instana Node.js 收集器使用下列附加程式:

  • 擷取記憶體回收的相關資訊
  • 擷取事件迴圈活動的相關資訊
  • 適用於 側寫

所有原生附加程式都是 選用相依關係。 在沒有這些原生附加程式的情況下,收集器將正常運作,但將停用上述特性。 如果遺漏任何這些相依關係,則在啟動時,會將日誌訊息列印至應用程式日誌,如下所示:

Could not load @instana/autoprofile. You will not get profiling information for this Node.js app in Instana, although
autoprofiling has been enabled. This typically occurs when native add-ons could not be built during module installation
(npm install/yarn) or when npm install --no-optional or yarn --ignore-optional have been used to install dependencies.
See the instructions to learn more about the requirements of the collector:
https://www.ibm.com/docs/de/obi/current?topic=nodejs-collector-installation#native-add-ons

附註: 如果其他記憶體回收及事件迴圈度量值與您無關,且您不打算在 Node.js上使用 Instana AutoProfile 特性,則可以放心地忽略這些訊息。

遺漏原生附加程式有兩個可能的原因:

  • 安裝與 npm install --no-optionalyarn --ignore-optional的相依關係。 如果該旗標存在,則 npm/yarn 甚至不會嘗試安裝這些相依關係。 若要修正該問題,請從安裝步驟中移除 --no-optional/--ignore-optional 旗標,或在 npm install --no-optional/yarn --ignore-optional 步驟之後為有問題的相依關係新增明確安裝步驟:
    • npm install @instana/autoprofile / yarn add @instana/autoprofile
    • npm install event-loop-stats / yarn add event-loop-stats
    • npm install gcstats.js / yarn add gcstats.js
  • npm install/yarn 步驟期間,附加程式編譯失敗。 本節的其餘部分說明發生這種情況的原因,以及如何修正它。

當安裝 Instana Node.js 收集器相依關係時 (作為 npm installyarn 步驟的一部分) ,會針對您的系統及 Node.js 版本自動編譯原生附加程式。 若要使編譯運作,系統需要安裝 makeg++python 等工具。 通常可以使用稱為 build-essential 或類似的軟體組來安裝這些工具 (視您作業系統的套件管理程式及登錄而定)。 下列範例顯示如何對熱門 Linux 發行套件執行此動作:

# for Debian-based distributions (including Ubuntu)
apt-get install build-essential
# or, for Fedora-based distributions (CentOS, Red Hat, etc.)
yum groupinstall "Development Tools"
# or, for Alpine Linux
apk add build-base python

重要事項: 相依關係的安裝需要在將執行應用程式的機器上進行。 否則,原生附加程式可能與目標機器的系統架構或使用中的 Node.js 版本不相容。 因此,在建置伺服器上執行指令 npm install/yarn ,然後將應用程式 (包括相依關係) 複製到目標機器,以安裝相依關係是 不當作法

如果您在容器中執行 Node.js 應用程式,則這方面需要額外注意。 您可能想要檢查 Docker 建置的輸出是否有 node-gyp 錯誤 (尋找 gyp ERR!node-pre-gyp ERR!)。 如果這些存在,您應該檢查並評估它們。 其中一些可以被安全地忽略。 例如,部分套件可能嘗試下載經過前置編譯的二進位檔,如果失敗,則它們會透過 node-gyp 回復編譯,也就是說,如果編譯步驟已運作,則可以忽略下載錯誤。 其他套件在編譯期間會發出大量附註和警告,也可以忽略。

如果選用相依關係的安裝以 gyp ERR! not ok結束,您可能想要查看它。 雖然 Instana 可能無法提供修正特定 Dockerfile的支援,但我們確實提供一些 範例 Dockerfiles

如果在執行 npm install時未順利安裝原生附加程式相依關係 (例如 gcstats.jsevent-loop-stats ) ,套件 @instana/collector 會自動嘗試使用符合作業系統、 Node.js 版本及 libc 變式的預先建置二進位檔。 此功能僅在 x64 Linux上可用。 您可以設定 INSTANA_COPY_PRECOMPILED_NATIVE_ADDONS=false來停用它。

在開發期間停用 Node.js 收集器

停用 Node.js 收集器以進行 (本端) 開發的最簡單方法是使用環境變數。 Express 架構為此目的推廣環境變數 NODE_ENV ,我們建議用於此目的。 以下列方式載入 Node.js 收集器:

if (process.env.NODE_ENV !== 'development') {
  require('@instana/collector')();
}

接下來,在本端啟動應用程式,並將 NODE_ENV 變數設為 development。 範例:

export NODE_ENV=development
# -or-
NODE_ENV=development node myApp.js

套件名稱變更

instana-nodejs-sensor 套件不再更新。

附註: 仍然使用套件名稱 instana-nodejs-sensor? 切換至 @instana/collector

更新 @instana/collector 套件

我們持續改善 Instana 的 Node.js 支援,並建議一律使用 @instana/collector 套件的最新可用版本,以從這些改良中獲益。 每次建置/推出應用程式時,最好將套件更新至其最新版本。 更新的運作方式與任何其他 npm 套件一樣。

在起始 npm install --save @instana/collector 之後 (請參閱上述) ,您的 package.json 將包含相依關係宣告,如 "@instana/collector": "^1.68.2"。 脫字符號 (^) 表示 SemVer 版本範圍 (在此範例中, ^1.68.2 代表 >= 1.68.2 && < 2.0.0)。 版本範圍指定 npm installnpm update 指令的行為。

將版本指定為 "@instana/collector": "1.68.2" (沒有脫字符號 (^) 或更一般的脫字符號 (^) ,而不使用版本範圍) 會固定該確切版本,亦即, npm installnpm update 一律使用版本 1.68.2。 這「不是」建議的選項。 如需詳細資料,請參閱 版本範圍 上的 npm 文件。

  • 在專案中執行 npm update @instana/collector 將安裝符合 package.json 檔案中版本範圍的最新版本。 它也會更新 package.json中的版本範圍字串。 如果有鎖定檔 (package-lock.json) ,也會相應地更新。 請參閱 npm update的文件。
  • 在專案中執行 npm install 也將安裝符合 package.json 檔案中版本範圍的最新版本,但前提是
    1. node_modules 資料夾尚未包含符合版本範圍的 @instana/collector 版本,且
    2. 沒有任何 package-lock.json 檔案會鎖定套件的版本。

最後,如果您在 CI 上建置應用程式,且每次都執行全新 npm install (您未在建置之間保留 node_modules 資料夾) ,且您未將 package-lock.json 確定為版本控制,則以建置步驟形式執行 npm install 足以取得最新版本。 在所有其他情況下 (在建置之間保留 node_modules 及/或在版本控制中保留 package-lock.json ) ,建議在建置中執行 npm update @instana/collector

如果您使用 yarn 而非 npm,請參閱 yarn 文件,特別是 yarn update ,以取得詳細資料,但基本上建議和程序是相同的。

另請參閱