Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/gitpod-db/src/traced-db.ts
2498 views
1
/**
2
* Copyright (c) 2020 Gitpod GmbH. All rights reserved.
3
* Licensed under the GNU Affero General Public License (AGPL).
4
* See License.AGPL.txt in the project root for license information.
5
*/
6
7
import { TraceContext, TracingManager } from "@gitpod/gitpod-protocol/lib/util/tracing";
8
import { interfaces } from "inversify";
9
import * as opentracing from "opentracing";
10
11
export class DBWithTracing<T> {
12
protected tracer: opentracing.Tracer;
13
constructor(protected readonly db: any, manager: TracingManager) {
14
this.tracer = manager.getTracerForService("mysql");
15
}
16
17
public trace(ctx: TraceContext): T {
18
return new Proxy(this.db, {
19
get: (_target: any, name: string) => {
20
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
21
const f = Reflect.get(_target, name);
22
if (!f) {
23
return undefined;
24
}
25
26
return async (...args: any[]) => {
27
// do not try and trace calls with an empty trace context - the callers intention most likely was to omit the trace
28
// so as to not spam the trace logs
29
// Also, opentracing makes some assumptions about the Span object, so this might fail under some circumstances
30
function isEmptyObject(obj: object): boolean {
31
return Object.keys(obj).length === 0;
32
}
33
if (!ctx.span || isEmptyObject(ctx.span)) {
34
return await f.bind(_target)(...args);
35
}
36
37
const span = this.tracer.startSpan(name, { childOf: ctx.span });
38
try {
39
return await f.bind(_target)(...args);
40
} catch (e) {
41
TraceContext.setError({ span }, e);
42
throw e;
43
} finally {
44
span.finish();
45
}
46
};
47
},
48
});
49
}
50
}
51
52
export function bindDbWithTracing<T>(traceKey: string | symbol, bind: interfaces.Bind, delegateKey: string | symbol) {
53
return bind(traceKey).toDynamicValue((ctx) => {
54
const root = ctx.container.get(delegateKey) as T;
55
const tracingManager = ctx.container.get(TracingManager);
56
return new DBWithTracing(root, tracingManager);
57
});
58
}
59
60
export const TracedWorkspaceDB = Symbol("TracedWorkspaceDB");
61
export const TracedUserDB = Symbol("TracedUserDB");
62
export const TracedOneTimeSecretDB = Symbol("TracedOneTimeSecretDB");
63
64