Protocol 15: one shared session log on the server, chat never logged, Mark a problem
Every app streams its redacted diagnostic lines (server time, batched every 10 s, gzip, buffered while offline) to POST /l/; the server merges them with its own into session-YYYY-MM-DD.log in time order, tagged by who. Opt-out in Settings > About; Mark a problem (Ctrl+Shift+B, the player menus, About) writes a marker with an optional note. Copy diagnostics can include the server's session log. Chat text never reaches any log. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4ab37c55cf
commit
7487b4deb1
29 files changed
+1380
-47
No files matched your search
@@ -11,6 +11,7 @@ import 'media_endpoint.dart';
|
||||
import 'relay_routes.dart';
|
||||
import 'server_hub.dart';
|
||||
import 'session.dart';
|
||||
import 'session_log.dart';
|
||||
|
||||
/// [configured], else systemd's `$STATE_DIRECTORY/yt-dlp`, else `yt-dlp`
|
||||
/// next to the server binary when that is writable (not under `dart run`),
|
||||
@@ -56,8 +57,16 @@ class SyncServer {
|
||||
/// IPv4 interface.
|
||||
final bool loopbackOnly;
|
||||
|
||||
/// The folder of the session log (`session-YYYY-MM-DD.log`, every
|
||||
/// member's diagnostics and the server's records merged); null: none.
|
||||
final String? logDir;
|
||||
SessionLog? _sessionLog;
|
||||
|
||||
/// The session log while running with a [logDir].
|
||||
SessionLog? get sessionLog => _sessionLog;
|
||||
|
||||
/// [ytDlp] replaces the server's own (tests).
|
||||
SyncServer(this.config, {YtDlp? ytDlp, this.loopbackOnly = false}) {
|
||||
SyncServer(this.config, {YtDlp? ytDlp, this.loopbackOnly = false, this.logDir}) {
|
||||
hub = ServerHub(sessions, config.secret,
|
||||
hostKey: config.hostKey,
|
||||
jellyfin: config.jellyfin,
|
||||
@@ -103,6 +112,7 @@ class SyncServer {
|
||||
mountRelayRoutes(_app, sessions, relayAt: hub.relayAt, sourceOf: hub.sourceOf, onLog: logRequest);
|
||||
mountAvatarRoute(_app, hub);
|
||||
mountArtRoute(_app, hub);
|
||||
mountSessionLogRoutes(_app, hub, () => _sessionLog);
|
||||
mountJellyfinRelayRoute(
|
||||
_app, sessions, () => hub.jellyfin, () => _relayClient ??= HttpClient(),
|
||||
next: () => hub.nextJellyfinRef, onLog: logRequest);
|
||||
@@ -139,6 +149,14 @@ class SyncServer {
|
||||
if (config.secret.isEmpty) {
|
||||
_log.warning('no password set: open server, anyone who can reach it can join');
|
||||
}
|
||||
final dir = logDir;
|
||||
if (dir != null && _sessionLog == null) {
|
||||
try {
|
||||
_sessionLog = SessionLog(dir)..captureOwn();
|
||||
} catch (e) {
|
||||
_log.warning('no session log: cannot write $dir ($e)');
|
||||
}
|
||||
}
|
||||
await _resolveJellyfinServerId();
|
||||
_mountRoutes();
|
||||
_server = await _app.serve(
|
||||
@@ -158,6 +176,7 @@ class SyncServer {
|
||||
hub.sampleRates();
|
||||
hub.broadcastState();
|
||||
hub.broadcastFeed();
|
||||
_sessionLog?.flush();
|
||||
});
|
||||
_log.info('server "${config.name}" listening on $boundPort');
|
||||
}
|
||||
@@ -193,5 +212,7 @@ class SyncServer {
|
||||
await _app.close();
|
||||
_server = null;
|
||||
_log.info('server "${config.name}" stopped');
|
||||
await _sessionLog?.close();
|
||||
_sessionLog = null;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user