ProtoFlix

Documentation · Installer et exploiter

Santé et diagnostic

Santé, journaux, métriques, traces et diagnostics de l’administrateur.

Statut au 2026-11-05 (lot 1c) : implémentés et testés : /livez, /readyz (contrôle de la base), logs JSON avec correlation_id, trace_id et span_id, métriques HTTP, base de données, build et runtime sur l'écoute d'administration, traces OpenTelemetry exportables en OTLP/HTTP, pprof. Planifiés : métriques de lecture, de jobs, de scan et de workers (elles arrivent avec leurs domaines), diagnostics admin /api/v1/admin/*. Décision associée : ADR 0012.

L'observabilité fait partie du produit : un administrateur qui n'a jamais lu le code doit pouvoir comprendre pourquoi un titre démarre lentement, pourquoi un transcodage échoue et ce qui limite une session.

1. Santé

EndpointRôleAuthentification
GET /livezLe processus répond (pas de dépendance vérifiée)Aucune
GET /readyzPrêt à servir : base SQLite ouverte et accessible en écriture, migrations à jour, rôles démarrés. Sur un worker distant : coordinateur joignableAucune ; réponse minimale (ok / not ready), sans détail
GET /api/v1/server/infoNom, version publique de l'APIAucune ; aucune information sensible (pas de version FFmpeg, OS, chemins)
GET /api/v1/admin/healthÉtat détaillé des dépendances, stockages, accélérateursAdmin

/livez et /readyz ne doivent jamais renvoyer de détail exploitable par un attaquant.

2. Logs

  • log/slog avec gestionnaire JSON en production, texte en développement (PROTOFLIX_LOG_FORMAT).
  • Sortie sur stdout/stderr ; rotation et rétention déléguées à journald ou au pilote Docker (pas d'écriture de fichiers de log par le serveur en V1).
  • Niveaux : debug (développement), info (événements métier notables : démarrage, scan terminé, session démarrée/terminée), warn (dégradation récupérable : source injoignable, retry), error (échec nécessitant attention).
  • Champs communs : time, level, msg, correlation_id, trace_id et span_id (ajoutés automatiquement quand le contexte porte un span valide, implémenté) ; selon le contexte user_id (opaque), playback_session_id, job_id, job_type, library_id.
  • Correlation ID : X-Request-ID accepté depuis un proxy de confiance s'il est bien formé, sinon généré ; renvoyé dans la réponse et dans chaque erreur structurée (request_id), propagé aux jobs créés par la requête.
  • Redaction : voir docs/security/secrets-and-privacy.md §3. Jamais de jeton, cookie, mot de passe, corps d'authentification ; chemins système seulement dans les événements destinés à l'admin.

3. Métriques

Instrumentation OpenTelemetry, exposée au format Prometheus sur l'écoute d'administration (PROTOFLIX_ADMIN_ADDR, désactivée par défaut, typiquement 127.0.0.1:9096). Cette écoute n'a pas d'authentification : elle reste sur loopback ou sur un réseau privé, et n'est jamais publiée via le reverse proxy. Le serveur avertit au démarrage si elle écoute au-delà de loopback. L'écoute publique ne sert jamais /metrics (testé).

Règle de cardinalité : les labels ont des valeurs bornées et connues. Jamais de nom de fichier, chemin, titre, identifiant d'utilisateur, identifiant de session ou URL brute en label. Les routes HTTP sont étiquetées par le motif choisi par le routeur (/api/v1/items/{itemId}) ; toute requête non routée tombe sous l'unique valeur unmatched, et les méthodes inconnues sous _OTHER. Un test envoie des chemins arbitraires et vérifie que l'ensemble des labels reste borné.

Les noms ci-dessous sont ceux exposés en Prometheus. Implémentées (lot 1c) :

MétriqueTypeLabels
http_server_request_duration_secondshistogrammehttp_request_method, http_route, http_response_status_code (convention sémantique OpenTelemetry)
http_server_active_requestsjauge—
protoflix_db_write_wait_secondshistogramme— : attente de l'écrivain unique et de son verrou (BEGIN IMMEDIATE). C'est l'indicateur principal de l'ADR 0019
protoflix_db_write_duration_secondshistogramme— : durée pendant laquelle une transaction tient l'écrivain
protoflix_db_write_transactions_totalcompteuroutcome (committed, rolled_back, begin_failed, commit_failed)
protoflix_db_connections_in_usejaugepool (writer, reader)
protoflix_db_connections_waits_totalcompteurpool
protoflix_build_infojauge (toujours 1)version
protoflix_jobs_livejaugetype, state (queued, running, retry_wait)
protoflix_jobs_oldest_ready_age_secondsjaugetype : âge du plus vieux job prêt, c'est-à-dire la latence de la file
protoflix_jobs_finished_totalcompteurtype, state (terminal)
protoflix_jobs_attempt_duration_secondshistogrammetype, outcome (succeeded, failed, cancelled, released, lease_lost)
go_*, process_*diverscollecteurs Prometheus standard (mémoire, goroutines, GC, CPU, descripteurs)

Planifiées, à ajouter avec leur domaine (noms indicatifs) :

Métrique (nom indicatif)TypeLabels autorisés
protoflix_playback_sessions_activejaugemode (direct_play, remux, transcode), network (local, remote)
protoflix_playback_negotiation_duration_secondshistogrammemode
protoflix_playback_time_to_first_segment_secondshistogrammemode, accel (none, vaapi, qsv, nvenc…)
protoflix_playback_decisions_totalcompteurmode, reason (énumération fermée : video_codec, audio_codec, container, bitrate, resolution, subtitle_burn_in, hdr_tonemap, policy…)
protoflix_transcode_engine_start_duration_secondshistogrammeaccel
protoflix_transcode_speed_ratiohistogrammeaccel, video_codec_out
protoflix_engine_errors_totalcompteurcategory (driver, codec, filter, input, resource, timeout, crash)
protoflix_jobsjaugetype, state
protoflix_job_duration_secondshistogrammetype, outcome
protoflix_job_retries_totalcompteurtype
protoflix_job_queue_oldest_age_secondsjaugetype
protoflix_downloads_activejaugekind (http, bittorrent)
protoflix_private_storage_used_bytesjauge— (total, pas par compte)
protoflix_storage_source_statejauge (0/1)state (compte par état, pas par source)
protoflix_scan_files_totalcompteuroutcome (discovered, changed, removed_confirmed, error)
protoflix_disk_free_bytesjaugearea (data, cache, transcode)
protoflix_auth_failures_totalcompteurkind (password, quick_code, invitation, token)
label op sur les métriques d'écriture—énumération fermée (catalog, jobs, progress, auth…), quand ces domaines existeront
protoflix_db_size_bytesjaugefile (main, wal)
protoflix_workersjaugekind (local, remote), state (online, offline)
protoflix_worker_jobs_activejaugeworker (nom donné à l'enrôlement, nombre borné par l'administrateur), type
protoflix_job_leases_expired_totalcompteurtype, kind (local, remote)
protoflix_internal_api_requests_totalcompteurroute, status_class
protoflix_segment_relay_duration_secondshistogramme— (relais coordinateur → worker de transcodage distant)

L'état par source de bibliothèque (identifiant, chemin) est exposé dans le diagnostic admin, pas en métrique. Les métriques runtime Go standard (mémoire, goroutines, GC) sont incluses.

CPU, mémoire, I/O et GPU de l'hôte : relevés pour le diagnostic admin et le Resource Manager ; pour un monitoring complet de l'hôte, l'administrateur utilise ses propres outils (node_exporter, etc.).

4. Traces

  • OpenTelemetry Go, export désactivé par défaut : sans destination, les spans ne sont même pas enregistrés. Activation par PROTOFLIX_OTLP_ENDPOINT (OTLP/HTTP, par exemple http://collector:4318, /v1/traces ajouté si besoin) vers une destination choisie par l'administrateur. Un test vérifie qu'aucun span n'est produit sans destination, et que l'export atteint un collecteur configuré.
  • Implémenté : span serveur par requête API, nommé MÉTHODE /motif, en erreur pour les réponses 5xx. Les sondes /livez et /readyz ne sont pas tracées.
  • Spans principaux : requête API, décision de lecture, accès base (par requête nommée sqlc), création de job, exécution de job, lancement du moteur, génération du manifeste, premier segment disponible.
  • Propagation W3C traceparent acceptée seulement depuis les proxies de confiance (implémenté et testé) : un client direct ne peut pas choisir l'identifiant de trace.
  • Attributs interdits : jetons, cookies, corps, chemins complets, noms de fichiers.
  • Échantillonnage : 100 % quand l'export est activé (implémenté), ce qui convient au volume d'un foyer. Un échantillonnage configurable (par exemple 10 % des requêtes, 100 % des erreurs et des négociations de lecture) est planifié si le volume l'exige.

5. Diagnostics administrateur

Exposés sous /api/v1/admin/* (rôle admin) et dans l'espace admin du client web :

  • version et build du serveur, version du schéma, version de SQLite embarquée, taille de protoflix.db et du fichier -wal ;
  • workers enregistrés (local ou distant), version, capacités annoncées, dernier heartbeat, leases en cours ;
  • FFmpeg : version, options de compilation, encodeurs/décodeurs, et pour chaque accélérateur l'état détecté / expérimental / validé / non supporté (jamais « supporté » sur simple détection) ;
  • capacité de l'hôte : CPU, mémoire, GPU, charge ;
  • sources de bibliothèques : état (online, unavailable, permission_denied, io_error), dernière vue, chemin (admin uniquement) ;
  • sessions actives avec plan de lecture : ce qui est lu tel quel, copié, réencodé, et pourquoi (un fichier de bibliothèque privée apparaît comme « Contenu privé », sans titre) ;
  • occupation des quotas de bibliothèques privées par compte (volume seulement, jamais les fichiers) ; téléchargements en cours et en échec si le module est activé ;
  • jobs actifs, en échec, en dead-letter, avec erreur structurée et action de relance ;
  • erreurs récentes regroupées par catégorie ;
  • espace disque et quotas des répertoires ;
  • diagnostic de configuration (clés présentes, valeurs non sensibles, avertissements).

Le flux temps réel des sessions et jobs pour l'admin passe par SSE (ADR 0007).

6. Profilage

net/http/pprof (/debug/pprof/) est servi uniquement sur l'écoute d'administration, donc désactivé tant que PROTOFLIX_ADMIN_ADDR est vide, et jamais sur l'écoute publique (implémenté). Les profils sont enregistrés sur un routeur dédié, pas sur http.DefaultServeMux.

7. Critères d'acceptation (à transformer en tests)

  • Toute réponse d'erreur contient un request_id retrouvable dans les logs.
  • Aucune métrique n'a de label hors de la liste autorisée (test d'inventaire). Fait pour les routes HTTP ; inventaire complet à étendre avec chaque domaine.
  • Aucune ligne de log ne contient un jeton ou un cookie (test sur la sortie de la suite d'intégration).
  • /readyz passe à « non prêt » quand la base est arrêtée, et revient sans redémarrage.

Source : docs/operations/observability.md, dans le dépôt de ProtoFlix.