This is the abstraction that I've written:
import { context, defaultTextMapSetter } from '@opentelemetry/api';
import { W3CTraceContextPropagator } from '@opentelemetry/core';
type SqlCommentComponents = {
traceparent?: string;
};
const renderSqlCommentComponent = (comments: SqlCommentComponents) => {
return (
'/*' +
Object.entries(comments)
.filter(([, value]) => {
return value !== undefined;
})
.map(([key, value]) => {
return `${encodeURIComponent(key)}='${encodeURIComponent(value)}'`;
})
.join(',') +
'*/'
);
};
export const getSqlcommenterComment = (): string | null => {
const propagator = new W3CTraceContextPropagator();
const activeContext = {};
const sqlCommentComponents: SqlCommentComponents = {};
propagator.inject(context.active(), activeContext, defaultTextMapSetter);
if (
'traceparent' in activeContext &&
typeof activeContext.traceparent === 'string'
) {
sqlCommentComponents.traceparent = activeContext.traceparent;
}
return Object.entries(sqlCommentComponents).length === 0
? null
: renderSqlCommentComponent(sqlCommentComponents);
};
I then use Slonik interceptor to append the Sqlcommenter comment to the end of the SQL:
interceptors.push({
transformQuery: (queryContext, query) => {
return {
...query,
sql: `${query.sql}\n${getSqlcommenterComment() ?? ''}`,
};
return query;
},
});
The output that it produces appears to be correct:
SELECT id
FROM ip_address
WHERE
ip_address = $1 AND
updated_at > now() - interval '7 day'
/*traceparent='00-b1fb1430bc3932f7ad4193417161a8c0-876e8f488bbd46d2-01'*/
However, when viewing traces in the Cloud Trace, I don't see the associated traces, which makes me suspect that I am not generating the traceparent
value correctly.