Merge pull request #463 from trails-cool/federation/logtape
feat(journal): surface Fedify logs via LogTape console sink
This commit is contained in:
commit
d13a0fcd18
5 changed files with 37 additions and 0 deletions
3
.github/workflows/cd-staging.yml
vendored
3
.github/workflows/cd-staging.yml
vendored
|
|
@ -131,6 +131,9 @@ jobs:
|
||||||
# rollout 12.2). FEDERATION_KEY_ENCRYPTION_KEY comes from the
|
# rollout 12.2). FEDERATION_KEY_ENCRYPTION_KEY comes from the
|
||||||
# SOPS env decrypted above; previews never set this flag.
|
# SOPS env decrypted above; previews never set this flag.
|
||||||
echo "FEDERATION_ENABLED=true"
|
echo "FEDERATION_ENABLED=true"
|
||||||
|
# Verbose Fedify logs during the soak (signature verification
|
||||||
|
# detail). Dial down to info once federation is proven out.
|
||||||
|
echo "FEDERATION_LOG_LEVEL=debug"
|
||||||
} >> infrastructure/staging.env
|
} >> infrastructure/staging.env
|
||||||
|
|
||||||
- name: Copy compose file + env to server
|
- name: Copy compose file + env to server
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
// 202 for activity types without a registered listener, which is
|
// 202 for activity types without a registered listener, which is
|
||||||
// exactly the "acknowledge and drop" the spec wants; the same applies
|
// exactly the "acknowledge and drop" the spec wants; the same applies
|
||||||
// to wrapped types we inspect and ignore (e.g. Undo(Like)).
|
// to wrapped types we inspect and ignore (e.g. Undo(Like)).
|
||||||
|
import { configure, getConsoleSink } from "@logtape/logtape";
|
||||||
import { createFederation, type Federation } from "@fedify/fedify";
|
import { createFederation, type Federation } from "@fedify/fedify";
|
||||||
import { Accept, Follow, Person, Reject, Undo } from "@fedify/fedify/vocab";
|
import { Accept, Follow, Person, Reject, Undo } from "@fedify/fedify/vocab";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
|
|
@ -96,8 +97,36 @@ async function findLocalPublicUserByIri(iri: URL | null): Promise<UserRow | null
|
||||||
}
|
}
|
||||||
|
|
||||||
let _federation: Federation<void> | null = null;
|
let _federation: Federation<void> | null = null;
|
||||||
|
let _logtapeConfigured = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fedify logs through LogTape, which is silent until configured — and
|
||||||
|
* an unconfigured LogTape means signature-verification failures (the
|
||||||
|
* single most debuggable federation problem) vanish without a trace.
|
||||||
|
* Routed to the console so docker logs / Loki pick them up alongside
|
||||||
|
* pino. Level via FEDERATION_LOG_LEVEL (default "info"; set "debug"
|
||||||
|
* to see per-request signature verification detail).
|
||||||
|
*/
|
||||||
|
function configureFederationLogging(): void {
|
||||||
|
if (_logtapeConfigured) return;
|
||||||
|
_logtapeConfigured = true;
|
||||||
|
const level = (process.env.FEDERATION_LOG_LEVEL ?? "info") as "debug" | "info" | "warning";
|
||||||
|
configure({
|
||||||
|
sinks: { console: getConsoleSink() },
|
||||||
|
loggers: [
|
||||||
|
{ category: "fedify", lowestLevel: level, sinks: ["console"] },
|
||||||
|
// LogTape's meta logger warns about itself; keep it quiet unless
|
||||||
|
// something is really wrong.
|
||||||
|
{ category: ["logtape", "meta"], lowestLevel: "warning", sinks: ["console"] },
|
||||||
|
],
|
||||||
|
}).catch(() => {
|
||||||
|
// configure() throws if something else configured LogTape first —
|
||||||
|
// fine, their sinks win.
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function buildFederation(): Federation<void> {
|
function buildFederation(): Federation<void> {
|
||||||
|
configureFederationLogging();
|
||||||
const federation = createFederation<void>({
|
const federation = createFederation<void>({
|
||||||
kv: new PostgresKvStore(),
|
kv: new PostgresKvStore(),
|
||||||
// Canonical origin so generated IRIs are correct behind the Caddy
|
// Canonical origin so generated IRIs are correct behind the Caddy
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fedify/fedify": "2.1.16",
|
"@fedify/fedify": "2.1.16",
|
||||||
"@js-temporal/polyfill": "^0.5.1",
|
"@js-temporal/polyfill": "^0.5.1",
|
||||||
|
"@logtape/logtape": "^2.0.5",
|
||||||
"@react-router/node": "catalog:",
|
"@react-router/node": "catalog:",
|
||||||
"@react-router/serve": "catalog:",
|
"@react-router/serve": "catalog:",
|
||||||
"@sentry/node": "catalog:",
|
"@sentry/node": "catalog:",
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ services:
|
||||||
# empty (flag off) so preview journals never emit federation traffic.
|
# empty (flag off) so preview journals never emit federation traffic.
|
||||||
FEDERATION_ENABLED: ${FEDERATION_ENABLED:-}
|
FEDERATION_ENABLED: ${FEDERATION_ENABLED:-}
|
||||||
FEDERATION_KEY_ENCRYPTION_KEY: ${FEDERATION_KEY_ENCRYPTION_KEY:-}
|
FEDERATION_KEY_ENCRYPTION_KEY: ${FEDERATION_KEY_ENCRYPTION_KEY:-}
|
||||||
|
FEDERATION_LOG_LEVEL: ${FEDERATION_LOG_LEVEL:-}
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "curl -sf http://localhost:3000/api/health || exit 1"]
|
test: ["CMD-SHELL", "curl -sf http://localhost:3000/api/health || exit 1"]
|
||||||
interval: 15s
|
interval: 15s
|
||||||
|
|
|
||||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
|
|
@ -209,6 +209,9 @@ importers:
|
||||||
'@js-temporal/polyfill':
|
'@js-temporal/polyfill':
|
||||||
specifier: ^0.5.1
|
specifier: ^0.5.1
|
||||||
version: 0.5.1
|
version: 0.5.1
|
||||||
|
'@logtape/logtape':
|
||||||
|
specifier: ^2.0.5
|
||||||
|
version: 2.1.1
|
||||||
'@react-router/node':
|
'@react-router/node':
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 7.16.0(react-router@7.16.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(typescript@6.0.3)
|
version: 7.16.0(react-router@7.16.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(typescript@6.0.3)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue