Logging centralisé (dynors-logging)
Objectif : montrer comment centraliser les logs (backend et frontend) d’un projet client grâce au module dynors-logging et à DynorsLogger.
1. Principe
dynors-loggingfournit une abstraction de logging :LoggingProvider.DynorsLogger(Spring) est le point d’entrée unique utilisé par les apps backend.- Le provider réel peut être :
console(dev),sentry(prod),noop(tests),- (plus tard)
datadog, etc.
👉 Changer de provider = changer une ligne de config, pas le code.
2. Dépendances & configuration
Dans build.gradle.kts du projet client :
dependencies {
implementation("com.dynors:dynors-logging:1.0.0-SNAPSHOT")
}
Dans application.yml :
dynors:
logging:
provider: console # console, sentry, noop, ...
enabled: true
sentry:
dsn: ${SENTRY_DSN:}
environment: ${ENVIRONMENT:production}
En dev : provider: console.
En prod : provider: sentry (avec SENTRY_DSN configuré).
3. Utilisation de DynorsLogger côté backend
import com.dynors.extensions.logging.spring.DynorsLogger;
@Service
public class OrderService {
@Autowired
private DynorsLogger logger;
public void createOrder(CreateOrderRequest request) {
try {
// ... logique métier ...
logger.info("Commande créée", Map.of(
"service", "OrderService",
"action", "createOrder",
"tenant", request.getTenantCode(),
"orderId", "..."
));
} catch (Exception e) {
logger.error("Erreur création commande", e, Map.of(
"service", "OrderService",
"action", "createOrder",
"tenant", request.getTenantCode()
));
throw e;
}
}
}
Caractéristiques :
- capture automatique de la classe, méthode et ligne d’appel (comme SLF4J),
- ajout d’un contexte riche via la Map<String, Object> (tenant, ids métier, etc.),
- provider pluggable (Sentry, console, …) sans changer ce code.
4. Logging des erreurs frontend
Pour les apps avec frontend (Angular, React, …) :
- Créer un endpoint backend
/api/logs/errorsqui reçoit des erreurs front et les passe àDynorsLogger. - Créer un
LoggerServicecôté front qui envoie un payload JSON vers cet endpoint.
Exemple backend
@RestController
@RequestMapping("/api/logs")
public class LoggingController {
@Autowired
private DynorsLogger logger;
@PostMapping("/errors")
public ResponseEntity<Void> logError(@RequestBody FrontErrorLogDto dto) {
logger.error(dto.getMessage(), null, Map.of(
"service", "Frontend",
"component", dto.getComponent(),
"action", dto.getAction(),
"tenant", dto.getTenant(),
"url", dto.getUrl(),
"userAgent", dto.getUserAgent()
));
return ResponseEntity.ok().build();
}
}
Exemple frontend (Angular)
@Injectable({ providedIn: 'root' })
export class LoggerService {
private endpoint = environment.logging.endpoint;
constructor(private http: HttpClient) {}
logError(message: string, error?: unknown, context: Record<string, any> = {}): void {
const payload = {
message,
component: context.component,
action: context.action,
tenant: environment.tenantCode,
url: window.location.href,
userAgent: navigator.userAgent
};
this.http.post(this.endpoint, payload).subscribe({
next: () => {},
error: () => {}
});
}
}
👉 Résultat : toutes les erreurs front et back se retrouvent dans le même pipeline de logs (console/Sentry/…), avec le même format de contexte.
5. Bonnes pratiques de logging dans un projet client
- Toujours inclure dans le contexte :
tenant(code du tenant courant),- identifiants métier clés (
userId,orderId,clientId, …), serviceetaction.- Utiliser des niveaux adaptés :
infopour les événements métier importants (création commande, paiement validé),warningpour les situations anormales mais non bloquantes,errorpour les vraies erreurs (exceptions, échecs d’intégration),debuguniquement en dev.- Éviter de logger des données sensibles (mots de passe, secrets, données personnelles trop détaillées).
Pour plus de détails, voir :
- dynors-extensions/packages/extensions/logging/README.md
- dynors-extensions/packages/extensions/logging/INTEGRATION_GUIDE.md.