Skip to content

Commit 0199b4f

Browse files
committed
feat: clean up tracing impl
1 parent d539aca commit 0199b4f

File tree

5 files changed

+68
-31
lines changed

5 files changed

+68
-31
lines changed

apps/ensadmin/src/app/@breadcrumbs/(apis)/api/graphql/page.tsx renamed to apps/ensadmin/src/app/@breadcrumbs/(apis)/api/omnigraph/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { BreadcrumbItem, BreadcrumbPage } from "@/components/ui/breadcrumb";
33
export default function Page() {
44
return (
55
<BreadcrumbItem>
6-
<BreadcrumbPage>GraphQL API (ENS v1 + v2)</BreadcrumbPage>
6+
<BreadcrumbPage>Omnigraph API (ENS v1 + v2)</BreadcrumbPage>
77
</BreadcrumbItem>
88
);
99
}

apps/ensapi/src/omnigraph-api/builder.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { trace } from "@opentelemetry/api";
22
import SchemaBuilder, { type MaybePromise } from "@pothos/core";
33
import DataloaderPlugin from "@pothos/plugin-dataloader";
44
import RelayPlugin from "@pothos/plugin-relay";
5-
import TracingPlugin, { isRootField } from "@pothos/plugin-tracing";
5+
import TracingPlugin from "@pothos/plugin-tracing";
66
import { createOpenTelemetryWrapper } from "@pothos/tracing-opentelemetry";
77
import type {
88
ChainId,
@@ -24,7 +24,25 @@ import type { Address, Hex } from "viem";
2424
import type { context } from "@/omnigraph-api/context";
2525

2626
const tracer = trace.getTracer("graphql");
27-
const createSpan = createOpenTelemetryWrapper(tracer, { includeArgs: true, includeSource: false });
27+
const createSpan = createOpenTelemetryWrapper(tracer, {
28+
includeArgs: true,
29+
includeSource: false,
30+
onSpan: (span, options, parent, args, ctx, info) => {
31+
// edge field names are too loud by default and not helpful
32+
if (info.fieldName === "edges") return span.updateName("edges");
33+
34+
// turn a node field name into "Typename([:id])"
35+
if (info.fieldName === "node") {
36+
const typename = (info.returnType as any).name;
37+
const id = (parent as any).node.id;
38+
39+
return span.updateName(`${typename}(${id})`);
40+
}
41+
42+
// otherwise name the span as "Typename.fieldName"
43+
return span.updateName(`${info.parentType.name}.${info.fieldName}`);
44+
},
45+
});
2846

2947
export const builder = new SchemaBuilder<{
3048
Context: ReturnType<typeof context>;
@@ -54,7 +72,7 @@ export const builder = new SchemaBuilder<{
5472
}>({
5573
plugins: [TracingPlugin, DataloaderPlugin, RelayPlugin],
5674
tracing: {
57-
default: (config) => isRootField(config),
75+
default: () => true,
5876
wrap: (resolver, options) => createSpan(resolver, options),
5977
},
6078
relay: {

apps/ensapi/src/omnigraph-api/lib/find-domains/find-domains-resolver.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { type ResolveCursorConnectionArgs, resolveCursorConnection } from "@poth
33
import { and, count } from "drizzle-orm";
44

55
import { ensDb } from "@/lib/ensdb/singleton";
6-
import { withSpanAsync } from "@/lib/instrumentation/auto-span";
6+
import { withActiveSpanAsync } from "@/lib/instrumentation/auto-span";
77
import { makeLogger } from "@/lib/logger";
88
import type { context as createContext } from "@/omnigraph-api/context";
99
import type {
@@ -100,7 +100,7 @@ export function resolveFindDomains(
100100

101101
return lazyConnection({
102102
totalCount: () =>
103-
withSpanAsync(tracer, "totalCount", {}, async () => {
103+
withActiveSpanAsync(tracer, "find-domains.totalCount", {}, async () => {
104104
const rows = await ensDb.with(domains).select({ count: count() }).from(domains);
105105
return rows[0].count;
106106
}),
@@ -149,17 +149,17 @@ export function resolveFindDomains(
149149
logger.debug({ sql: query.toSQL() });
150150

151151
// execute paginated query
152-
const results = await withSpanAsync(
152+
const results = await withActiveSpanAsync(
153153
tracer,
154-
"connection",
154+
"find-domains.connection",
155155
{ orderBy, orderDir, limit },
156156
() => query.execute(),
157157
);
158158

159159
// load Domain entities via dataloader
160-
const loadedDomains = await withSpanAsync(
160+
const loadedDomains = await withActiveSpanAsync(
161161
tracer,
162-
"dataloader",
162+
"find-domains.dataloader",
163163
{ count: results.length },
164164
() =>
165165
rejectAnyErrors(

apps/ensapi/src/omnigraph-api/lib/get-domain-by-interpreted-name.ts

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import config from "@/config";
22

3+
import { trace } from "@opentelemetry/api";
34
import { Param, sql } from "drizzle-orm";
45
import { namehash } from "viem";
56

@@ -16,13 +17,15 @@ import {
1617
} from "@ensnode/ensnode-sdk";
1718

1819
import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton";
20+
import { withActiveSpanAsync } from "@/lib/instrumentation/auto-span";
1921
import { lazy } from "@/lib/lazy";
2022
import { makeLogger } from "@/lib/logger";
2123

2224
// lazy() defers construction until first use so that this module can be
2325
// imported without env vars being present (e.g. during OpenAPI generation).
24-
const getRootRegistryId = lazy(() => maybeGetENSv2RootRegistryId(config.namespace));
26+
const _maybeGetENSv2RootRegistryId = lazy(() => maybeGetENSv2RootRegistryId(config.namespace));
2527

28+
const tracer = trace.getTracer("get-domain-by-interpreted-name");
2629
const logger = makeLogger("get-domain-by-interpreted-name");
2730
const v1Logger = makeLogger("get-domain-by-interpreted-name:v1");
2831
const v2Logger = makeLogger("get-domain-by-interpreted-name:v2");
@@ -63,18 +66,27 @@ const v2Logger = makeLogger("get-domain-by-interpreted-name:v2");
6366
export async function getDomainIdByInterpretedName(
6467
name: InterpretedName,
6568
): Promise<DomainId | null> {
66-
// Domains addressable in v2 are preferred, but v1 lookups are cheap, so just do them both ahead of time
67-
const rootRegistryId = getRootRegistryId();
68-
const [v1DomainId, v2DomainId] = await Promise.all([
69-
v1_getDomainIdByInterpretedName(name),
70-
// only resolve v2Domain if ENSv2 Root Registry is defined
71-
rootRegistryId ? v2_getDomainIdByInterpretedName(rootRegistryId, name) : null,
72-
]);
73-
74-
logger.debug({ v1DomainId, v2DomainId });
75-
76-
// prefer v2Domain over v1Domain
77-
return v2DomainId || v1DomainId || null;
69+
return withActiveSpanAsync(tracer, "getDomainIdByInterpretedName", { name }, async () => {
70+
// Domains addressable in v2 are preferred, but v1 lookups are cheap, so just do them both ahead of time
71+
const rootRegistryId = _maybeGetENSv2RootRegistryId();
72+
73+
const [v1DomainId, v2DomainId] = await Promise.all([
74+
withActiveSpanAsync(tracer, "v1_getDomainId", {}, () =>
75+
v1_getDomainIdByInterpretedName(name),
76+
),
77+
// only resolve v2Domain if ENSv2 Root Registry is defined
78+
rootRegistryId
79+
? withActiveSpanAsync(tracer, "v2_getDomainId", {}, () =>
80+
v2_getDomainIdByInterpretedName(rootRegistryId, name),
81+
)
82+
: null,
83+
]);
84+
85+
logger.debug({ v1DomainId, v2DomainId });
86+
87+
// prefer v2Domain over v1Domain
88+
return v2DomainId || v1DomainId || null;
89+
});
7890
}
7991

8092
/**

apps/ensapi/src/omnigraph-api/schema/domain.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { trace } from "@opentelemetry/api";
12
import { type ResolveCursorConnectionArgs, resolveCursorConnection } from "@pothos/plugin-relay";
23
import { and, count, eq, getTableColumns } from "drizzle-orm";
34

@@ -9,6 +10,7 @@ import {
910
} from "@ensnode/ensnode-sdk";
1011

1112
import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton";
13+
import { withSpanAsync } from "@/lib/instrumentation/auto-span";
1214
import { builder } from "@/omnigraph-api/builder";
1315
import {
1416
orderPaginationBy,
@@ -41,6 +43,7 @@ import { RegistrationInterfaceRef } from "@/omnigraph-api/schema/registration";
4143
import { RegistryRef } from "@/omnigraph-api/schema/registry";
4244
import { ResolverRef } from "@/omnigraph-api/schema/resolver";
4345

46+
const tracer = trace.getTracer("schema/Domain");
4447
const isENSv1Domain = (domain: Domain): domain is ENSv1Domain => "parentId" in domain;
4548

4649
/////////////////////////////
@@ -49,21 +52,25 @@ const isENSv1Domain = (domain: Domain): domain is ENSv1Domain => "parentId" in d
4952

5053
export const ENSv1DomainRef = builder.loadableObjectRef("ENSv1Domain", {
5154
load: (ids: ENSv1DomainId[]) =>
52-
ensDb.query.v1Domain.findMany({
53-
where: (t, { inArray }) => inArray(t.id, ids),
54-
with: { label: true },
55-
}),
55+
withSpanAsync(tracer, "ENSv1Domain.load", { count: ids.length }, () =>
56+
ensDb.query.v1Domain.findMany({
57+
where: (t, { inArray }) => inArray(t.id, ids),
58+
with: { label: true },
59+
}),
60+
),
5661
toKey: getModelId,
5762
cacheResolved: true,
5863
sort: true,
5964
});
6065

6166
export const ENSv2DomainRef = builder.loadableObjectRef("ENSv2Domain", {
6267
load: (ids: ENSv2DomainId[]) =>
63-
ensDb.query.v2Domain.findMany({
64-
where: (t, { inArray }) => inArray(t.id, ids),
65-
with: { label: true },
66-
}),
68+
withSpanAsync(tracer, "ENSv2Domain.load", { count: ids.length }, () =>
69+
ensDb.query.v2Domain.findMany({
70+
where: (t, { inArray }) => inArray(t.id, ids),
71+
with: { label: true },
72+
}),
73+
),
6774
toKey: getModelId,
6875
cacheResolved: true,
6976
sort: true,

0 commit comments

Comments
 (0)