Node.js用New Relicは、大半の標準的なウェブリクエストを自動的にインストゥルメントしますが、時には拡張インストゥルメンテーションを必要とする場合もあります。エージェントのカスタムインストゥルメンテーションAPIがあれば、通常は未対応のWebフレームワーク、データベース、そしてメッセージサービスクライアント向けにインストゥルメンテーションを作成できます。
Node.jsエージェントのカスタムインストゥルメンテーションAPIでは、以下を行うことができます:
エージェントのバージョン要件
このドキュメント内のカスタムインストゥルメンテーション方法は、Node.jsエージェントのバージョン2.0.0から利用できます。カスタムインストゥルメンテーションAPI v1.xを使用したインストゥルメンテーションの詳細に関しては、レガシーNode.jsカスタムインストゥルメンテーションのドキュメントを参照してください。
未対応のWebフレームワークをインストゥルメントする
Node.jsエージェントバージョン2.0.0より、New Relicは追加のウェブフレームワークに対するインストゥルメンテーション拡張のためにAPIを提供しています。チュートリアルを含めた詳細に関しては、GitHubにおけるNode.jsのWebフレームワークのインストゥルメンテーションドキュメントを参照してください。
未対応のメッセージサービスクライアントをインストゥルメントする
Node.jsエージェントバージョン2.0.0より、New Relicは追加のメッセージサービスライブラリに対するインストゥルメンテーション拡張のためにAPIを提供しています。チュートリアルを含めた詳細に関しては、GitHubにおけるNode.jsのメッセージサービスクライアントのインストゥルメンテーションドキュメントを参照してください。
未対応のデータストアをインストゥルメントする
Node.jsエージェントバージョン2.0.0より、New Relicは追加のデータストアライブラリに対するインストゥルメンテーションを拡張するためにAPIを提供しています。チュートリアルを含めた詳細に関しては、GitHubにおけるNode.jsのデータストアのインストゥルメンテーションドキュメントを参照してください。
Webトランザクションをインストゥルメントする
カスタムウェブトランザクションを作成するには、startWebTransaction
を呼び出してトランザクションを開始します。トランザクションを終了するには、以下のいずれかのオプションを使用してください。
トランザクションを終了する | コメント |
---|
Promise | startWebTransaction に渡したハンドラーがpromiseを返した場合、エージェントは返されたpromiseが解決または却下されると、トランザクションを終了します。
|
手動 | 新規トランザクションのコンテキストでgetTransaction を呼び出した場合は、トランザクションが手動で処理されることがエージェントに通知されます。 ハンドラーでgetTransaction が呼び出された場合は、呼び出してトランザクションを終了する必要があります。 transaction.end(). |
同期 | いずれのオプションも実行されなかった場合、ハンドラーが同期して返された時点でトランザクションは終了します。 |
この例では、socket.io
内の/websocket/ping
トランザクション、/websocket/update
トランザクション、および/websocket/new-message
トランザクションをインストゥルメントします。/ping
の例は同期ですが、/new-message
と/update
の例は非同期になります。
const nr = require('newrelic');
const app = require('http').createServer();
const io = require('socket.io')(app);
io.on('connection', function(socket) {
socket.on('ping', function(data) {
nr.startWebTransaction('/websocket/ping', function transactionHandler() {
socket.on('update', function(data) {
nr.startWebTransaction('/websocket/update', function transactionHandler() {
const transaction = nr.getTransaction();
updateChatWindow(data, function transactionHandler() {
socket.emit('update-done');
socket.on('new-message', function(data) {
nr.startWebTransaction('/websocket/new-message', function transactionHandler() {
return new Promise(function(resolve, reject) {
addMessageToChat(data, function() {
socket.emit('message-received');
この方法で得られるのは、作成したトランザクションに関する基本的なタイミングデータのみとなります。特定のフレームワークに関する、より複雑なタイミングデータとトランザクションの命名を作成するには、Node.js APIドキュメントならびにGitHubにおける関連のWebFrameworkチュートリアルを参照してください。
バックグラウンドトランザクションをインストゥルメントする
カスタムトランザクションを使用して、Web以外のトランザクション(バックグラウンドトランザクション)をインストゥルメントできます。たとえば:
- ご利用のアプリケーションにおける周期的な仕事
- リクエスト完了後も続く作業
バックグラウンドタスクをインストゥルメントするには、ハンドラーでstartBackgroundTransaction
を呼び出してバックグラウンドトランザクションを開始します。トランザクションを終了するには、以下のいずれかのオプションを使用してください。
トランザクションを終了する | コメント |
---|
Promise | startBackgroundTransaction に渡したハンドラーがpromiseを返した場合、エージェントは返されたpromiseが解決または却下されると、トランザクションを終了します。
|
手動 | 新規トランザクションのコンテキストでgetTransaction を呼び出した場合は、トランザクションが手動で処理されることがエージェントに通知されます。 ハンドラーでgetTransaction が呼び出された場合は、呼び出してトランザクションを終了する必要があります。 transaction.end(). |
同期 | いずれのオプションも実行されなかった場合、ハンドラーが同期して返された時点でトランザクションは終了します。 |
この例は、update:cache
内にsetInterval
をインストゥルメントします。
const nr = require('newrelic');
const redis = require('redis').createClient();
nr.startBackgroundTransaction('update:cache', function transactionHandler() {
const newValue = someDataGenerator();
const transaction = nr.getTransaction();
redis.set('some:cache:key', newValue, function() {
nr.startBackgroundTransaction('flush:cache', function transactionHandler() {
return new Promise(function(resolve, reject) {
flushCache(redis, function afterFlush(err) {
トランザクション内でインストゥルメンテーションを拡張する
APIにあるインストゥルメンテーション登録手段を使用して、インストゥルメンテーションを作成できます。 インストゥルメンテーションAPIを使用してインストゥルメンテーションを書いた場合、関連オブジェクト上で「モンキーパッチ」メソッド(置換関数)を用いてメトリクスと命名をより詳細に指定できるようになります。その他のオプションでは、既にインストゥルメントされたWebトランザクションへの可視性を提供するか、自動的にインストゥルメントされないデータベースやその他のトランザクション内作業への洞察を得ることができます。
これを行うには、コールバックをカスタムトレーサーでラップします。カスタムトレーサーは、特定の関数やデータベース呼び出しなど、既存トランザクション内の追加セグメントに関する具体的なメトリクスの作成・収集を行います。
- 個別のコールバックをインストゥルメントするには、コールバック内で
startSegment()
を呼び出し、主なコールバックロジックをhandler
関数に移動します。 - 非同期関数内で呼び出された関数をインストゥルメントするには、ターゲット関数とその親非同期関数をどちらも
startSegment()
でラップします。
重要
こうした例は、トランザクション内で実行中のコード内に配置する必要があります。トランザクションの作成元がカスタムもしくは自動であるかは、関係がありません。
この例では、単一のコールバックを追跡します:
nr.startSegment('db:createObject', true, function(cb) {
}, function(err, result) {
if (util.handleError(err, res)) {
res.write(JSON.stringify(result.rows[0].id));
この例では、pg.connect
とclient.query
の両方を追跡します。これは、client.query
が非同期親関数(pg.connect
)によって呼び出されるためです。そうでないと、client.query
からデータを取得できません。これによって、startSegment()
はこうした非同期領域全域に有効なトランザクションを伝播できます。
nr.startSegment('pg:connect', true, function(cb) {
pg.connect(config.db_string, cb);
}, function(err, client, done) {
if (util.handleError(err, '500', res)) {
nr.startSegment('pg:query', true, function(cb) {
client.query('SELECT count(*) FROM test_count', cb);
}, function(err, result) {
if (util.handleError(err, '500', res)) {
res.write(result.rows[0].count);
この例はコールバックの場合と同じですが、PromiseベースのAPIとのやり取りを扱っています。promiseの場合は、単純にpromiseを返してから、then
の後でstartSegment
を呼び出し、実行を続けます。
nr.startSegment('pg:connect', true, function() {
return pg.connect(config.db_string);
}).then(function(client) {
return nr.startSegment('pg:query', true, function() {
return client.query('SELECT count(*) FROM test_count');
}).then(function(result) {
res.write(result.rows[0].count);
util.handleError(err, '500', res);
util.handleError(err, '500', res);
この例では、非同期の作業を制御するためにasync
/await
を使用して、コードをインストゥルメントする方法を解説しています。これには、Node.js 8以降ならびにNode.js用New Relicエージェントv2.3.0以降を使用する必要があります。
const client = await nr.startSegment('pg:connect', true, async () => {
return await pg.connect(config.db_string);
const result = await nr.startSegment('pg:query', true, async () => {
return await client.query('SELECT count(*) FROM test_count');
res.write(result.rows[0].count);
util.handleError(err, '500', res);
util.handleError(err, '500', res);
この例では、戻り値を変数に割り当てる非同期関数を記録する際に、startSegment
を使用する方法を解説します。
const result = nr.startSegment('calculateTotal', true, function() {
return calculateTotal(outerVar1, outerVar2);
重要
startSegment
関数は、Node.jsエージェント3.3.0のリリースで使用できます。