Loading CHANGES.md +1 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ To be released. - Fedify now supports OpenTelemetry for tracing. [[#170]] - Added `CreateFederationOptions.tracerProvider` option. - Added `LookupWebFingerOptions.tracerProvider` option. - Added `@fedify/fedify/x/sveltekit` module for integrating with [SvelteKit] hook. [[#171], [#183] by Jiyu Park] Loading docs/manual/opentelemetry.md +6 −4 Original line number Diff line number Diff line Loading @@ -115,10 +115,11 @@ Instrumented spans Fedify automatically instruments the following operations with OpenTelemetry spans: | Operation | Description | |----------------------|-----------------------------------| | `Federation.fetch()` | Serves the incoming HTTP request. | | `handleWebFinger()` | Handles the WebFinger request. | | Operation | Span type | Description | |----------------------|-----------|-----------------------------------| | `Federation.fetch()` | Server | Serves the incoming HTTP request. | | `lookupWebFinger()` | Client | Looks up the WebFinger resource. | | `handleWebFinger()` | Server | Handles the WebFinger request. | More operations will be instrumented in the future releases. Loading Loading @@ -146,5 +147,6 @@ for ActivityPub: | `activitypub.inboxes` | int | The number of inboxes the activity is sent to. | `12` | | `activitypub.shared_inbox` | boolean | Whether the activity is sent to the shared inbox. | `true` | | `webfinger.resource` | string | The queried resource URI. | `"acct:fedify@hollo.social"` | | `webfinger.resource.scheme` | string | The scheme of the queried resource URI. | `"acct"` | [OpenTelemetry Semantic Conventions]: https://opentelemetry.io/docs/specs/semconv/ src/webfinger/handler.ts +4 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,10 @@ async function handleWebFingerInternal<TContextData>( } throw e; } span?.setAttribute( "webfinger.resource.scheme", resourceUrl.protocol.replace(/:$/, ""), ); if (actorDispatcher == null) { logger.error("Actor dispatcher is not set."); return await onNotFound(request); Loading src/webfinger/lookup.ts +54 −0 Original line number Diff line number Diff line import { getLogger } from "@logtape/logtape"; import { SpanKind, SpanStatusCode, type TracerProvider, } from "@opentelemetry/api"; import metadata from "../deno.json" with { type: "json" }; import { getUserAgent, type GetUserAgentOptions, Loading @@ -19,6 +25,12 @@ export interface LookupWebFingerOptions { * the `User-Agent` header value. */ userAgent?: GetUserAgentOptions | string; /** * The OpenTelemetry tracer provider. * @since 1.3.0 */ tracerProvider?: TracerProvider; } /** Loading @@ -31,6 +43,48 @@ export interface LookupWebFingerOptions { export async function lookupWebFinger( resource: URL | string, options: LookupWebFingerOptions = {}, ): Promise<ResourceDescriptor | null> { if (options.tracerProvider == null) { return await lookupWebFingerInternal(resource, options); } const tracer = options.tracerProvider.getTracer( metadata.name, metadata.version, ); return await tracer.startActiveSpan( "WebFinger", { kind: SpanKind.CLIENT, attributes: { "webfinger.resource": resource.toString(), "webfinger.resource.scheme": typeof resource === "string" ? resource.replace(/:.*$/, "") : resource.protocol.replace(/:$/, ""), }, }, async (span) => { try { const result = await lookupWebFingerInternal(resource, options); span.setStatus({ code: result === null ? SpanStatusCode.ERROR : SpanStatusCode.OK, }); return result; } catch (error) { span.setStatus({ code: SpanStatusCode.ERROR, message: String(error), }); throw error; } finally { span.end(); } }, ); } async function lookupWebFingerInternal( resource: URL | string, options: LookupWebFingerOptions = {}, ): Promise<ResourceDescriptor | null> { if (typeof resource === "string") resource = new URL(resource); let protocol = "https:"; Loading Loading
CHANGES.md +1 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ To be released. - Fedify now supports OpenTelemetry for tracing. [[#170]] - Added `CreateFederationOptions.tracerProvider` option. - Added `LookupWebFingerOptions.tracerProvider` option. - Added `@fedify/fedify/x/sveltekit` module for integrating with [SvelteKit] hook. [[#171], [#183] by Jiyu Park] Loading
docs/manual/opentelemetry.md +6 −4 Original line number Diff line number Diff line Loading @@ -115,10 +115,11 @@ Instrumented spans Fedify automatically instruments the following operations with OpenTelemetry spans: | Operation | Description | |----------------------|-----------------------------------| | `Federation.fetch()` | Serves the incoming HTTP request. | | `handleWebFinger()` | Handles the WebFinger request. | | Operation | Span type | Description | |----------------------|-----------|-----------------------------------| | `Federation.fetch()` | Server | Serves the incoming HTTP request. | | `lookupWebFinger()` | Client | Looks up the WebFinger resource. | | `handleWebFinger()` | Server | Handles the WebFinger request. | More operations will be instrumented in the future releases. Loading Loading @@ -146,5 +147,6 @@ for ActivityPub: | `activitypub.inboxes` | int | The number of inboxes the activity is sent to. | `12` | | `activitypub.shared_inbox` | boolean | Whether the activity is sent to the shared inbox. | `true` | | `webfinger.resource` | string | The queried resource URI. | `"acct:fedify@hollo.social"` | | `webfinger.resource.scheme` | string | The scheme of the queried resource URI. | `"acct"` | [OpenTelemetry Semantic Conventions]: https://opentelemetry.io/docs/specs/semconv/
src/webfinger/handler.ts +4 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,10 @@ async function handleWebFingerInternal<TContextData>( } throw e; } span?.setAttribute( "webfinger.resource.scheme", resourceUrl.protocol.replace(/:$/, ""), ); if (actorDispatcher == null) { logger.error("Actor dispatcher is not set."); return await onNotFound(request); Loading
src/webfinger/lookup.ts +54 −0 Original line number Diff line number Diff line import { getLogger } from "@logtape/logtape"; import { SpanKind, SpanStatusCode, type TracerProvider, } from "@opentelemetry/api"; import metadata from "../deno.json" with { type: "json" }; import { getUserAgent, type GetUserAgentOptions, Loading @@ -19,6 +25,12 @@ export interface LookupWebFingerOptions { * the `User-Agent` header value. */ userAgent?: GetUserAgentOptions | string; /** * The OpenTelemetry tracer provider. * @since 1.3.0 */ tracerProvider?: TracerProvider; } /** Loading @@ -31,6 +43,48 @@ export interface LookupWebFingerOptions { export async function lookupWebFinger( resource: URL | string, options: LookupWebFingerOptions = {}, ): Promise<ResourceDescriptor | null> { if (options.tracerProvider == null) { return await lookupWebFingerInternal(resource, options); } const tracer = options.tracerProvider.getTracer( metadata.name, metadata.version, ); return await tracer.startActiveSpan( "WebFinger", { kind: SpanKind.CLIENT, attributes: { "webfinger.resource": resource.toString(), "webfinger.resource.scheme": typeof resource === "string" ? resource.replace(/:.*$/, "") : resource.protocol.replace(/:$/, ""), }, }, async (span) => { try { const result = await lookupWebFingerInternal(resource, options); span.setStatus({ code: result === null ? SpanStatusCode.ERROR : SpanStatusCode.OK, }); return result; } catch (error) { span.setStatus({ code: SpanStatusCode.ERROR, message: String(error), }); throw error; } finally { span.end(); } }, ); } async function lookupWebFingerInternal( resource: URL | string, options: LookupWebFingerOptions = {}, ): Promise<ResourceDescriptor | null> { if (typeof resource === "string") resource = new URL(resource); let protocol = "https:"; Loading