Traceability Service
Il servizio di tracciabilità fornisce un sistema automatico di TraceId per tracciare richieste, log ed eventi attraverso l'intera applicazione.
Panoramica
Il TraceabilityService genera e mantiene un TraceId univoco che viene:
- Propagato automaticamente in tutte le richieste HTTP come header
X-Trace-Id - Incluso in tutti i log dell'applicazione
- Utilizzato per correlare eventi e operazioni
Vantaggi
- ✅ Correlazione end-to-end: Traccia le richieste dal frontend al backend
- ✅ Debug facilitato: Trova facilmente tutti i log relativi a una specifica operazione
- ✅ Analisi distribuite: Supporta architetture microservizi
- ✅ User tracking: Traccia le azioni degli utenti autenticati
- ✅ Persistente: TraceId sopravvive ai reload della pagina
Regole TraceId
Il TraceId viene determinato automaticamente seguendo questa logica:
- Utente autenticato → usa
userId - Utente non autenticato → genera un GUID univoco al primo avvio
- Persistenza → salvato in localStorage per mantenere consistenza tra sessioni
Installazione
Il servizio è configurato automaticamente con provideTessUiLibrary():
import { provideTessUiLibrary } from '@tess-ui-library/core';
export const appConfig: ApplicationConfig = {
providers: [
provideTessUiLibrary(),
],
};
Uso Base
Recuperare il TraceId
import { Component, inject } from '@angular/core';
import { TraceabilityService } from '@tess-ui-library/core';
@Component({
selector: 'app-example',
standalone: true,
template: `<p>TraceId: {{ traceId }}</p>`,
})
export class ExampleComponent {
private traceability = inject(TraceabilityService);
traceId = this.traceability.getTraceId();
}
Observable per Cambiamenti
Il TraceId può cambiare quando l'utente effettua login/logout:
import { Component, inject, OnInit } from '@angular/core';
import { TraceabilityService } from '@tess-ui-library/core';
@Component({
selector: 'app-trace-monitor',
standalone: true,
template: `<p>Current TraceId: {{ currentTraceId }}</p>`,
})
export class TraceMonitorComponent implements OnInit {
private traceability = inject(TraceabilityService);
currentTraceId = '';
ngOnInit() {
// Subscribe ai cambiamenti di TraceId
this.traceability.traceId$.subscribe(traceId => {
this.currentTraceId = traceId;
console.log('TraceId aggiornato:', traceId);
});
}
}
HTTP Interceptor
L'HTTP Interceptor viene configurato automaticamente per aggiungere l'header X-Trace-Id a tutte le richieste:
// Configurato automaticamente, nessun setup richiesto
Tutte le richieste HTTP includeranno:
X-Trace-Id: user-123 // o GUID se non autenticato
Verifica nell'Network Tab
// Request headers
GET /api/users HTTP/1.1
Host: api.example.com
X-Trace-Id: user-123
Content-Type: application/json
Integrazione con Logging
Il TraceId viene automaticamente incluso in tutti i log:
import { Component, inject } from '@angular/core';
import { LoggerService } from '@tess-ui-library/core';
@Component({
selector: 'app-example',
standalone: true,
template: `...`,
})
export class ExampleComponent {
private logger = inject(LoggerService);
performAction() {
this.logger.info('Azione eseguita');
// Log output: [INFO] [user-123] Azione eseguita
}
}
API
getTraceId(): string
Ritorna il TraceId corrente.
const traceId = this.traceability.getTraceId();
console.log('TraceId:', traceId);
traceId$: Observable<string>
Observable che emette il TraceId ogni volta che cambia.
this.traceability.traceId$.subscribe(traceId => {
console.log('Nuovo TraceId:', traceId);
});
setTraceId(traceId: string): void
Imposta manualmente il TraceId (usato internamente dal sistema di auth).
// Solitamente chiamato automaticamente al login
this.traceability.setTraceId('user-456');
resetTraceId(): void
Resetta il TraceId generandone uno nuovo (utile al logout).
// Chiamato automaticamente al logout
this.traceability.resetTraceId();
Integrazione con Authentication
Il servizio si integra automaticamente con l'autenticazione:
// Esempio di integrazione nel servizio di auth
@Injectable({ providedIn: 'root' })
export class AuthService {
private traceability = inject(TraceabilityService);
login(credentials: Credentials) {
return this.http.post<AuthResponse>('/api/auth/login', credentials)
.pipe(
tap(response => {
// Aggiorna TraceId con userId dopo login
this.traceability.setTraceId(response.user.id);
})
);
}
logout() {
return this.http.post('/api/auth/logout', {})
.pipe(
tap(() => {
// Resetta TraceId al logout
this.traceability.resetTraceId();
})
);
}
}
Esempi Pratici
Tracking Azioni Utente
@Injectable({ providedIn: 'root' })
export class AnalyticsService {
private http = inject(HttpClient);
private traceability = inject(TraceabilityService);
trackEvent(eventName: string, data?: any) {
const event = {
eventName,
data,
traceId: this.traceability.getTraceId(),
timestamp: new Date().toISOString(),
};
this.http.post('/api/analytics/events', event).subscribe();
}
}
Error Reporting con TraceId
@Injectable({ providedIn: 'root' })
export class ErrorReportingService {
private http = inject(HttpClient);
private traceability = inject(TraceabilityService);
reportError(error: Error) {
const errorReport = {
message: error.message,
stack: error.stack,
traceId: this.traceability.getTraceId(),
timestamp: new Date().toISOString(),
userAgent: navigator.userAgent,
};
this.http.post('/api/errors', errorReport).subscribe();
}
}
Distributed Tracing
@Injectable({ providedIn: 'root' })
export class OrderService {
private http = inject(HttpClient);
private traceability = inject(TraceabilityService);
private logger = inject(LoggerService);
createOrder(order: Order) {
const traceId = this.traceability.getTraceId();
this.logger.info('Creazione ordine iniziata', { orderId: order.id });
// TraceId viene propagato automaticamente nell'header HTTP
return this.http.post<Order>('/api/orders', order)
.pipe(
tap(createdOrder => {
this.logger.info('Ordine creato', { orderId: createdOrder.id });
}),
catchError(error => {
this.logger.error('Errore creazione ordine', {
orderId: order.id,
error: error.message,
});
throw error;
})
);
}
}
Backend Correlation (Node.js/Express esempio)
// Backend: Middleware per estrarre TraceId
app.use((req, res, next) => {
const traceId = req.headers['x-trace-id'] || generateUUID();
req.traceId = traceId;
// Aggiungi TraceId al logger
req.log = logger.child({ traceId });
next();
});
// Usa il logger con TraceId in ogni endpoint
app.post('/api/orders', (req, res) => {
req.log.info('Ricevuta richiesta creazione ordine');
// ... logica business ...
req.log.info('Ordine creato con successo', { orderId: order.id });
res.json(order);
});
Configurazione Avanzata
Custom TraceId Generator
// app.config.ts
import { TRACE_ID_GENERATOR } from '@tess-ui-library/core';
export const appConfig: ApplicationConfig = {
providers: [
{
provide: TRACE_ID_GENERATOR,
useValue: () => {
// Custom logic per generare TraceId
return `custom-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
},
},
],
};
Custom Storage Key
import { TRACE_ID_STORAGE_KEY } from '@tess-ui-library/core';
export const appConfig: ApplicationConfig = {
providers: [
{
provide: TRACE_ID_STORAGE_KEY,
useValue: 'myapp:traceId', // Custom storage key
},
],
};
Monitoring e Debug
Console Logging
Durante lo sviluppo, verifica i TraceId nei log:
// In sviluppo
this.logger.debug('Operazione completata', {
traceId: this.traceability.getTraceId(),
operation: 'checkout',
duration: 1234,
});
Application Insights Integration
// Configurazione automatica con AppInsightsLoggerProvider
// Il TraceId viene incluso in tutti i telemetry events
DevTools Network Tab
Controlla che l'header X-Trace-Id sia presente nelle richieste HTTP:
- Apri DevTools (F12)
- Tab "Network"
- Seleziona una richiesta
- Tab "Headers"
- Verifica presenza di
X-Trace-Idnei Request Headers
Best Practices
- Non modificare manualmente: Lascia che il sistema gestisca automaticamente il TraceId
- Usa nei log: Includi sempre il TraceId nei log per correlazione
- Propaga al backend: Assicurati che il backend estragga e utilizzi il TraceId
- Monitoring: Usa strumenti di APM (Application Performance Monitoring) per analizzare i tracciamenti
- Privacy: Considera implicazioni privacy quando usi userId come TraceId
- Distributed systems: Propaga il TraceId attraverso tutti i microservizi
- Error handling: Includi sempre TraceId nei report di errore
Troubleshooting
TraceId non presente negli headers
Verifica che l'HTTP interceptor sia configurato:
// app.config.ts
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { traceIdInterceptor } from '@tess-ui-library/core';
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(
withInterceptors([traceIdInterceptor])
),
],
};
TraceId cambia inaspettatamente
Controlla che non ci siano chiamate manuali a resetTraceId() o setTraceId().
TraceId non persiste
Verifica che il localStorage non sia disabilitato o bloccato dal browser.