Skip to content

Instantly share code, notes, and snippets.

@shousper
Created August 13, 2021 02:42
Show Gist options
  • Select an option

  • Save shousper/4f0180fb3bfda740b59f5bcdef7e59f3 to your computer and use it in GitHub Desktop.

Select an option

Save shousper/4f0180fb3bfda740b59f5bcdef7e59f3 to your computer and use it in GitHub Desktop.
knexjs Query Instrumentation
import { UpDownCounter, ValueRecorder } from '@opentelemetry/api-metrics';
import { hrTime, hrTimeDuration } from '@opentelemetry/core';
type QueryEvent = {
sql: string;
__knexUid: string;
__knexTxId?: string;
};
export function install(db: Knex): void {
const queryStarts: Map<string, [number, number]> = new Map();
const activeQueries = getActiveQueries();
const queryLatency = getQueryLatency();
db.on('query', queryStart);
db.on('query-error', queryComplete);
db.on('query-response', (_: unknown, data: QueryEvent) => queryComplete(data));
function queryStart(data: QueryEvent): void {
queryStarts.set(data.__knexUid, hrTime());
activeQueries.add(1);
}
function queryComplete(data: QueryEvent, error?: Error): void {
const start = queryStarts.get(data.__knexUid);
if (!start) {
// Unable to track query, we don't have a start time.
return;
}
queryStarts.delete(data.__knexUid);
activeQueries.add(-1);
queryLatency.record(hrTimeToSeconds(hrTimeDuration(start, hrTime())), {
sql: data.sql,
error: String(!!error),
});
}
}
function hrTimeToSeconds(hrTime: HrTime): number {
return Math.round(hrTime[0] + hrTime[1] / 1e9);
}
function getActiveQueries(): UpDownCounter {
// .. snip ..
}
function getQueryLatency(): ValueRecorder {
// .. ship ..
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment