fix: add pages/admin/logs/ excluded by .gitignore logs/ rule

This commit is contained in:
dahoud
2026-04-09 10:00:59 +00:00
parent bcdf5c0338
commit 0dbbf445f0
2 changed files with 241 additions and 0 deletions

1
.gitignore vendored
View File

@@ -47,6 +47,7 @@ Thumbs.db
# Logs # Logs
*.log *.log
logs/ logs/
!src/main/resources/META-INF/resources/pages/admin/logs/
# Temporary files # Temporary files
*.tmp *.tmp

View File

@@ -0,0 +1,240 @@
<!DOCTYPE html>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
template="/templates/main-template.xhtml">
<ui:define name="title">Logs &amp; Monitoring - UnionFlow</ui:define>
<ui:define name="content">
<h:form id="formLogs">
<p:messages id="messages" showDetail="true" closable="true"/>
<!-- En-tête -->
<div class="card mb-3">
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
<div>
<h3 class="m-0">
<i class="pi pi-chart-bar text-primary mr-2"></i>
Logs &amp; Monitoring Système
</h3>
<p class="text-600 m-0 mt-2">Surveillance des logs système et audit financier</p>
</div>
<div class="flex gap-2 mt-2 md:mt-0">
<p:commandButton value="Actualiser"
icon="pi pi-refresh"
action="#{logsSystemeBean.actualiser}"
update="@form"
styleClass="ui-button-text"/>
</div>
</div>
</div>
<!-- Santé système -->
<div class="grid mb-3">
<div class="col-12 md:col-4" rendered="#{logsSystemeBean.santeSysteme != null}">
<div class="card text-center">
<p:tag value="#{logsSystemeBean.santeSysteme.get('status')}"
severity="#{logsSystemeBean.getSanteSeverity(logsSystemeBean.santeSysteme.get('status').toString())}"
styleClass="text-lg px-3 py-2"/>
<div class="text-600 text-sm mt-2">État du backend</div>
</div>
</div>
</div>
<!-- Tabs : Logs Système / Audit Finance / Anomalies -->
<p:tabView id="tabsLogs">
<!-- Tab 1 : Logs système -->
<p:tab title="Logs Système">
<!-- Barre de filtres -->
<div class="grid mb-3">
<div class="col-12 md:col-2">
<p:selectOneMenu value="#{logsSystemeBean.filtreLevel}"
styleClass="w-full"
placeholder="Niveau">
<f:selectItem itemLabel="Tous niveaux" itemValue=""/>
<f:selectItem itemLabel="ERROR" itemValue="ERROR"/>
<f:selectItem itemLabel="WARN" itemValue="WARN"/>
<f:selectItem itemLabel="INFO" itemValue="INFO"/>
<f:selectItem itemLabel="DEBUG" itemValue="DEBUG"/>
</p:selectOneMenu>
</div>
<div class="col-12 md:col-2">
<p:inputText value="#{logsSystemeBean.filtreSource}"
placeholder="Source"
styleClass="w-full"/>
</div>
<div class="col-12 md:col-2">
<p:inputText value="#{logsSystemeBean.motCle}"
placeholder="Mot-clé"
styleClass="w-full"/>
</div>
<div class="col-12 md:col-2">
<p:calendar value="#{logsSystemeBean.dateDebut}"
pattern="yyyy-MM-dd"
placeholder="Date début"
styleClass="w-full"/>
</div>
<div class="col-12 md:col-2">
<p:calendar value="#{logsSystemeBean.dateFin}"
pattern="yyyy-MM-dd"
placeholder="Date fin"
styleClass="w-full"/>
</div>
<div class="col-12 md:col-2 flex gap-1">
<p:commandButton icon="pi pi-filter"
title="Filtrer"
action="#{logsSystemeBean.appliquerFiltres}"
update="dtLogsSysteme"
styleClass="flex-auto"/>
<p:commandButton icon="pi pi-times"
title="Réinitialiser"
action="#{logsSystemeBean.reinitialiserFiltres}"
update="dtLogsSysteme"
styleClass="ui-button-secondary flex-auto"/>
</div>
</div>
<p:dataTable id="dtLogsSysteme"
var="log"
value="#{logsSystemeBean.logsSysteme}"
paginator="true"
rows="#{logsSystemeBean.taille}"
emptyMessage="Aucun log trouvé"
rowHover="true"
scrollable="true"
scrollWidth="100%">
<p:column headerText="Niveau" style="width:80px">
<p:tag value="#{log.get('level')}"
severity="#{logsSystemeBean.getLevelSeverity(log.get('level').toString())}"/>
</p:column>
<p:column headerText="Timestamp" style="width:160px">
#{log.get('timestamp')}
</p:column>
<p:column headerText="Source">
<span class="font-mono text-sm">#{log.get('source')}</span>
</p:column>
<p:column headerText="Message">
<div class="text-sm" style="max-width:400px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;"
title="#{log.get('message')}">
#{log.get('message')}
</div>
</p:column>
<p:column headerText="Utilisateur" style="width:120px">
#{log.get('userId')}
</p:column>
<p:column headerText="Session" style="width:120px">
<span class="font-mono text-xs">#{log.get('sessionId')}</span>
</p:column>
</p:dataTable>
</p:tab>
<!-- Tab 2 : Audit Finance -->
<p:tab title="Audit Finance">
<div class="grid mb-3">
<div class="col-12 md:col-2">
<p:inputText value="#{logsSystemeBean.filtreOperation}"
placeholder="Opération"
styleClass="w-full"/>
</div>
<div class="col-12 md:col-2">
<p:selectOneMenu value="#{logsSystemeBean.filtreSeverity}"
styleClass="w-full">
<f:selectItem itemLabel="Toutes sévérités" itemValue=""/>
<f:selectItem itemLabel="CRITICAL" itemValue="CRITICAL"/>
<f:selectItem itemLabel="HIGH" itemValue="HIGH"/>
<f:selectItem itemLabel="MEDIUM" itemValue="MEDIUM"/>
<f:selectItem itemLabel="LOW" itemValue="LOW"/>
</p:selectOneMenu>
</div>
<div class="col-12 md:col-2">
<p:calendar value="#{logsSystemeBean.dateDebut}"
pattern="yyyy-MM-dd"
placeholder="Date début"
styleClass="w-full"/>
</div>
<div class="col-12 md:col-2">
<p:calendar value="#{logsSystemeBean.dateFin}"
pattern="yyyy-MM-dd"
placeholder="Date fin"
styleClass="w-full"/>
</div>
<div class="col-12 md:col-4 flex gap-1">
<p:commandButton value="Charger l'audit"
icon="pi pi-filter"
action="#{logsSystemeBean.chargerLogsAuditFinance}"
update="dtAuditFinance messages"
styleClass="flex-auto"/>
<p:commandButton value="Anomalies"
icon="pi pi-exclamation-triangle"
action="#{logsSystemeBean.chargerAnomalies}"
update="dtAnomalies messages"
styleClass="ui-button-warning flex-auto"/>
</div>
</div>
<p:dataTable id="dtAuditFinance"
var="audit"
value="#{logsSystemeBean.logsAuditFinance}"
paginator="true"
rows="20"
emptyMessage="Chargez les logs via les filtres"
rowHover="true">
<p:column headerText="Opération">
<span class="font-mono text-sm">#{audit.get('operation')}</span>
</p:column>
<p:column headerText="Entité">#{audit.get('entityType')}</p:column>
<p:column headerText="Montant">
<h:outputText value="#{audit.get('amount')}" rendered="#{audit.get('amount') != null}">
<f:convertNumber type="currency" currencySymbol="FCFA " groupingUsed="true"/>
</h:outputText>
</p:column>
<p:column headerText="Sévérité">
<p:tag value="#{audit.get('severity')}"
severity="#{audit.get('severity') == 'CRITICAL' ? 'danger' : audit.get('severity') == 'HIGH' ? 'warning' : 'info'}"/>
</p:column>
<p:column headerText="Utilisateur">#{audit.get('userId')}</p:column>
<p:column headerText="Date">#{audit.get('timestamp')}</p:column>
</p:dataTable>
</p:tab>
<!-- Tab 3 : Anomalies -->
<p:tab title="Anomalies détectées (#{logsSystemeBean.anomalies.size()})">
<p:dataTable id="dtAnomalies"
var="anomalie"
value="#{logsSystemeBean.anomalies}"
paginator="true"
rows="20"
emptyMessage="Aucune anomalie détectée (chargez via l'onglet Audit Finance)"
rowHover="true">
<p:column headerText="Type">
<p:tag value="#{anomalie.get('type')}" severity="danger"/>
</p:column>
<p:column headerText="Description">#{anomalie.get('description')}</p:column>
<p:column headerText="Montant">
<h:outputText value="#{anomalie.get('amount')}" rendered="#{anomalie.get('amount') != null}">
<f:convertNumber type="currency" currencySymbol="FCFA " groupingUsed="true"/>
</h:outputText>
</p:column>
<p:column headerText="Score risque">
<p:knob value="#{anomalie.get('riskScore')}"
min="0" max="100"
rendered="#{anomalie.get('riskScore') != null}"
style="width:50px; height:50px;"/>
</p:column>
<p:column headerText="Date">#{anomalie.get('detectedAt')}</p:column>
</p:dataTable>
</p:tab>
</p:tabView>
</h:form>
</ui:define>
</ui:composition>