26 KiB
Marche à suivre — Mise en production Omika Diagnostics (V2)
Objet : procédure complète et à jour de mise en production de la chaîne Diagnostics, tenant compte du premier déploiement d'il y a deux semaines (DiagnosticsWorker + DiagnosticsWeb + schéma
001→004/005) et de tous les changements intervenus depuis : API centraleOmika.Diagnostics.Api(T19), tablesdiagnostics_clients/diagnostics_users/diagnostics_reference/diagnostics_tasks, rétention télémétrie + erreurs non traitées, suppression de groupes d'erreurs, etc.Cible : Windows Server 2025
SRV-OMIKA, PowerShell administrateur, PostgreSQL 18, runtime .NET 10 (hébergement).Ce document remplace
MISE_A_JOUR_DIAGNOSTICS_SRV-OMIKA.md(qui s'arrêtait à011) et complèteT15-RUNBOOK-DEPLOIEMENT-PRODUCTION.md(qui s'arrêtait à005).
0. Vue d'ensemble des projets Diagnostics
| Projet | Rôle | Référence |
|---|---|---|
Omika.Diagnostics.Core |
Modèles, abstractions de repository, import JSONL, validation. | — |
Omika.Diagnostics.Data |
Persistance Npgsql (pas d'ORM) + DI. | — |
Omika.Diagnostics.Worker |
Service d'import JSONL → PostgreSQL + rétention (OmikaDiagnosticsWorker). |
Windows Service |
Omika.Diagnostics.Web |
Service interface de consultation/admin (OmikaDiagnosticsWeb). |
Kestrel + service Windows |
Omika.Diagnostics.Api |
Service API centrale (T19), reçoit les lots des serveurs clients (OmikaDiagnosticsApi). |
Kestrel + service Windows |
Omika.Api |
API métier/mobile chez le client : POST /api/diagnostics + ServerDiagnosticMiddleware + forwarder central. |
Windows Service OmikaApi |
Omika.Worker |
Worker métier (sync) ; émet des diagnostics serveur et forwarde son propre spool si hébergé sur un autre serveur que l'API. | Windows Service OmikaWorker |
Omika.Observability.External |
Pont optionnel OpenTelemetry → Collector → SigNoz (hors chaîne Diagnostics). | — |
Omika.App* |
App mobile/desktop : outbox SQLite + uploader POST /api/diagnostics. |
— |
⚠️
Omika.slnxne référence pas les projets Diagnostics : on publie chaque.csprojdirectement (voir §2). La chaîne Diagnostics est indépendante du pont OpenTelemetry/SigNoz (Observability:External) — ne pas les confondre.
1. Ce qui a changé depuis le premier déploiement
- Nouveau service :
OmikaDiagnosticsApi(src/Omika.Diagnostics.Api) — API centrale multi-serveur. Non présent dans le premier déploiement. - Base de données fortement évoluée : migrations
005 → 016ajoutées (contexte client, appareil/licence, usage, registre clients, utilisateurs Web, référentiel, tâches de traitement, rétention télémétrie/erreurs, DELETE groupe). - Nouvelles tables :
diagnostics_clients,diagnostics_users,diagnostics_reference,diagnostics_tasks. - Nouveaux privilèges : rôle
omika_diagnostics_api(009) ; DELETE Web surdiagnostics_tasks(013) etdiagnostic_event(016) ; SELECT/DELETE worker surtelemetry_metric_hourly(014) ; SELECT colonne-ciblé worker surdiagnostics_tasks(015). - Nouvelles fonctionnalités Web :
/Clients,/Users,/Referentiel,/Taches, boutons « Supprimer » (tâche + groupe d'erreurs).
2. Prérequis
Poste DEV (publication)
cd D:\Avalonia\Omika
dotnet --version # SDK 10 (global.json épingle 10.0.302)
git pull # branche à jour
SRV-OMIKA (PowerShell administrateur)
net session # OK sinon STOP
dotnet --list-runtimes # Microsoft.AspNetCore.App 10.x
Get-Service postgresql* # Running
Test-Path 'C:\Program Files\PostgreSQL\18\bin\psql.exe'
Test-Path 'C:\Program Files\PostgreSQL\18\bin\pg_dump.exe'
3. Publication (poste DEV)
Script prêt :
scripts\publish-diagnostics.ps1(ajouter-IncludeCentralApi). Équivalent manuel ci-dessous.
cd D:\Avalonia\Omika
# 1. Omika.Api (métier + forwarder)
dotnet publish src\Omika.Api\Omika.Api.csproj `
-c Release -r win-x64 --self-contained false -o C:\Omika\Deploy\OmikaApi-next
# 2. Omika.Worker (sync métier)
dotnet publish src\Omika.Worker\Omika.Worker.csproj `
-c Release -r win-x64 --self-contained false -o C:\Omika\Deploy\OmikaWorker-next
# 3. Omika.Diagnostics.Worker (EnableWindowsService=true = défaut)
dotnet publish src\Omika.Diagnostics.Worker\Omika.Diagnostics.Worker.csproj `
-c Release -r win-x64 --self-contained false -o C:\Omika\Deploy\DiagnosticsWorker-next
# 4. Omika.Diagnostics.Web
dotnet publish src\Omika.Diagnostics.Web\Omika.Diagnostics.Web.csproj `
-c Release -r win-x64 --self-contained false -o C:\Omika\Deploy\DiagnosticsWeb-next
# 5. Omika.Diagnostics.Api (NOUVEAU — API centrale)
dotnet publish src\Omika.Diagnostics.Api\Omika.Diagnostics.Api.csproj `
-c Release -r win-x64 --self-contained false -o C:\Omika\Deploy\DiagnosticsApi-next
Contrôles : chaque dossier contient son .exe ; appsettings.Development.json
absent (ou jamais activé) ; aucun secret Dev dans les publications.
Transférer ensuite les 5 dossiers *-next vers C:\Omika\Deploy\ sur SRV-OMIKA.
4. Base de données — inventaire des migrations (001 → 016)
Ordre d'application strict sur SRV-OMIKA, en superuser (postgres), avec
ON_ERROR_STOP=1. Toutes sont idempotentes et non destructives.
| # | Fichier | Objet | Rôle(s) impacté(s) |
|---|---|---|---|
| 001 | 001_diagnostics_schema.sql |
diagnostic_event + telemetry_metric_hourly + dédup event_id |
— |
| 002 | 002_actor_key.sql |
colonnes actor_key/actor_key_version |
— |
| 003 | 003_diagnostics_roles.sql |
rôles owner(NOLOGIN)/worker/web + ownership + grants |
worker: INSERT ; web: SELECT |
| 004 | 004_diagnostics_retention.sql |
rétention bornée | worker: +SELECT+DELETE diagnostic_event |
| 005 | 005_diagnostics_client_context.sql |
colonnes client_code/server_instance/environment |
— |
| 006 | 006_diagnostics_device_license.sql |
colonnes appareil/licence | — |
| 007 | 007_diagnostics_usage.sql |
colonnes screen_code/feature_code |
— |
| 008 | 008_diagnostics_clients.sql |
table diagnostics_clients |
— |
| 009 | 009_diagnostics_clients_grants.sql |
rôle omika_diagnostics_api + grants clients |
api: SELECT + UPDATE(last_seen) ; web: SELECT/INSERT/UPDATE |
| 010 | 010_diagnostics_web_users.sql |
table diagnostics_users |
web: SELECT/INSERT/UPDATE |
| 011 | 011_diagnostics_reference.sql |
table diagnostics_reference + seed 29+3 |
web: SELECT/INSERT/UPDATE |
| 012 | 012_diagnostics_tasks.sql |
table diagnostics_tasks |
web: SELECT/INSERT/UPDATE |
| 013 | 013_diagnostics_tasks_delete.sql |
DELETE tâche | web: +DELETE diagnostics_tasks |
| 014 | 014_diagnostics_telemetry_retention.sql |
rétention télémétrie (180 j) | worker: +SELECT+DELETE telemetry_metric_hourly |
| 015 | 015_diagnostics_retention_untreated.sql |
ne pas purger les erreurs non traitées | worker: +SELECT(2 col.) diagnostics_tasks |
| 016 | 016_diagnostics_event_delete.sql |
suppression d'un groupe d'erreurs | web: +DELETE diagnostic_event |
⚠️
003_diagnostics_roles_preprod.sqlconcerne uniquement la préproduction : ne jamais l'appliquer en Production.
Récapitulatif des privilèges par rôle (après 016)
| Rôle (LOGIN) | Service | Privilèges |
|---|---|---|
omika_diagnostics_worker |
Diagnostics.Worker | diagnostic_event INSERT/SELECT/DELETE ; telemetry_metric_hourly SELECT/DELETE ; diagnostics_tasks SELECT(group_url_identifier,status) |
omika_diagnostics_web |
Diagnostics.Web | diagnostic_event SELECT/DELETE ; diagnostics_clients SELECT/INSERT/UPDATE(cols) ; diagnostics_users SELECT/INSERT/UPDATE(cols) ; diagnostics_reference SELECT/INSERT/UPDATE(cols) ; diagnostics_tasks SELECT/INSERT/UPDATE(cols)/DELETE |
omika_diagnostics_api |
Diagnostics.Api | diagnostics_clients SELECT + UPDATE(last_seen_at_utc) uniquement |
5. Marche à suivre détaillée (fenêtre de maintenance)
5.1 Audit (lecture seule) — déterminer les migrations déjà appliquées
$env:PGPASSWORD = '<SECRET_POSTGRES_ADMIN>'
$psql = 'C:\Program Files\PostgreSQL\18\bin\psql.exe'
& $psql -h 127.0.0.1 -p 5432 -U postgres -d omika_diagnostics -c `
"SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_name LIKE 'diagnostic%' ORDER BY 1;"
& $psql -h 127.0.0.1 -p 5432 -U postgres -d omika_diagnostics -c `
"SELECT column_name FROM information_schema.columns WHERE table_name='diagnostic_event' ORDER BY ordinal_position;"
& $psql -h 127.0.0.1 -p 5432 -U postgres -d omika_diagnostics -c `
"SELECT rolname FROM pg_roles ORDER BY rolname;"
Remove-Item Env:PGPASSWORD
Repères : diagnostic_event=001 ; actor_key=002 ; rôles owner/worker/web=003 ;
client_code=005 ; diagnostics_clients=008 ; rôle omika_diagnostics_api=009 ;
diagnostics_users=010 ; diagnostics_reference=011 ; diagnostics_tasks=012.
5.2 Backup PostgreSQL (AVANT toute migration)
$env:PGPASSWORD = '<SECRET_POSTGRES_ADMIN>'
$stamp = Get-Date -Format 'yyyyMMdd_HHmm'
$out = "C:\Omika\Backups\omika_diagnostics_${stamp}_before_upgrade.backup"
& 'C:\Program Files\PostgreSQL\18\bin\pg_dump.exe' `
-h 127.0.0.1 -p 5432 -U postgres -d omika_diagnostics -F c -v -f $out
Remove-Item Env:PGPASSWORD
Get-Item $out | Select-Object Name,Length # taille > 0 sinon NO-GO
5.3 Backup des binaires (AVANT remplacement)
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$root = 'C:\Omika\Backups'
Copy-Item 'C:\Omika\Apps\OmikaApi' -Destination "$root\OmikaApi_${stamp}" -Recurse -Force
Copy-Item 'C:\Omika\Apps\OmikaWorker' -Destination "$root\OmikaWorker_${stamp}" -Recurse -Force
Copy-Item 'C:\Omika\Apps\DiagnosticsWorker' -Destination "$root\DiagnosticsWorker_${stamp}" -Recurse -Force
Copy-Item 'C:\Omika\Apps\DiagnosticsWeb' -Destination "$root\DiagnosticsWeb_${stamp}" -Recurse -Force
# DiagnosticsApi : nouveau — backup seulement s'il existe déjà
if (Test-Path 'C:\Omika\Apps\DiagnosticsApi') { Copy-Item 'C:\Omika\Apps\DiagnosticsApi' -Destination "$root\DiagnosticsApi_${stamp}" -Recurse -Force }
5.4 Arrêt des services (ordre : figer la lecture, puis les écrivains)
Stop-Service OmikaDiagnosticsWeb -Force
Stop-Service OmikaApi -Force
Stop-Service OmikaWorker -Force
Stop-Service OmikaDiagnosticsWorker -Force
# OmikaDiagnosticsApi : à arrêter aussi s'il existait déjà
Stop-Service OmikaDiagnosticsApi -Force -ErrorAction SilentlyContinue
Get-Service OmikaApi,OmikaWorker,OmikaDiagnosticsWorker,OmikaDiagnosticsWeb,OmikaDiagnosticsApi |
Select-Object Name,Status
5.5 Migrations (UNIQUEMENT les manquantes, dans l'ordre, TOUJOURS avant les binaires)
$env:PGPASSWORD = '<SECRET_POSTGRES_ADMIN>'
$psql = 'C:\Program Files\PostgreSQL\18\bin\psql.exe'
$db = 'C:\Omika\Deploy\DiagnosticsDatabase' # dossier contenant les .sql livrés
$migrations = @(
'001_diagnostics_schema.sql','002_actor_key.sql','003_diagnostics_roles.sql',
'004_diagnostics_retention.sql','005_diagnostics_client_context.sql',
'006_diagnostics_device_license.sql','007_diagnostics_usage.sql',
'008_diagnostics_clients.sql','009_diagnostics_clients_grants.sql',
'010_diagnostics_web_users.sql','011_diagnostics_reference.sql',
'012_diagnostics_tasks.sql','013_diagnostics_tasks_delete.sql',
'014_diagnostics_telemetry_retention.sql','015_diagnostics_retention_untreated.sql',
'016_diagnostics_event_delete.sql'
)
foreach ($m in $migrations) {
$f = Join-Path $db $m
if (-not (Test-Path $f)) { Write-Host "ABSENT : $m" ; continue }
Write-Host "Application : $m ..."
& $psql -h 127.0.0.1 -p 5432 -U postgres -d omika_diagnostics -v ON_ERROR_STOP=1 -f $f
if ($LASTEXITCODE -ne 0) { throw "ÉCHEC sur $m (exit $LASTEXITCODE). STOP." }
}
Remove-Item Env:PGPASSWORD
Règle d'ordre : migration avant binaires (colonnes/tables additives ; anciens binaires restent compatibles, l'inverse échouerait). Idempotence ⇒ réappliquer une migration déjà en place est un no-op (sauf 003 : ne pas rejouer l'ownership inutilement si les rôles existent déjà).
5.6 Mots de passe des rôles LOGIN (manuel, jamais en script/log)
Après 003/009 :
\password omika_diagnostics_worker
\password omika_diagnostics_web
\password omika_diagnostics_api # nouveau rôle (009) — pour DiagnosticsApi
5.7 Copie des binaires (préserve la config serveur existante)
robocopy 'C:\Omika\Deploy\OmikaApi-next' 'C:\Omika\Apps\OmikaApi' /E /XF appsettings.json appsettings.Production.json web.config
robocopy 'C:\Omika\Deploy\OmikaWorker-next' 'C:\Omika\Apps\OmikaWorker' /E /XF appsettings.json appsettings.Production.json web.config
robocopy 'C:\Omika\Deploy\DiagnosticsWorker-next' 'C:\Omika\Apps\DiagnosticsWorker' /E /XF appsettings.json appsettings.Production.json web.config
robocopy 'C:\Omika\Deploy\DiagnosticsWeb-next' 'C:\Omika\Apps\DiagnosticsWeb' /E /XF appsettings.json appsettings.Production.json web.config
robocopy 'C:\Omika\Deploy\DiagnosticsApi-next' 'C:\Omika\Apps\DiagnosticsApi' /E /XF appsettings.json appsettings.Production.json web.config
robocopy 'C:\Omika\Deploy\LanguesApi-next' 'C:\Omika\Apps\LanguesApi' /E /XF appsettings.json appsettings.Production.json web.config
Ne jamais supprimer :
C:\Omika\Data\Api\Diagnostics\Jsonl\**,C:\Omika\Data\DiagnosticsWorker\Checkpoint\import-checkpoint.json,C:\Omika\Config\**, certificats TLS, variables d'environnement MACHINE.
5.8 Création du service OmikaDiagnosticsApi (NOUVEAU)
Le service n'existe pas encore : le créer (compte dédié, jamais LocalSystem) :
$cred = Get-Credential -UserName '.\svc_omika_diagapi' -Message 'Compte service OmikaDiagnosticsApi'
New-Service -Name 'OmikaDiagnosticsApi' -DisplayName 'Omika Diagnostics Api' `
-BinaryPathName '"C:\Omika\Apps\DiagnosticsApi\Omika.Diagnostics.Api.exe"' `
-Credential $cred -StartupType Manual
# ACL dossier spool central + logs
icacls 'C:\ProgramData\Omika\Diagnostics\Central' /grant:r 'svc_omika_diagapi:(OI)(CI)M'
icacls 'C:\Omika\Logs\DiagnosticsApi' /grant:r 'svc_omika_diagapi:(OI)(CI)M'
Le compte dédié doit avoir le droit « Ouvrir une session en tant que service ». Ce service se crée par le script dédié
infra\deploy\Install-OmikaDiagnosticsApi.ps1(compte, ACL du spool central, droit de connexion,-WhatIf,-Desinstaller). L'orchestrateurInstall-OmikaServices.ps1l'inclut par défaut — utilisez-SansDiagnosticsApipour l'exclure sur un serveur mono-serveur, où il est inutile.
6. Configuration serveur par service (secrets injectés SUR LE SERVEUR)
Règle : en variable d'environnement, : devient __
(Diagnostics:Central:Directory ⇔ Diagnostics__Central__Directory).
ConnectionStrings:DiagnosticsDatabase prime sur Diagnostics:ConnectionString.
Toute modif de variable d'un service exige un redémarrage du service.
Omika.Api (OmikaApi) — émission + ingestion + forwarding
| Variable | Rôle |
|---|---|
ASPNETCORE_ENVIRONMENT |
Production (obligatoire) |
MobileAuth__SigningKey |
fail-fast en Prod (signature tokens mobile) |
DiagnosticsIdentity__HmacKey |
clé HMAC ActorKey/DeviceKey (≥256 bits Base64) |
DiagnosticDeployment__ClientCode |
CodeClient (sinon fallback HFSQL) |
DiagnosticDeployment__ServerInstanceId |
id d'instance (sinon MachineName) |
Observability__Remote__Directory |
dossier JSONL partagé (identique au Worker) |
Observability__ServerDiagnostics__Enabled |
true pour activer l'émission serveur 4xx/5xx/exceptions (voir §7) |
DiagnosticsForwarding__Enabled |
kill switch forwarder central (true/false) |
DiagnosticsForwarding__Endpoint |
URL centrale HTTPS (si forwarding) |
DiagnosticsForwarding__ApiKey |
clé d'accès centrale (secret) |
LicenseConnection__* / SyncConnection__* |
secrets HFSQL existants (non touchés) |
Omika.Worker (OmikaWorker)
| Variable | Rôle |
|---|---|
ASPNETCORE_ENVIRONMENT |
Production (obligatoire) |
DiagnosticDeployment__ClientCode |
CodeClient (sinon fallback HFSQL) |
DiagnosticDeployment__ServerInstanceId |
id d'instance (sinon MachineName) |
Observability__Remote__Directory |
dossier JSONL (voir note topologie ci-dessous) |
DiagnosticsForwarding__Enabled |
forwarder du Worker (true si serveur séparé de l'API) |
DiagnosticsForwarding__Endpoint |
URL centrale HTTPS (si forwarding Worker) |
DiagnosticsForwarding__ApiKey |
clé d'accès centrale (secret) |
| secrets HFSQL existants | non touchés |
Topologie serveur client :
- Même serveur que l'API :
Observability__Remote__Directory= dossier partagé avec l'API, lu parOmikaDiagnosticsWorker. LaisserDiagnosticsForwarding__Enabled=falsecôté Worker (l'API forwarde déjà ce dossier) → un seul forwarder sur le dossier partagé.- Serveur séparé de l'API :
Observability__Remote__Directory= dossier local au Worker (jamais un partage réseau) ; activerDiagnosticsForwarding__Enabled=true+Endpoint+ApiKey. Le Worker forwarde alors son propre spool vers le central (checkpointforwarder-checkpoint-worker.json, distinct de celui de l'API).
Omika.Diagnostics.Worker (OmikaDiagnosticsWorker)
| Variable | Défaut | Rôle |
|---|---|---|
ConnectionStrings__DiagnosticsDatabase |
— | Npgsql Username=omika_diagnostics_worker |
Observability__Remote__Directory |
"" |
dossier JSONL (identique à Omika.Api) |
Diagnostics__Import__CheckpointDirectory |
"" |
dossier checkpoint |
Diagnostics__Import__CheckpointFileName |
import-checkpoint.json |
nom checkpoint |
Diagnostics__RetentionDays |
60 |
rétention événements |
Diagnostics__TelemetryRetentionDays |
180 |
rétention télémétrie |
Diagnostics__RetentionIntervalHours |
24 |
fréquence purge |
Diagnostics__RetentionBatchSize |
1000 |
lot de purge |
Omika.Diagnostics.Web (OmikaDiagnosticsWeb)
| Variable | Rôle |
|---|---|
ASPNETCORE_ENVIRONMENT |
Production (default-deny) |
ConnectionStrings__DiagnosticsDatabase |
Npgsql Username=omika_diagnostics_web |
DiagnosticsAuth__Operators__* |
bootstrap temporaire (hash uniquement) puis retrait |
Omika.Diagnostics.Api (OmikaDiagnosticsApi) — NOUVEAU
| Variable | Défaut | Rôle |
|---|---|---|
ASPNETCORE_ENVIRONMENT |
— | Production |
ConnectionStrings__DiagnosticsDatabase |
— | Npgsql Username=omika_diagnostics_api |
Diagnostics__Central__Directory |
logs/diagnostics-central |
spool central (chemin explicite, ex. C:\ProgramData\Omika\Diagnostics\Central) |
Diagnostics__Central__MaxRequestBodyBytes |
524288 |
corps borné |
Diagnostics__Central__MaxEventsPerBatch |
100 |
événements max/lot |
7. Activer l'envoi des diagnostics (API Omika + application)
Trois flux distincts, tous opt-in :
7.1 Application (mobile/desktop) → Omika.Api
L'application écrit dans une outbox SQLite locale (omika-diagnostics.db, toujours
active). L'upload vers POST /api/diagnostics est désactivé avant inscription
(DiagnosticUploadOptions.Enabled=false) puis activé automatiquement dès que
l'utilisateur s'inscrit (QR ou code manuel), sur toutes les plateformes
(Android, iOS, Desktop).
- Activation automatique : à l'inscription réussie, l'application écrit elle-même
le fichier
diagnostics-upload.jsondans le dossier de données de l'app (%LocalAppData%\Omika\) :et active l'upload en mémoire pour la session courante (reprise sous ~60 s). Champs optionnels :{ "Enabled": true }Interval,Timeout,BatchSize,MaxBatchBytes,EndpointPath. - Appareils déjà inscrits (avant cette version) : le fichier est migré au démarrage si la session est inscrite et que le fichier n'existe pas encore.
- Kill-switch support : poser manuellement
{ "Enabled": false }dans ce fichier désactive l'upload ; un fichier existant n'est jamais écrasé par la restauration de session. - L'app envoie vers l'
OmikaApidéjà configuré (BaseUrl + token de session) : aucun endpoint/secret supplémentaire. - Token absent → aucun envoi, données conservées (reprise au prochain contexte).
⚠️ Point d'attention : l'upload ne s'exécute que lorsque l'app est active (aucun job OS en arrière-plan) et exige un token de session valide.
7.2 Omika.Api → chaîne Diagnostics (diagnostics serveur)
Le ServerDiagnosticMiddleware capture 4xx/5xx/exceptions et les écrit dans le
JSONL remote (relu par OmikaDiagnosticsWorker). Désactivé par défaut.
Activation :
Observability__ServerDiagnostics__Enabled = true
Observability__Remote__Directory = <chemin JSONL partagé avec le Worker>
DiagnosticsIdentity__HmacKey = <clé HMAC>
DiagnosticDeployment__ClientCode = <CodeClient> (sinon HFSQL)
DiagnosticDeployment__ServerInstanceId = <id instance>
7.3 Serveur client → API centrale (multi-serveur uniquement)
Uniquement si vous recevez des diagnostics de serveurs clients distants :
- Dans
OmikaDiagnosticsWeb→ Clients Diagnostics → Nouveau client (CodeClient exact), créer puis copier immédiatement la clé. - Sur le serveur client, dans
OmikaApi:DiagnosticsForwarding__Enabled = true DiagnosticsForwarding__Endpoint = https://<central>/api/v1/diagnostics/batches DiagnosticsForwarding__ApiKey = <clé copiée> - Si
OmikaWorkerest sur un AUTRE serveur queOmikaApi, activer AUSSI le forwarding sur le Worker (même clé ou clé du client Worker, checkpoints distincts) :Chaque service forwarde alors son propre dossier JSONL local. Sur un même serveur (dossier partagé), n'activer qu'un seul forwarder (l'API) pour éviter le double envoi.# sur le serveur du Worker DiagnosticsForwarding__Enabled = true DiagnosticsForwarding__Endpoint = https://<central>/api/v1/diagnostics/batches DiagnosticsForwarding__ApiKey = <clé copiée> Observability__Remote__Directory= <dossier LOCAL au Worker> - Redémarrer
OmikaApi(etOmikaWorkerle cas échéant), puis vérifierlast_seen_at_utcdans Clients Diagnostics.
Sur un SRV-OMIKA mono-serveur (Omika.Api écrit le JSONL localement), l'API centrale
OmikaDiagnosticsApiet le forwarding ne sont pas nécessaires.
8. Redémarrage + smoke tests
8.1 Ordre de redémarrage (consommateurs avant producteurs)
Start-Service OmikaDiagnosticsWorker # 1. importeur (consommateur JSONL)
Start-Service OmikaDiagnosticsWeb # 2. UI
Start-Service OmikaDiagnosticsApi # 3. API centrale (si multi-serveur)
Start-Service OmikaWorker # 4. sync métier
Start-Service OmikaApi # 5. API (producteur, dernier)
Get-Service OmikaApi,OmikaWorker,OmikaDiagnosticsWorker,OmikaDiagnosticsWeb,OmikaDiagnosticsApi |
Select-Object Name,Status
8.2 Smoke tests
Invoke-WebRequest 'http://127.0.0.1:<PORT_API>/health' -UseBasicParsing # 200 Healthy
Invoke-WebRequest 'http://127.0.0.1:<PORT_WEB>/Login' -UseBasicParsing # 200
Invoke-WebRequest 'http://127.0.0.1:<PORT_DIAG_API>/' -UseBasicParsing # 200 {status:ok}
SQL post-redémarrage :
SELECT count(*) FROM diagnostic_event;
SELECT max(ingested_at_utc) FROM diagnostic_event;
SELECT reference_type, count(*) FROM diagnostics_reference GROUP BY reference_type;
-- attendu : SCREEN_CODE = 29, FEATURE_CODE = 3
SELECT count(*) FROM diagnostics_tasks;
Dans OmikaDiagnosticsWeb, vérifier : Dashboard, Diagnostics, Erreurs (bouton
« Supprimer le groupe »), Traces, Synchronisation, Telemetry, Versions,
Référentiel, Taches (bouton « Supprimer »), et /Clients + /Users (Admin).
9. Écarts constatés (scripts/documents à mettre à jour)
infra\deploy\Install-OmikaServerFiles.ps1: ne copie que 4 publications (OmikaApi, OmikaWorker, DiagnosticsWorker, DiagnosticsWeb) → ne déploie pasDiagnosticsApi.RÉSOLU : un script par déploiement dansinfra\deploy\Install-OmikaServices.ps1: ne crée que 4 services → ne crée pasOmikaDiagnosticsApini ses ACL (spool central/logs).infra\deploy(Install-OmikaDiagnosticsApi.ps1incluse), et l'orchestrateur les enchaîne dans le bon ordre (le propriétaire d'un dossier est installé avant ses lecteurs, pour que les ACL inter-services puissent être posées).infra\deploy\Install-DatabaseSchema.ps1: n'applique que001+002.Harden-DatabaseRoles.ps1: n'applique que003. Les migrations004 → 016restent manuelles (cette marche à suivre les couvre).Omika.slnxne référence pas les projets Diagnostics (build par.csproj).- App : l'activation de l'upload est désormais automatique dès l'inscription
(fichier
diagnostics-upload.jsonécrit par l'app elle-même ; kill-switch support via{ "Enabled": false }). Corrigé au passage : le fichier était nommédevelopment-upload.jsonet documenté à tort comme « compilé hors Release ». - Docs obsolètes :
MISE_A_JOUR_DIAGNOSTICS_SRV-OMIKA.md(→011) etT15-RUNBOOK-DEPLOIEMENT-PRODUCTION.md(→005).
Recommandation : mettre à jour les scripts 1–3 pour couvrir le 5ᵉ service et la
liste complète 001→016 (et générer le SHA256SUMS.txt incluant DiagnosticsApi).
10. Rollback
- Binaires : restaurer les dossiers
C:\Omika\Backups\*_<stamp>(arrêt → copie → démarrage dans l'ordre §8.1). - Base : pas de rollback SQL automatique (migrations additives/idempotentes).
pg_restore(backup §5.2) uniquement sur décision humaine explicite. - Kill switch :
DiagnosticsForwarding__Enabled=false(+ redémarrage OmikaApi) coupe tout envoi central sans toucher au métier ni au spool.