From 188e2b10e9178b54c886101681ad9a12d215b0ef Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 8 Apr 2026 11:18:13 -0400 Subject: [PATCH] feat: integrate ap.inErr analytics into federation analytics chart --- .../en-GB/admin/settings/activitypub.json | 3 ++ public/src/admin/federation/analytics.js | 31 +++++++++++++++---- src/controllers/admin/federation.js | 7 +++-- src/views/admin/federation/analytics.tpl | 4 +-- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/public/language/en-GB/admin/settings/activitypub.json b/public/language/en-GB/admin/settings/activitypub.json index 307c4c26a6..d0398e74ff 100644 --- a/public/language/en-GB/admin/settings/activitypub.json +++ b/public/language/en-GB/admin/settings/activitypub.json @@ -68,8 +68,11 @@ "analytics.intro": "This page provides an overview of the state of your forum's federation with other instances/servers", "analytics.details": "NodeBB tracks ActivityPub activity receipts and sends, and you are able to view them by hostname, either hourly or daily. Note that the metrics are only incremented on successful receipts and sends.", "analytics.by-hostname": "Filter by Hostname", + "analytics.in": "Incoming", + "analytics.out": "Outgoing", "analytics.received": "Received Activities", "analytics.sent": "Sent Activites", + "analytics.errors": "Errors", "analytics.term": "Time scale", "analytics.hourly": "Hourly", "analytics.daily": "Daily" diff --git a/public/src/admin/federation/analytics.js b/public/src/admin/federation/analytics.js index 23f3ffd1b0..c2b933fbd4 100644 --- a/public/src/admin/federation/analytics.js +++ b/public/src/admin/federation/analytics.js @@ -7,9 +7,11 @@ import { PointElement, Tooltip, Filler, + Legend, } from 'chart.js'; import { get } from 'api'; +import { translate } from 'translator'; Chart.register( LineController, @@ -18,7 +20,8 @@ Chart.register( LineElement, PointElement, Tooltip, - Filler + Filler, + Legend ); let charts; @@ -57,7 +60,7 @@ async function updateCharts() { }); } -function initializeCharts() { +async function initializeCharts() { const receivedCanvas = document.getElementById('received'); const sentCanvas = document.getElementById('sent'); @@ -79,12 +82,22 @@ function initializeCharts() { datasets: [ { ...commonDataSetOpts, - backgroundColor: 'rgba(186,139,175,0.2)', - borderColor: 'rgba(186,139,175,1)', - pointBackgroundColor: 'rgba(186,139,175,1)', - pointHoverBorderColor: 'rgba(186,139,175,1)', + label: await translate('[[admin/settings/activitypub:analytics.received]]'), + backgroundColor: 'rgba(161,181,108,0.2)', + borderColor: 'rgba(161,181,108,1)', + pointBackgroundColor: 'rgba(161,181,108,1)', + pointHoverBorderColor: 'rgba(161,181,108,1)', data: ajaxify.data.received, }, + { + ...commonDataSetOpts, + label: await translate('[[admin/settings/activitypub:analytics.errors]]'), + backgroundColor: 'rgba(171,70,66,0.2)', + borderColor: 'rgba(171,70,66,1)', + pointBackgroundColor: 'rgba(171,70,66,1)', + pointHoverBorderColor: 'rgba(171,70,66,1)', + data: ajaxify.data.receivedErr, + }, ], }, 'sent': { @@ -92,6 +105,7 @@ function initializeCharts() { datasets: [ { ...commonDataSetOpts, + label: await translate('[[admin/settings/activitypub:analytics.sent]]'), backgroundColor: 'rgba(151,187,205,0.2)', borderColor: 'rgba(151,187,205,1)', pointBackgroundColor: 'rgba(151,187,205,1)', @@ -113,6 +127,11 @@ function initializeCharts() { beginAtZero: true, }, }, + plugins: { + legend: { + position: 'bottom', + }, + }, }; return new Map([ diff --git a/src/controllers/admin/federation.js b/src/controllers/admin/federation.js index edb64de4c0..27704eaf27 100644 --- a/src/controllers/admin/federation.js +++ b/src/controllers/admin/federation.js @@ -68,15 +68,18 @@ federationController.analytics = async function (req, res) { method = 'getDailyStatsForSet'; count = 30; } - const set = host ? `activities:byHost:${host}` : 'activities'; + const receivedSet = host ? `activities:byHost:${host}` : 'activities'; + const receivedErrSet = host ? `ap.inErr:byHost:${host}` : 'ap.inErr'; const sentSet = host ? `ap.out:byHost:${host}` : 'ap.out'; - const received = await analytics[method](set, Date.now(), count); + const received = await analytics[method](receivedSet, Date.now(), count); + const receivedErr = await analytics[method](receivedErrSet, Date.now(), count); const sent = await analytics[method](sentSet, Date.now(), count); res.render('admin/federation/analytics', { title: '[[admin/menu:federation/analytics]]', instances, received, + receivedErr, sent, }); }; diff --git a/src/views/admin/federation/analytics.tpl b/src/views/admin/federation/analytics.tpl index 3d4d37a9ee..66ad37995c 100644 --- a/src/views/admin/federation/analytics.tpl +++ b/src/views/admin/federation/analytics.tpl @@ -31,7 +31,7 @@
-
[[admin/settings/activitypub:analytics.received]]
+
[[admin/settings/activitypub:analytics.in]]
@@ -42,7 +42,7 @@
-
[[admin/settings/activitypub:analytics.sent]]
+
[[admin/settings/activitypub:analytics.out]]