Hello I was wondering if anyone has done this to track their meteor apps https://docs.datadoghq.com/tracing/setup/nodejs/ I tried adding it following this guide but haven’t succed as Im not getting anything on the dd instance.
Thanks!
Hello I was wondering if anyone has done this to track their meteor apps https://docs.datadoghq.com/tracing/setup/nodejs/ I tried adding it following this guide but haven’t succed as Im not getting anything on the dd instance.
Thanks!
You could start the production build with -r argument, like:
“node -r trace.js bundle/main.js”
and in trace.js:
require(‘dd-trace’).init()
Thanks, Im just lost on how to add this if Im building my app on aws pipelines, I have a staged step where I call meteor build build/ --allow-superuser --directory --architecture os.linux.x86_64
after that I build a docker image with this build docker build --build-arg NODE_VERSION=8.11.0 -t $REPOSITORY_URI:latest .
So on those steps where should I add this node -r trace.js bundle/main.js
call?
Thanks again!
In the Dockerfile itself where COMMAND or ENTRYPOINT is defined. I don’t know if it’s exactly that line of code and I don’t know if it’s going to work, it’s just the concept using that command line option to preload datadog:
https://nodejs.org/api/cli.html#cli_r_require_module
So please post here once you were successful
I embarked on this journey last week and have had partial success.
I created my own server-side instrumentation around meteor methods using the opentracing api and it works fine in isolation. Trace id correlation, though, does not, and I suspect that it has something to do with fibers because I seem to get trace ids from the dd-trace-patched mongodb driver mixed up with the trace ids from my manual instrumentation in my dd-trace-patched winston logging calls.
This is my call chain:
registered meteor method invocation
tracer.startSpan
error logging wrapper
code that does actual work, including mongodb queries
return to logging wrapper
span.finish()
What I noticed was that the error logging wrapper which uses winston to log json to aws cloudwatch would get the wrong traceid when logging a caught and re-thrown error, in one instance one that belonged to a mongodb span instead of the span that was opened around it.
This made the datadog feature to see log entries for a specific trace not work
If I figure this out I will let you know.
Here’s my instrumentation code in case it helps:
export const outputWithTraceId = (span: opentracing.Span, message: string) => {
return; // no-op for now
const context = span.context();
const traceId = context.toTraceId();
process.stdout.write(`traceId: ${traceId} - ${message}\n`);
};
const handleError = (span: opentracing.Span, name: string, e: any) => {
outputWithTraceId(span, `handling error for ${name}`);
const errorMessage = getErrorMessage(e);
span.log({
event: "error",
message: errorMessage,
error: e
}); // span.log does NOT work with datadog so this line does nothing
span.setTag(opentracing.Tags.ERROR, true);
span.setTag("errorMessage", errorMessage);
span.finish();
};
const wrap = <T extends (...args: any[]) => any>(fn: T, name: string) =>
function wrappedMethod(...args: Parameters<T>) {
const tracer = opentracing.globalTracer();
// https://docs.datadoghq.com/tracing/trace_search_and_analytics/?tab=nodejs
const tags: {
[key: string]: string | boolean;
} = {
[ResourceNameTag]: name,
[AnalyticsTag]: true
};
if (this.userId) {
tags["user.id"] = this.userId;
}
const userSpan = tracer.startSpan("meteorCall", {
tags
});
outputWithTraceId(userSpan, `new span for ${name}`);
try {
const result: ReturnType<T> = fn.bind(this)(...args);
userSpan.log({
event: "request_end"
});
outputWithTraceId(userSpan, `success - finishing for ${name}`);
userSpan.finish();
return result;
} catch (e) {
handleError(userSpan, name, e);
throw e;
}
};
function wrapAllExistingMethods() {
const meteor = Meteor as any;
const defaultServer = meteor.default_server;
const handlers: { [k: string]: (...args: any[]) => any } =
defaultServer.method_handlers;
Object.keys(handlers).forEach(key => {
const fn = handlers[key];
const wrapped = wrap(fn, key);
handlers[key] = wrapped;
});
}
// First time in, wrap existing methods
wrapAllExistingMethods();
export const wrapMethodsForTracing = <
T extends { [k in keyof T]: (...args: any[]) => any }
>(
methods: T
): T => {
const wrappedMethods = { ...methods };
for (const name of Object.keys(methods)) {
const method = methods[name as keyof T];
wrappedMethods[name] = wrap(method, name);
}
return wrappedMethods;
};
Did you have any luck with implementing this?
I’ve imported the tracer early on in server code and it catches certain services, but I believe it’s missing quite a bit. Wondering where you wound up on this one.
Hey @typ no luck, tried a lot of stuff and I just gave up, nothing really worked, sorry I don’t have a solution for you.
I’ve seen this presentation: https://www.youtube.com/watch?v=GGBIuDJauYo
by @npvn and Oli from Pathable. Perhaps they could elaborate a bit on how they got the integration working?