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



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.

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: });
      const consumer = createConsumer(client, route.topic, route.partitionNumber, offset);

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


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


the instrumentation function (copied from that support post above)

module.exports = instrumentKafkaClient;

function instrumentKafkaClient(shim: any, kafkaModule: any, moduleName: any) {
  // 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