Files
mcp-wms-api/docs/logs.md
T
Arthur Ria 0ff44f7b78 Documentation : structure README / CLAUDE / DECISIONS / MONITORING
Nouveaux documents :
- README.md : porte d'entrée humaine, absente jusqu'ici. Objet du projet,
  installation, npm test, branchement Claude Desktop, ajout d'un profil WMS,
  compilation de l'exécutable.
- DECISIONS.md : 20 décisions et pièges vérifiés sur un WMS réel (D1..D20),
  chacun avec son pourquoi. Extrait ce qui était noyé dans CLAUDE.md :
  100 % API, tenant_code OAuth, réponses {entities}, casse des propriétés,
  dotenv sur stderr, dates relatives LINQ non traduisibles, absence de
  CommandParameterData, etc.
- MONITORING.md : supervision du serveur MCP. Préfixes de logs, séquence
  d'un démarrage sain, cycle de vie du token OAuth et ses trois filets,
  état des caches, table symptôme -> cause. Une section dit explicitement
  ce qui n'est pas instrumenté (ni healthcheck, ni métriques, ni alerte).
- docs/logs.md : accès aux logs du WMS. Chemins, placeholder {host},
  blocage volontaire sur les profils SaaS, les trois outils, format des
  lignes, limites connues.

Mises à jour :
- CLAUDE.md réécrit et aligné sur le code. Correction de l'écart le plus
  gênant : le code utilise QueryType 0 (Reading), la doc annonçait 1, soit
  l'inverse de ce qui fonctionne pour les comparaisons de statut par
  chaîne. Corrigés également : 6 resources et non 7 (workflows://categories
  n'existe pas), section .env mono-profil obsolète, références à des
  fichiers de test absents, README annoncé mais inexistant. Le suivi de
  projet et les checklists de phases sont retirés.
- docs/README.md : index réel du dossier. L'ancien promettait une resource
  docs:// qui n'a jamais existé.
- docs/getting_started.md : avertissement en tête, c'est une capture
  partielle du portail Mecalux dont les liens internes ne résolvent pas.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 15:15:31 +02:00

166 lines
6.0 KiB
Markdown

# Logs du WMS
Comment le serveur MCP accède aux fichiers de logs du WMS, ce qu'il sait faire
et ce qu'il ne peut pas faire.
Pour superviser **le serveur MCP lui-même**, voir
[MONITORING.md](../MONITORING.md).
---
## 1. Où sont les logs
Les logs sont lus **directement sur le système de fichiers** du serveur WMS,
via des partages réseau Windows — jamais par API.
| Emplacement | Contenu |
|---|---|
| `\\<host>\inetpub\logs\LogFiles\Mecalux` | logs applicatifs IIS, organisés en sous-dossiers par composant |
| `\\<host>\ProgramData\Mecalux\ETLLogs` | logs du middleware ETL |
Configuration dans `.env`, plusieurs chemins séparés par des `;` :
```env
LOGS_PATH=\\{host}\inetpub\logs\LogFiles\Mecalux;\\{host}\ProgramData\Mecalux\ETLLogs
```
**Le placeholder `{host}` est remplacé à chaque appel** par le host du profil
actif. Il n'y a donc pas de chemin de logs à redéfinir par profil : un seul
gabarit suffit, et il suit automatiquement `switch_wms_profile`.
Le scan est **récursif** et ne retient que les fichiers dont le nom se termine
par `.log`. Un dossier absent ou inaccessible n'interrompt pas le scan : il est
journalisé (`[Logs] Cannot scan directory …`) et ignoré.
---
## 2. Prérequis d'accès
Les partages `\\<host>\...` doivent être joignables **depuis la machine qui
exécute le serveur MCP**, avec les droits de lecture du compte Windows courant.
Le serveur ne présente aucun credential propre pour SMB — il hérite de la
session Windows.
Vérification rapide, hors serveur MCP :
```bash
Test-Path "\\10.255.255.2\inetpub\logs\LogFiles\Mecalux"
```
Si cette commande renvoie `False`, aucun outil de log ne fonctionnera : le
problème est réseau ou droits, pas applicatif.
---
## 3. Profils SaaS : les logs ne sont pas accessibles
Quand le profil actif est déclaré `<PROFIL>_SAAS=true`, les trois outils de log
**échouent volontairement** avec :
> Log access is disabled for SaaS profile "X". The WMS is cloud-hosted — local
> log files are not reachable. Use the WMS API (query/command/workflow tools)
> instead.
C'est un choix explicite, pas une régression : le WMS est hébergé dans le cloud
Mecalux, son système de fichiers n'est pas exposé. Retourner « 0 fichier »
laisserait croire à une absence d'erreurs — un faux négatif dangereux en
diagnostic. Voir D9 dans [DECISIONS.md](../DECISIONS.md).
**Sur un profil SaaS, le diagnostic passe donc uniquement par les API** :
`query_wms_entities`, `count_wms_entities`, `search_wms_data`, les outils AD et
`get_system_parameters`.
---
## 4. Les trois outils
### `list_log_files`
Liste tous les `.log` trouvés sous `LOGS_PATH`, **triés du plus récent au plus
ancien**, avec taille, date de modification et dossier d'origine. Point de
départ naturel : il montre quels composants ont écrit récemment.
Si aucun fichier n'est trouvé, l'erreur **énumère les chemins scannés** — c'est
généralement suffisant pour diagnostiquer un `{host}` mal résolu.
### `read_recent_logs(count, log_file)`
Renvoie les `count` dernières lignes (100 par défaut). Sans `log_file`, prend
**le fichier le plus récemment modifié, tous dossiers confondus** — ce qui n'est
pas forcément celui que l'on croit sur un serveur multi-composants ; préférez
nommer le fichier.
La résolution de `log_file` se fait en trois passes, de la plus stricte à la
plus permissive :
1. chemin direct sous le premier `LOGS_PATH`
(ex. `ApplicationDictionary\ApplicationDictionary.log`) ;
2. nom exact recherché dans chaque sous-dossier immédiat ;
3. correspondance partielle, insensible à la casse.
En cas d'échec, l'erreur liste les fichiers disponibles.
### `search_logs(keyword, max_results, context_lines)`
Recherche insensible à la casse dans **tous** les fichiers, du plus récent au
plus ancien, en s'arrêtant à `max_results` (50 par défaut). Chaque résultat
porte son fichier, son numéro de ligne et `context_lines` lignes avant/après (2
par défaut), la ligne trouvée étant marquée `isMatch`.
C'est l'outil à privilégier pour tracer un identifiant métier (numéro de
commande, code produit, id de tâche) à travers les composants.
---
## 5. Format des lignes
`ApplicationService.log` suit ce format :
```
YYYY-MM-DD HH:MM:SS.ffff [thread] [Level] [Component] [message]
```
Exemple :
```
2026-08-24 09:14:22.1873 [42] [ERROR] [OutboundOrderService] [Order 4711 not found]
```
Conséquence pratique : une recherche par **date préfixe** (`2026-08-24 09:`)
fonctionne bien, et le niveau se filtre par `[ERROR]` — crochets inclus, pour
éviter les faux positifs sur le mot « error » dans un message.
Les logs ETL n'ont pas le même format ; ne présumez pas d'une structure commune
entre les deux emplacements.
---
## 6. Limites à connaître
- **Lecture intégrale en mémoire.** `read_recent_logs` et `search_logs`
chargent chaque fichier entier avant de le découper. Sur un log de plusieurs
centaines de Mo, c'est lent et coûteux en RAM. Vérifiez les tailles avec
`list_log_files` avant de lancer une recherche large.
- **Recherche par sous-chaîne uniquement**, pas d'expression régulière.
- **Pas de filtre temporel** : `search_logs` ne sait pas restreindre à une
plage horaire. Le contournement est d'inclure le préfixe de date dans le
mot-clé.
- **Aucun filtre de nom de fichier configurable.** Le scan retient tous les
`.log`. (Une variable `LOG_FILE_PATTERN` a existé dans `.env` sans jamais
être appliquée ; elle a été supprimée — voir D20.)
- **Pas de rotation ni de purge** : le serveur MCP lit, il n'écrit ni ne
supprime rien.
---
## 7. Hors périmètre : l'historique des shipment templates
Les logs `ApplyShipmentTemplates` **ne sont pas présents** sur l'hôte joignable
(`10.255.255.2`) : ils résident sur les serveurs de production / ETL des
clients. Aucun outil ne les analyse, car il n'y aurait rien à lire.
Ce que l'on peut obtenir par API se limite à la **dernière** exécution, via
l'entité Reading `ShipmentTemplate` (`LastExecuteDate`, `Status`,
`IsEnabled`). Voir D16 dans [DECISIONS.md](../DECISIONS.md) et les recettes de
la resource `wms://query-examples`.