mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-05-07 02:27:22 +02:00
feat: track and show sent activities as well
This commit is contained in:
@@ -66,5 +66,7 @@
|
||||
"content.world-default-cid": "Default category ID for "World" page composer",
|
||||
|
||||
"analytics.intro": "From this page you can view the state of your instance's federation with other servers",
|
||||
"analytics.activities": "Received Activities"
|
||||
"analytics.by-hostname": "Filter by Hostname",
|
||||
"analytics.activities": "Received Activities",
|
||||
"analytics.sent": "Sent Activites"
|
||||
}
|
||||
@@ -27,17 +27,20 @@ export function init() {
|
||||
const hostFilterEl = document.getElementById('hostFilter');
|
||||
if (hostFilterEl) {
|
||||
hostFilterEl.addEventListener('change', async function () {
|
||||
const { activities } = await get(`/api${ajaxify.data.url}?host=${this.value}`);
|
||||
const chart = charts.get('activities');
|
||||
chart.data.datasets[0].data = activities;
|
||||
chart.update();
|
||||
const data = await get(`/api${ajaxify.data.url}?host=${this.value}`);
|
||||
|
||||
['activities', 'sent'].forEach((name) => {
|
||||
const chart = charts.get(name);
|
||||
chart.data.datasets[0].data = data[name];
|
||||
chart.update();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function initializeCharts() {
|
||||
const activitiesCanvas = document.getElementById('activities');
|
||||
// const dailyCanvas = document.getElementById('pageviews:daily');
|
||||
const sentCanvas = document.getElementById('sent');
|
||||
// const topicsCanvas = document.getElementById('topics:daily');
|
||||
// const postsCanvas = document.getElementById('posts:daily');
|
||||
const hourlyLabels = utils.getHoursArray().map(function (text, idx) {
|
||||
@@ -73,19 +76,19 @@ function initializeCharts() {
|
||||
},
|
||||
],
|
||||
},
|
||||
// 'pageviews:daily': {
|
||||
// labels: dailyLabels,
|
||||
// datasets: [
|
||||
// {
|
||||
// ...commonDataSetOpts,
|
||||
// backgroundColor: 'rgba(151,187,205,0.2)',
|
||||
// borderColor: 'rgba(151,187,205,1)',
|
||||
// pointBackgroundColor: 'rgba(151,187,205,1)',
|
||||
// pointHoverBorderColor: 'rgba(151,187,205,1)',
|
||||
// data: ajaxify.data.analytics['pageviews:daily'],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
'sent': {
|
||||
labels: hourlyLabels,
|
||||
datasets: [
|
||||
{
|
||||
...commonDataSetOpts,
|
||||
backgroundColor: 'rgba(151,187,205,0.2)',
|
||||
borderColor: 'rgba(151,187,205,1)',
|
||||
pointBackgroundColor: 'rgba(151,187,205,1)',
|
||||
pointHoverBorderColor: 'rgba(151,187,205,1)',
|
||||
data: ajaxify.data.sent,
|
||||
},
|
||||
],
|
||||
},
|
||||
// 'topics:daily': {
|
||||
// labels: dailyLabels.slice(-7),
|
||||
// datasets: [
|
||||
@@ -115,7 +118,7 @@ function initializeCharts() {
|
||||
};
|
||||
|
||||
activitiesCanvas.width = $(activitiesCanvas).parent().width();
|
||||
// dailyCanvas.width = $(dailyCanvas).parent().width();
|
||||
sentCanvas.width = $(sentCanvas).parent().width();
|
||||
// topicsCanvas.width = $(topicsCanvas).parent().width();
|
||||
// postsCanvas.width = $(postsCanvas).parent().width();
|
||||
|
||||
@@ -135,14 +138,13 @@ function initializeCharts() {
|
||||
data: data.activities,
|
||||
options: chartOpts,
|
||||
})],
|
||||
['sent', new Chart(sentCanvas.getContext('2d'), {
|
||||
type: 'line',
|
||||
data: data.sent,
|
||||
options: chartOpts,
|
||||
})],
|
||||
]);
|
||||
|
||||
// new Chart(dailyCanvas.getContext('2d'), {
|
||||
// type: 'line',
|
||||
// data: data['pageviews:daily'],
|
||||
// options: chartOpts,
|
||||
// });
|
||||
|
||||
// new Chart(topicsCanvas.getContext('2d'), {
|
||||
// type: 'line',
|
||||
// data: data['topics:daily'],
|
||||
|
||||
@@ -381,6 +381,7 @@ ActivityPub._sendMessage = async function (uri, id, type, payload) {
|
||||
});
|
||||
|
||||
if (String(response.statusCode).startsWith('2')) {
|
||||
ActivityPub.record.send(payload.type, uri);
|
||||
ActivityPub.helpers.log(`[activitypub/send] Successfully sent ${payload.type} to ${uri}`);
|
||||
return true;
|
||||
}
|
||||
@@ -455,7 +456,9 @@ ActivityPub.send = async (type, id, targets, payload) => {
|
||||
}).catch(err => winston.error(err.stack));
|
||||
};
|
||||
|
||||
ActivityPub.record = async ({ id, type, actor }) => {
|
||||
ActivityPub.record = {};
|
||||
|
||||
ActivityPub.record.receipt = async ({ id, type, actor }) => {
|
||||
const now = Date.now();
|
||||
const { hostname } = new URL(actor);
|
||||
|
||||
@@ -466,6 +469,15 @@ ActivityPub.record = async ({ id, type, actor }) => {
|
||||
]);
|
||||
};
|
||||
|
||||
ActivityPub.record.send = async ({ type, target }) => {
|
||||
const { hostname } = new URL(target);
|
||||
|
||||
await Promise.all([
|
||||
ActivityPub.instances.log(hostname),
|
||||
analytics.increment(['ap.out', `ap.out:byType:${type}`, `ap.out:byHost:${hostname}`]),
|
||||
]);
|
||||
};
|
||||
|
||||
ActivityPub.buildRecipients = async function (object, options) {
|
||||
/**
|
||||
* - Builds a list of targets for activitypub.send to consume
|
||||
|
||||
@@ -269,7 +269,7 @@ Controller.postInbox = async (req, res) => {
|
||||
|
||||
try {
|
||||
await activitypub.inbox[method](req);
|
||||
await activitypub.record(req.body);
|
||||
await activitypub.record.receipt(req.body);
|
||||
await helpers.formatApiResponse(202, res);
|
||||
} catch (e) {
|
||||
helpers.formatApiResponse(500, res, e).catch(err => winston.error(err.stack));
|
||||
|
||||
@@ -61,11 +61,14 @@ federationController.analytics = async function (req, res) {
|
||||
host = undefined;
|
||||
}
|
||||
const set = host ? `activities:byHost:${host}` : 'activities';
|
||||
const sentSet = host ? `ap.out:byHost:${host}` : 'ap:out';
|
||||
const activities = await analytics.getHourlyStatsForSet(set, Date.now(), 24);
|
||||
const sent = await analytics.getHourlyStatsForSet(sentSet, Date.now(), 24);
|
||||
|
||||
res.render('admin/federation/analytics', {
|
||||
title: '[[admin/menu:federation/analytics]]',
|
||||
instances,
|
||||
activities,
|
||||
sent,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
|
||||
<div class="row settings m-0">
|
||||
<div id="spy-container" class="col-12 col-md-8 px-0 mb-4" tabindex="0">
|
||||
<div id="relays" class="mb-4">
|
||||
<p class="lead">[[admin/settings/activitypub:analytics.intro]]</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="fs-5 fw-bold tracking-tight settings-header mb-3">[[admin/settings/activitypub:analytics.activities]]</label>
|
||||
<p class="lead">[[admin/settings/activitypub:analytics.intro]]</p>
|
||||
|
||||
<label class="fs-5 fw-bold tracking-tight settings-header mb-3">[[admin/settings/activitypub:analytics.by-hostname]] ({instances.length})</label>
|
||||
<div class="mb-3">
|
||||
<select class="form-select" autocomplete="off" id="hostFilter">
|
||||
<option value="">All instances</option>
|
||||
@@ -17,8 +15,13 @@
|
||||
{{{ end }}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="mb-4">
|
||||
<div class="card">
|
||||
<div class="card-header">[[admin/settings/activitypub:analytics.activities]]</div>
|
||||
<div class="card-body">
|
||||
<div class="position-relative" style="aspect-ratio: 2;">
|
||||
<canvas id="activities" height="250"></canvas>
|
||||
@@ -26,6 +29,17 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<div class="card">
|
||||
<div class="card-header">[[admin/settings/activitypub:analytics.sent]]</div>
|
||||
<div class="card-body">
|
||||
<div class="position-relative" style="aspect-ratio: 2;">
|
||||
<canvas id="sent" height="250"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- IMPORT admin/partials/settings/toc.tpl -->
|
||||
|
||||
Reference in New Issue
Block a user