Skip to content

Instantly share code, notes, and snippets.

@LeonanCarvalho
Last active January 26, 2022 14:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LeonanCarvalho/15f24a3cf5958c5efc9d7547423d6ad9 to your computer and use it in GitHub Desktop.
Save LeonanCarvalho/15f24a3cf5958c5efc9d7547423d6ad9 to your computer and use it in GitHub Desktop.
NewRelic Tests
//This implementation was a lab to understand how newrelic transactions work
const newrelic = require('newrelic');
module.exports = class NewRelicTracer {
constructor(name) {
this.name = name;
}
start(group = '') {
let payload;
// Call newrelic.getTransaction to retrieve a handle on the current transaction, if exists
const transactionHandle = newrelic.getTransaction();
//Newrelic aways have a stub to avoid crashing the app,
// When it do not return TransactionHandlerStub it will return a Boolean values (true/false)
// When it return a Stub, isSampled will return undefined
if (transactionHandle.isSampled() === true) {
//Create a distribuited trace context
payload = transactionHandle.createDistributedTracePayload().text();
}
//Return the transaction as a promise
return new Promise(resolve => {
newrelic.startBackgroundTransaction(this.name, group, () => {
//Inside a startbackground aways have a transaction, even if not sampled
const backgroundHandle = newrelic.getTransaction();
if (payload) {
backgroundHandle.acceptDistributedTracePayload(payload);
}
return resolve(backgroundHandle);
});
});
}
addSegment(name, recordMetrics = true) {
let promiseResolve;
const segmentPromise = new Promise(resolve => {
promiseResolve = resolve;
});
//Start a new span as a segment, and return the resolve as "end" to be controlled in the outer scope
newrelic.startSegment(
name,
recordMetrics,
async () => {
return await segmentPromise;
},
(err, output) => {
console.warn(`Segment ${name} Error:`, output);
promiseResolve(err);
}
);
return { end: promiseResolve };
}
};
//This method doesn't work because the new relic agent is not able to retrive the segments started after start a background transaction
//Returning a kind of detached segments, I was not able to check anything at logs =/
const NewRelicTracer = require('./custom_tracer');
const nrTracer = new NewRelicTracer(`workerInit`);
const transaction = await nrTracer.start('worker'); // At this point the transaction is created and you can see at one.newrelic.com
const segment = nrTracer.addSegment('segmentInit');// but this segment are detached, and is not able to find it in the dashboards ou NSQL
segment.end();
nrTracer.addSegment('testUnclosedSegment');
const segment2 = nrTracer.addSegment('segmentAutoScaler');
segment2.end();
const t1 = nrTracer.addSegment('metricTrue', true);
const t2 = nrTracer.addSegment('metricFalse', false); //Using record as a false doesn't appear to have significant changes at Distribuited Tracing dashboard
setTimeout(() => {
t1.end();
t2.end();
transaction.end();
}, 1000);
// This is the implementation that works as spected
//Creating the transaction, spans and tracing correctly all timers from the segments.
newrelic.startBackgroundTransaction('worker', 'test', () => {
const backgroundHandle = newrelic.getTransaction();
newrelic.startSegment(
'test segment',
false,
() => {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, 1000);
});
},
function cb(err, output) {
// Handle the error and output as appropriate.
console.log(output);
backgroundHandle.end();
}
);
newrelic.startSegment(
'test segment metric',
true,
() => {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, 1000);
});
},
function cb(err, output) {
// Handle the error and output as appropriate.
console.log(output);
backgroundHandle.end();
}
);
setTimeout(() => {
backgroundHandle.end();
}, 5000);
return backgroundHandle;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment