Your data. Anywhere you go.

New Relic for iOS or Android


Download on the App Store    Android App on Google play


New Relic Insights App for iOS


Download on the App Store


Learn more

Close icon

Understanding custom instrumentation

mod_queue
sla_breaching
1st-day

#1

Node Agent Question Template

  • What language agent version are you using? Any other relevant versions? (Node modules, etc.?)
    node agent 5.10

I’ve read the following links over and over yet it’s not clear how to implement custom instrumentation for messaging.

http://newrelic.github.io/node-newrelic/docs/tutorial-Messaging-Simple.html

instrumentMessages on an in-project module?

I see there are a couple main pieces:

  1. require the newrelic api library, call instrumentMessages and passing it a “message broker module”, and our custom instrumentation function.
  2. write the instrumentation function

I don’t understand what the “message broker module” is referred to in the docs. In the case of kafka-node, is it KafkaClient?
This pattern is referred to routinely. What is ‘my-module’ in this case?

var newrelic = require(‘newrelic’)
newrelic.instrument(‘my-module’, instrumentMyModule)
var myModule = require(‘my-module’)

Here’s what I’ve come up with so far. Thanks for any help.

My kafka reader:

import { Message, Consumer, KafkaClient} from 'kafka-node';
import * as newrelic from 'newrelic';

export class KafkaEventSource  {
  async start() {
      const client = createKafkaClient({ kafkaHost: config.kafka.host });
      const consumer = createConsumer(client, route.topic, route.partitionNumber, offset);

      consumer.on('message', (message: Message) => {      
         // process message
      });
  }
}

main.ts

import * as newrelic from 'newrelic';
const instrumentKafkaClient = require('./kafka-client-instrumentation');
newrelic.instrumentMessages(?, instrumentKafkaClient);
import { KafkaEventSource } from './kafka-event-source';

KafkaEventSource.start();

the instrumentation function (copied from that support post above)

module.exports = instrumentKafkaClient;

function instrumentKafkaClient(shim: any, kafkaModule: any, moduleName: any) {
  shim.setLibrary("kafka");
  // shim.require will load a file relative to the instrumented package root.
// In this case it would be equivalent to requiring kafka-node/lib/protocol.
var protocol = shim.require('./lib/protocol');

shim.recordSubscribedConsume(protocol, 'decodeFetchResponse', {
  consumer: shim.FIRST,
  messageHandler: function checkDecodedMessage(shim: any, fn:any, name:any, args: any) {
    var type = args[1];
    if (type !== 'message') {
      // If you return null then there won't be a transaction.
      return null;
    }

    var message = args[2];
    return {
      destinationName: message.topic,
      destinationType: shim.TOPIC,
      routingKey: message.key
    };
  }
});
}