1 | import { Tracer, Span, SpanKind } from "@opencensus/core";
|
2 | import { GraphQLResolveInfo, ResponsePath } from "graphql";
|
3 |
|
4 | export const openCensusTracer = Symbol("OpenCensus Tracer");
|
5 | export const openCensusSpanMap = Symbol("OpenCensus Span Map");
|
6 |
|
7 | export async function openCensusTracingGraphQLMiddleware(
|
8 | resolve: Function,
|
9 | parent: any,
|
10 | args: any,
|
11 | context: {
|
12 | [openCensusTracer]?: Tracer;
|
13 | [openCensusSpanMap]?: Map<ResponsePath, Span>;
|
14 | },
|
15 | info: GraphQLResolveInfo
|
16 | ): Promise<any> {
|
17 | const tracer = context[openCensusTracer];
|
18 | if (!tracer || !tracer.currentRootSpan) {
|
19 | return resolve(parent, args, context, info);
|
20 | }
|
21 |
|
22 | let span;
|
23 | const spanMap = (context[openCensusSpanMap] =
|
24 | context[openCensusSpanMap] || new Map());
|
25 | const parentSpan = info.path.prev && spanMap.get(info.path.prev);
|
26 | if (parentSpan) {
|
27 | span = tracer.startChildSpan({
|
28 | name: info.fieldName,
|
29 | kind: SpanKind.UNSPECIFIED,
|
30 | childOf: parentSpan
|
31 | });
|
32 |
|
33 | span.addAttribute("parentId", (parent && parent.id) || null);
|
34 | span.addAttribute("parentType", info.parentType.toString());
|
35 | span.addAttribute("fieldName", info.fieldName);
|
36 | span.addAttribute("returnType", info.returnType.toString());
|
37 | }
|
38 |
|
39 | try {
|
40 | return await resolve(parent, args, context, info);
|
41 | } finally {
|
42 | if (span) span.end();
|
43 | }
|
44 | }
|