Node.js のカスタム計測

Node.js 用 New Relic は、標準のウェブリクエストはほとんどの自動的に計測します。しかし、計測を拡張したい場合もあります。カスタム計測を使用すると、Web ソケットバックグラウンドジョブ、そしてサポート対象外のデータベースを計測できるようになります。カスタム計測は、コードの特定のセクションをターゲットにして、より詳細な情報を得ることもできます。

カスタム計測は、Node.js エージェントのバージョン 1.10.0 以降で使用できます。

ウェブトランザクションの計測

websocket リクエストなどのウェブトランザクションを計測するには、カスタムトランザクションを作成します。カスタムトランザクションを作成すると、エージェントが自動的に計測するトランザクションから取らえるものと同じタイプの可視性が得られます。

  1. 計測したいハンドラーを createWebTransaction() でラップします。.
  2. トランザクションの最後で endTransaction() を呼び出すようにします。
トランザクション名の最後に大括弧 [suffix] を使わないでください。New Relic は自動的に名前から大括弧を取り除きます。代わりに、括弧 (suffix) やその他の記号を使用してください。
例: socket.io 内で2つのトランザクションを計測する

この例では、socket.io 内の /websocket/ping トランザクションと /websocket/new-message トランザクションを計測しています。/ping の例は同期ですが、/new-message の方は非同期です。

var nr = require('newrelic')
var app = require('http').createServer()
var io = require('socket.io')(app)

io.on('connection', function (socket) {
  socket.on('ping', nr.createWebTransaction('/websocket/ping', function (data) {
    socket.emit('pong')
    nr.endTransaction()
  }))
  socket.on('new-message', nr.createWebTransaction('/websocket/new-message', function (data) {
    addMessageToChat(data, function () {
      socket.emit('message-received')
      nr.endTransaction()
    })
  }))
})
トランザクションの最後で、endTransaction() を呼ぶようにしてください。

バックグランドトランザクションの計測

カスタムトランザクションを使って、アプリ内の定期的なジョブやリクエスト完了後に続く作業など、バックグラウンドタスクを計測することもできます。バックグラウンドタスクを計測するには、計測したいハンドラーを createBackgroundTransaction() でラップします。トランザクションの最後で、endTransaction() を呼び出すのを忘れないでください。

例: setInterval 内での計測
setInterval 内での update:cache の計測の例

var nr = require('newrelic')
var redis = require('redis').createClient()

setInterval(nr.createBackgroundTransaction('update:cache', function () {
  var newValue = someDataGenerator()
 
  redis.set('some:cache:key', newValue, function () {
    nr.endTransaction() // End the transaction once redis is done
  })
}), 30000) // Every 30s
トランザクションの最後で、endTransaction() を呼び出すのを忘れないでください。

トランザクション内で計測を実行する

カスタム計測を使って、すでに計測済みのウェブトランザクションにより詳細情報に提供したり、データベースやその他のトランザクション内で自動的に計測されない作業を把握することもできます。そうするためには、コールバックをカスタムトレーサーにラップします。カスタムトレーサーは、特定の function やデータベースコールなど既存のトランザクション内の追加セグメント用の特定のメトリクスを作成し、収集します。

コールバックを計測するには、createTracer() でコールバックをラップします。非同期 function 内で呼び出される function を計測する場合は、ターゲット function とその親非同期 function の両方を createTracer() でラップする必要があります。

以下の例では、計測済みのトランザクション内に配置する必要があります。トランザクションは、自動的に計測されるか、カスタムトランザクションを介して計測されます。
例: コールバックの計測
以下はある一つのコールバックをラップする例です。

// Wrap the callback in a segment
db.createObject(nr.createTracer('db:createObject', function (err, result) {
  // Some error handler that will end the response for us
  if (util.handleError(err, res)) {
    return
  }
  res.write(JSON.stringify(result.rows[0].id))
  res.write('\n')
  res.end()
}))
例: 非同期 function の計測
この例では、pg.connectclient.query の両方をラップします。これは、client.query が非同期親 function (pg.connect)によって呼び出されるためです。それ以外の場合は、client.query からデータが取得されません。これにより、createTracer() は非同期の境界を越えてアクティブなトランザクションを伝播できます。

pg.connect(config.db_string, nr.createTracer('pg:connect', function (err, client, done) {
  if (util.handleError(err, '500', res)) {
    return done()
  }
  client.query('SELECT count(*) FROM test_count', nr.createTracer('pg:query', function (err, result) {
    if (util.handleError(err, '500', res)) {
      return done()
    }

    res.write(result.rows[0].count)
    res.write('\n')
  }))
}))

関連情報

関連情報は以下のとおりです。