Skip to main content

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:

  1. Utente autenticato → usa userId
  2. Utente non autenticato → genera un GUID univoco al primo avvio
  3. 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:

  1. Apri DevTools (F12)
  2. Tab "Network"
  3. Seleziona una richiesta
  4. Tab "Headers"
  5. Verifica presenza di X-Trace-Id nei Request Headers

Best Practices

  1. Non modificare manualmente: Lascia che il sistema gestisca automaticamente il TraceId
  2. Usa nei log: Includi sempre il TraceId nei log per correlazione
  3. Propaga al backend: Assicurati che il backend estragga e utilizzi il TraceId
  4. Monitoring: Usa strumenti di APM (Application Performance Monitoring) per analizzare i tracciamenti
  5. Privacy: Considera implicazioni privacy quando usi userId come TraceId
  6. Distributed systems: Propaga il TraceId attraverso tutti i microservizi
  7. 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.

Vedi Anche