@fedify/fedify 1.3.0-dev.569 → 1.3.0-dev.571

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "@fedify/fedify",
3
- "version": "1.3.0-dev.569+d97ee744",
3
+ "version": "1.3.0-dev.571+be4ca8c6",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./mod.ts",
@@ -1,6 +1,8 @@
1
1
  import * as dntShim from "../_dnt.shims.js";
2
2
  import { getLogger } from "@logtape/logtape";
3
+ import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
3
4
  import { accepts } from "../deps/jsr.io/@std/http/1.0.11/negotiation.js";
5
+ import metadata from "../deno.js";
4
6
  import { verifyRequest } from "../sig/http.js";
5
7
  import { detachSignature, verifyJsonLd } from "../sig/ld.js";
6
8
  import { doesActorOwnKey } from "../sig/owner.js";
@@ -68,25 +70,54 @@ export async function handleObject(request, { values, context, objectDispatcher,
68
70
  },
69
71
  });
70
72
  }
71
- export async function handleCollection(request, { name, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, onUnauthorized, onNotFound, onNotAcceptable, }) {
72
- if (collectionCallbacks == null)
73
- return await onNotFound(request);
73
+ export async function handleCollection(request, { name, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, onUnauthorized, onNotFound, onNotAcceptable, }) {
74
+ const spanName = name.trim().replace(/\s+/g, "_");
75
+ tracerProvider = tracerProvider ?? trace.getTracerProvider();
76
+ const tracer = tracerProvider.getTracer(metadata.name, metadata.version);
74
77
  const url = new URL(request.url);
75
78
  const cursor = url.searchParams.get("cursor");
79
+ if (collectionCallbacks == null)
80
+ return await onNotFound(request);
76
81
  let collection;
77
82
  const baseUri = uriGetter(identifier);
78
83
  if (cursor == null) {
79
84
  const firstCursor = await collectionCallbacks.firstCursor?.(context, identifier);
80
85
  const totalItems = await collectionCallbacks.counter?.(context, identifier);
81
86
  if (firstCursor == null) {
82
- const page = await collectionCallbacks.dispatcher(context, identifier, null, filter);
83
- if (page == null)
84
- return await onNotFound(request);
85
- const { items } = page;
87
+ const itemsOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection ${spanName}`, {
88
+ kind: SpanKind.SERVER,
89
+ attributes: {
90
+ "activitypub.collection.id": baseUri.href,
91
+ "activitypub.collection.type": OrderedCollection.typeId.href,
92
+ },
93
+ }, async (span) => {
94
+ if (totalItems != null) {
95
+ span.setAttribute("activitypub.collection.total_items", Number(totalItems));
96
+ }
97
+ try {
98
+ const page = await collectionCallbacks.dispatcher(context, identifier, null, filter);
99
+ if (page == null) {
100
+ span.setStatus({ code: SpanStatusCode.ERROR });
101
+ return await onNotFound(request);
102
+ }
103
+ const { items } = page;
104
+ span.setAttribute("fedify.collection.items", items.length);
105
+ return items;
106
+ }
107
+ catch (e) {
108
+ span.setStatus({ code: SpanStatusCode.ERROR, message: String(e) });
109
+ throw e;
110
+ }
111
+ finally {
112
+ span.end();
113
+ }
114
+ });
115
+ if (itemsOrResponse instanceof Response)
116
+ return itemsOrResponse;
86
117
  collection = new OrderedCollection({
87
118
  id: baseUri,
88
119
  totalItems: totalItems == null ? null : Number(totalItems),
89
- items: filterCollectionItems(items, name, filterPredicate),
120
+ items: filterCollectionItems(itemsOrResponse, name, filterPredicate),
90
121
  });
91
122
  }
92
123
  else {
@@ -109,10 +140,34 @@ export async function handleCollection(request, { name, identifier, uriGetter, f
109
140
  else {
110
141
  const uri = new URL(baseUri);
111
142
  uri.searchParams.set("cursor", cursor);
112
- const page = await collectionCallbacks.dispatcher(context, identifier, cursor, filter);
113
- if (page == null)
114
- return await onNotFound(request);
115
- const { items, prevCursor, nextCursor } = page;
143
+ const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name}`, {
144
+ kind: SpanKind.SERVER,
145
+ attributes: {
146
+ "activitypub.collection.id": uri.href,
147
+ "activitypub.collection.type": OrderedCollectionPage.typeId.href,
148
+ "fedify.collection.cursor": cursor,
149
+ },
150
+ }, async (span) => {
151
+ try {
152
+ const page = await collectionCallbacks.dispatcher(context, identifier, cursor, filter);
153
+ if (page == null) {
154
+ span.setStatus({ code: SpanStatusCode.ERROR });
155
+ return await onNotFound(request);
156
+ }
157
+ span.setAttribute("fedify.collection.items", page.items.length);
158
+ return page;
159
+ }
160
+ catch (e) {
161
+ span.setStatus({ code: SpanStatusCode.ERROR, message: String(e) });
162
+ throw e;
163
+ }
164
+ finally {
165
+ span.end();
166
+ }
167
+ });
168
+ if (pageOrResponse instanceof Response)
169
+ return pageOrResponse;
170
+ const { items, prevCursor, nextCursor } = pageOrResponse;
116
171
  let prev = null;
117
172
  if (prevCursor != null) {
118
173
  prev = new URL(context.url);
@@ -403,7 +403,10 @@ export class FederationImpl {
403
403
  }
404
404
  const callbacks = {
405
405
  dispatcher: async (context, identifier) => {
406
- const actor = await this.#getTracer().startActiveSpan("activitypub.dispatch_actor", { kind: SpanKind.SERVER }, async (span) => {
406
+ const actor = await this.#getTracer().startActiveSpan("activitypub.dispatch_actor", {
407
+ kind: SpanKind.SERVER,
408
+ attributes: { "fedify.actor.identifier": identifier },
409
+ }, async (span) => {
407
410
  try {
408
411
  const actor = await dispatcher(context, identifier);
409
412
  span.setAttribute("activitypub.actor.id", (actor?.id ?? context.getActorUri(identifier)).href);
@@ -560,7 +563,13 @@ export class FederationImpl {
560
563
  this.actorCallbacks = callbacks;
561
564
  const setters = {
562
565
  setKeyPairsDispatcher: (dispatcher) => {
563
- callbacks.keyPairsDispatcher = (ctx, identifier) => this.#getTracer().startActiveSpan("activitypub.dispatch_actor_key_pairs", { kind: SpanKind.SERVER }, async (span) => {
566
+ callbacks.keyPairsDispatcher = (ctx, identifier) => this.#getTracer().startActiveSpan("activitypub.dispatch_actor_key_pairs", {
567
+ kind: SpanKind.SERVER,
568
+ attributes: {
569
+ "activitypub.actor.id": ctx.getActorUri(identifier).href,
570
+ "fedify.actor.identifier": identifier,
571
+ },
572
+ }, async (span) => {
564
573
  try {
565
574
  return await dispatcher(ctx, identifier);
566
575
  }
@@ -600,7 +609,41 @@ export class FederationImpl {
600
609
  throw new RouterError("Path for object dispatcher must have at least one variable.");
601
610
  }
602
611
  const callbacks = {
603
- dispatcher,
612
+ dispatcher: (ctx, values) => {
613
+ const tracer = this.#getTracer();
614
+ return tracer.startActiveSpan("activitypub.dispatch_object", {
615
+ kind: SpanKind.SERVER,
616
+ attributes: {
617
+ "fedify.object.type": cls.typeId.href,
618
+ ...globalThis.Object.fromEntries(globalThis.Object.entries(values).map(([k, v]) => [
619
+ `fedify.object.values.${k}`,
620
+ v,
621
+ ])),
622
+ },
623
+ }, async (span) => {
624
+ try {
625
+ const object = await dispatcher(ctx, values);
626
+ span.setAttribute("activitypub.object.id", (object?.id ?? ctx.getObjectUri(cls, values)).href);
627
+ if (object == null) {
628
+ span.setStatus({ code: SpanStatusCode.ERROR });
629
+ }
630
+ else {
631
+ span.setAttribute("activitypub.object.type", getTypeId(object).href);
632
+ }
633
+ return object;
634
+ }
635
+ catch (e) {
636
+ span.setStatus({
637
+ code: SpanStatusCode.ERROR,
638
+ message: String(e),
639
+ });
640
+ throw e;
641
+ }
642
+ finally {
643
+ span.end();
644
+ }
645
+ });
646
+ },
604
647
  parameters: variables,
605
648
  };
606
649
  this.objectCallbacks[cls.typeId.href] = callbacks;
@@ -1180,6 +1223,7 @@ export class FederationImpl {
1180
1223
  uriGetter: context.getOutboxUri.bind(context),
1181
1224
  context,
1182
1225
  collectionCallbacks: this.outboxCallbacks,
1226
+ tracerProvider: this.tracerProvider,
1183
1227
  onUnauthorized,
1184
1228
  onNotFound,
1185
1229
  onNotAcceptable,
@@ -1192,6 +1236,7 @@ export class FederationImpl {
1192
1236
  uriGetter: context.getInboxUri.bind(context),
1193
1237
  context,
1194
1238
  collectionCallbacks: this.inboxCallbacks,
1239
+ tracerProvider: this.tracerProvider,
1195
1240
  onUnauthorized,
1196
1241
  onNotFound,
1197
1242
  onNotAcceptable,
@@ -1239,6 +1284,7 @@ export class FederationImpl {
1239
1284
  uriGetter: context.getFollowingUri.bind(context),
1240
1285
  context,
1241
1286
  collectionCallbacks: this.followingCallbacks,
1287
+ tracerProvider: this.tracerProvider,
1242
1288
  onUnauthorized,
1243
1289
  onNotFound,
1244
1290
  onNotAcceptable,
@@ -1259,6 +1305,7 @@ export class FederationImpl {
1259
1305
  ? ((i) => (i instanceof URL ? i.href : i.id?.href ?? "").startsWith(baseUrl))
1260
1306
  : undefined,
1261
1307
  collectionCallbacks: this.followersCallbacks,
1308
+ tracerProvider: this.tracerProvider,
1262
1309
  onUnauthorized,
1263
1310
  onNotFound,
1264
1311
  onNotAcceptable,
@@ -1271,6 +1318,7 @@ export class FederationImpl {
1271
1318
  uriGetter: context.getLikedUri.bind(context),
1272
1319
  context,
1273
1320
  collectionCallbacks: this.likedCallbacks,
1321
+ tracerProvider: this.tracerProvider,
1274
1322
  onUnauthorized,
1275
1323
  onNotFound,
1276
1324
  onNotAcceptable,
@@ -1282,6 +1330,7 @@ export class FederationImpl {
1282
1330
  uriGetter: context.getFeaturedUri.bind(context),
1283
1331
  context,
1284
1332
  collectionCallbacks: this.featuredCallbacks,
1333
+ tracerProvider: this.tracerProvider,
1285
1334
  onUnauthorized,
1286
1335
  onNotFound,
1287
1336
  onNotAcceptable,
@@ -1293,6 +1342,7 @@ export class FederationImpl {
1293
1342
  uriGetter: context.getFeaturedTagsUri.bind(context),
1294
1343
  context,
1295
1344
  collectionCallbacks: this.featuredTagsCallbacks,
1345
+ tracerProvider: this.tracerProvider,
1296
1346
  onUnauthorized,
1297
1347
  onNotFound,
1298
1348
  onNotAcceptable,