Closed SethDavenport closed 5 years ago
My Data dog init code looks like this:
// @flow
import ddTrace from 'dd-trace';
import { k, PROJECT_ENV } from '../project-env';
export const tracer = ddTrace.init({
service: `${k.DATADOG_APM_DEFAULT_SERVICE}-${k.APP_ROLE}`,
enabled: k.DATADOG_APM_ENABLED,
hostname: k.DATADOG_APM_HOST,
port: k.DATADOG_APM_PORT,
debug: k.DATADOG_APM_PORT,
tags: { env: PROJECT_ENV },
logInjection: true,
});
Downgrading back to 0.7.2 and removing the new logInjection: true
(:cry:) resolves the issue.
Environment:
I think the issue is here:
This correlate
function appears to be applied to any object passed as an argument to winston.info
:
However it mutates the input which as a caller I find unexpected.
Would it make sense to do something like this?
utils/log.js
:
'use strict'
const tx = require('./tx')
const log = {
// Add trace identifiers from the current scope to a log record.
correlate (tracer, record) {
const span = tracer.scope().active()
record = record || {}
if (span) {
// Don't mutate the input.
return Object.assign(
{},
record,
{
dd: {
trace_id: span.context().toTraceId(),
span_id: span.context().toSpanId(),
},
});
}
return record
}
}
module.exports = Object.assign({}, tx, log)
Actually looking again, tx.correlate
is used in bunch of places and it looks like making it not mutate its input will break a bunch of stuff. Maybe instead we can update winston.js
to something like this?
function createWrapLog (tracer, config) {
return function wrapLog (log) {
return function logWithTrace (level, msg, meta, callback) {
const scope = tracer.scope().active()
if (!scope || arguments.length < 1) return log.apply(this, arguments)
const correlatedArguments = Array.prototype.slice.call(arguments)
for (let i = 0, l = correlatedArguments.length; i < l; i++) {
if (typeof correlatedArguments[i] !== 'object') continue
tx.correlate(tracer, correlatedArguments[i])
return log.apply(this, correlatedArguments)
}
meta = tx.correlate(tracer)
callback = arguments[arguments.length - 1]
const index = typeof callback === 'function'
? arguments.length - 1
: arguments.length
Array.prototype.splice.call(arguments, index, 0, meta)
return log.apply(this, arguments)
}
}
}
I think the change you are proposing would make sense in every place where tx.correlate
is used. I didn't think about the case where an object that is used outside of logging would be passed to a logger when designing this, but it makes sense that the original object is never altered. I will try to see if this can be done for every logger.
I updated from dd-trace-js
0.7.2
to0.10.3
(and turned on thelogInjection
feature) and suddenly my insert and update postgres queries started failing:dd
is not a column in my table.Here's the code that results in that query:
I am not explicitly setting a
dd
prop on the params object I'm sending to knex.js (our ORM).The log entry generated from this function is as follows:
It looks like trace injection is adding a
dd
property to theparams
object I pass to knex.js; this extra property is causing knex to think I have a column in my table calleddd
when in fact I don't.