APM pour Blazor · Apache 2.0

Observabilité complète pour Blazor

Traces, métriques et profiling sans modifier votre code métier. Compatible Blazor Server, WebAssembly, Web API et EF Core — exportation vers Grafana Cloud ou auto-hébergé.

Blazor Server WebAssembly Web API EF Core Grafana Cloud

Zéro code métier à modifier

Chaque signal est capturé automatiquement par le middleware ou l'AOP — votre logique applicative reste intacte.

🌐

Requêtes HTTP

Traces entrantes (ASP.NET Core) et sortantes (HttpClient) avec statut, route et IP client.

Circuits SignalR

Connexion, déconnexion et durée de vie de chaque circuit Blazor Server.

🧩

Cycle de vie des composants

OnInitialized, OnParametersSet, OnAfterRender et événements utilisateur (clics, inputs).

🗺️

Navigation SPA

Un span par changement de route — latence perçue par l'utilisateur.

🔁

Services métier (AOP)

Un span automatique par appel de méthode via Castle DynamicProxy. Aucun attribut, aucune modification.

Castle DynamicProxy
📊

Métriques runtime

GC, thread pool et JIT — métriques .NET exportées en continu vers Prometheus / Mimir.

🗄️

Requêtes EF Core

Chaque requête SQL devient un span enfant avec db.statement, db.name et db.system.

Package séparé · beta
🌊

Client WebAssembly

Propagation du contexte de trace vers l'API serveur via des headers HTTP standards.

Trois packages, une stack complète

Le package principal est stable. L'instrumentation EF Core est en beta car sa dépendance OpenTelemetry n'est pas encore stable.

📦
BlazorAmpowering.Observability
1.0.0 stable

Instrumentation principale : traces HTTP, circuits SignalR, composants Blazor, navigation, AOP services, métriques runtime, profiling Pyroscope.

Voir sur NuGet
🗄️
BlazorAmpowering.Observability.EntityFrameworkCore
1.0.0-beta.1

Ajoute un span OpenTelemetry pour chaque requête SQL exécutée par EF Core. En beta car dépend de OpenTelemetry.Instrumentation.EntityFrameworkCore (pre-release).

Voir sur NuGet
🌊
BlazorAmpowering.Observability.WebAssembly
1.0.0 stable

Propagation du contexte OTel depuis le client WebAssembly vers l'API serveur via des headers HTTP (traceparent, X-Blazor-*).

Voir sur NuGet

Prêt en quelques minutes

Suivez les étapes correspondant à votre type de projet.

1

1. Installer le package

Ajoutez le package NuGet à votre projet serveur.

shell
dotnet add package BlazorAmpowering.Observability
2

2. Configurer appsettings.json

Ajoutez la section OpenTelemetry à votre fichier de configuration.

appsettings.json
{
  "OpenTelemetry": {
    "Enabled": true,
    "ApplicationName": "my-app",
    "OtlpEndpoint": "http://localhost:4318/v1/traces",
    "SamplingProbability": 1.0
  }
}
3

3. Enregistrer dans Program.cs

Appelez les extensions dans l'ordre indiqué.

Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddRazorComponents()
    .AddInteractiveServerComponents();

// Web API — un span par action
builder.Services
    .AddControllers()
    .AddApiObservability();

// Circuit handler + navigation
builder.Services.AddBlazorObservability();

// Pipeline OTel : traces + métriques
builder.AddBlazorTelemetry();

// Profiling Pyroscope (no-op si le profiler natif n'est pas chargé)
builder.AddBlazorProfiler();
4

4. Instrumenter les composants

Ajoutez l'héritage dans _Imports.razor pour instrumenter tous les composants d'un dossier.

Components/_Imports.razor
@using BlazorAmpowering.Observability.Components
@inherits InstrumentedComponentBase
Remplacez OnInitializedAsync par OnInitializedCoreAsync et OnParametersSetAsync par OnParametersSetCoreAsync dans vos composants.
MyComponent.razor
@code {
    protected override async Task OnInitializedCoreAsync()
    {
        data = await MyService.GetDataAsync();
    }
}
5

5. Activer la navigation (optionnel)

Injectez NavigationInstrumentation dans MainLayout.razor pour tracer chaque changement de route.

MainLayout.razor
@using BlazorAmpowering.Observability.Services
@inject NavigationInstrumentation NavInstrumentation
1

1. Installer le package WASM

Ajoutez le package au projet client WebAssembly.

shell
dotnet add package BlazorAmpowering.Observability.WebAssembly
2

2. Enregistrer dans Program.cs (client)

Une seule ligne dans le Program.cs du client WASM.

Program.cs (client WASM)
var builder = WebAssemblyHostBuilder.CreateDefault(args);

builder.Services.AddWasmObservability();

await builder.Build().RunAsync();
3

3. Instrumenter les composants WASM

Utilisez WasmInstrumentedComponentBase à la place du base class standard.

Client/_Imports.razor
@using BlazorAmpowering.Observability.WebAssembly.Components
@inherits WasmInstrumentedComponentBase
MyWasmComponent.razor
@code {
    protected override async Task OnInitializedCoreAsync()
    {
        // Les appels HTTP sortants injectent automatiquement
        // traceparent et X-Blazor-* dans les headers.
        data = await Http.GetFromJsonAsync<MyData[]>("/api/data");
    }

    // Contexte explicite pour les appels déclenchés par un événement
    private async Task HandleClick()
    {
        await TraceRequest(() => Http.PostAsJsonAsync("/api/action", payload));
    }
}
4

4. Configuration serveur

La pipeline OTel vit entièrement côté serveur. Le client WASM injecte uniquement les headers de contexte — aucune configuration OTel n'est nécessaire dans le projet client.
1

1. Ajouter l'observabilité aux contrôleurs

Chaînez AddApiObservability() après AddControllers().

Program.cs
builder.Services
    .AddControllers()
    .AddApiObservability();

// Désactiver la capture des paramètres en production (données sensibles)
builder.Services
    .AddControllers()
    .AddApiObservability(options =>
    {
        options.CaptureActionParameters = false;
    });
Un span enfant est automatiquement créé pour chaque action de contrôleur avec les tags controller, action, http.method, http.route et http.status_code.
2

2. Tags enrichis par WASM

Quand l'API est appelée depuis un client WASM, les spans sont automatiquement enrichis avec blazor.component, blazor.method, blazor.event et client.latency_ms.

Exemple de span produit
ProductsController.GetAll
├─ controller:        Products
├─ action:            GetAll
├─ http.method:       GET
├─ http.route:        api/products
├─ http.status_code:  200
├─ blazor.component:  ProductList   ← injecté par le client WASM
├─ blazor.method:     OnInitialized
└─ client.latency_ms: 42
1

1. Installer le package EF Core

Ce package est en pre-release car sa dépendance OpenTelemetry ne l'est pas encore.

shell
dotnet add package BlazorAmpowering.Observability --version 1.0.0
dotnet add package BlazorAmpowering.Observability.EntityFrameworkCore --prerelease
2

2. Appeler après AddBlazorTelemetry()

Ajoutez l'instrumentation EF Core après le pipeline OTel principal.

Program.cs
builder.AddBlazorTelemetry();

// EF Core — un span par requête SQL
builder.AddEntityFrameworkCoreInstrumentation();
Désactivez la capture des statements SQL en production si vos requêtes contiennent des données sensibles : builder.AddEntityFrameworkCoreInstrumentation(setDbStatementForText: false)
Exemple de span produit
GET /api/products
└─ ProductsController.GetAll
   └─ SELECT * FROM "Products"    ← span EF Core
      ├─ db.system:      sqlite
      ├─ db.name:        mydb
      └─ db.statement:   SELECT "p"."Id", "p"."Date" FROM "Products" AS "p"

Configuration Grafana Cloud

Grafana Cloud fournit Tempo (traces), Mimir/Prometheus (métriques) et Pyroscope (profiling) en service managé.

Étape 1 — Récupérer vos endpoints

Dans Grafana Cloud, allez dans Home → My Stack, puis sélectionnez chaque service pour obtenir son endpoint OTLP et son instance ID.

📈 Traces (Tempo)

OtlpEndpoint
https://otlp-gateway-prod-eu-west-2.grafana.net/otlp/v1/traces
OtlpHeaders
Authorization=Basic <base64(tempoInstanceId:apiToken)>

📊 Métriques (Prometheus / Mimir)

OtlpMetricsEndpoint
https://prometheus-prod-xx-prod-eu-west-2.grafana.net/otlp/v1/metrics
OtlpMetricsHeaders
Authorization=Basic <base64(prometheusInstanceId:apiToken)>

🔥 Profiling (Pyroscope)

PYROSCOPE_SERVER_ADDRESS
https://profiles-prod-XXX.grafana.net
PYROSCOPE_BASIC_AUTH_USER
<pyroscopeInstanceId>
PYROSCOPE_BASIC_AUTH_PASSWORD
<apiToken>

Étape 2 — appsettings.json

Les instance IDs Tempo et Prometheus sont distincts sur Grafana Cloud. Utilisez OtlpHeaders pour Tempo et OtlpMetricsHeaders pour Prometheus.
appsettings.json
{
  "OpenTelemetry": {
    "Enabled": true,
    "ApplicationName": "my-app",
    "OtlpEndpoint": "https://otlp-gateway-prod-eu-west-2.grafana.net/otlp/v1/traces",
    "OtlpHeaders": "Authorization=Basic <base64(tempoInstanceId:apiToken)>",
    "OtlpMetricsEndpoint": "https://prometheus-prod-xx-prod-eu-west-2.grafana.net/otlp/v1/metrics",
    "OtlpMetricsHeaders": "Authorization=Basic <base64(prometheusInstanceId:apiToken)>",
    "SamplingProbability": 0.1
  }
}

Pyroscope (profiling CPU)

Sur Linux, définissez les variables d'environnement suivantes avant de lancer votre application. Sur Windows et macOS, utilisez les scripts fournis dans le package NuGet sous scripts/.

Scripts inclus dans le package :

bash (Linux)
export CORECLR_ENABLE_PROFILING=1
export CORECLR_PROFILER={BD1A650D-AC5D-4896-B64F-D6FA25D6B26A}
export CORECLR_PROFILER_PATH=./profiler/Pyroscope.Profiler.Native.so

export PYROSCOPE_APPLICATION_NAME=my-app
export PYROSCOPE_SERVER_ADDRESS=https://profiles-prod-XXX.grafana.net
export PYROSCOPE_BASIC_AUTH_USER=<pyroscopeInstanceId>
export PYROSCOPE_BASIC_AUTH_PASSWORD=<apiToken>

dotnet run --project MyApp.csproj

Auto-hébergement (Docker)

Démarrez la stack locale avec Docker Compose.

shell
cd observability
docker compose up -d
Service URL
Grafanahttp://localhost:3000
Prometheushttp://localhost:9090
Tempohttp://localhost:3200
OTel Collector (OTLP HTTP)http://localhost:4318
Pyroscopehttp://localhost:4040

Intelligence sur vos données de production

Un plugin Grafana et un service SAAS vont transformer vos traces en insights actionnables — directement dans votre dashboard.

Soon
🎯

Code Coverage en production

Visualisez les lignes de code réellement exécutées en production, ligne par ligne, à partir des traces OpenTelemetry.

Soon
🔍

Détecteur de code mort

Identifiez automatiquement les méthodes et branches jamais appelées en production pour guider vos refactorisations.

Soon

Suggestions de performance

Recommandations d'optimisation basées sur l'analyse des spans : N+1, allocations inutiles, hot paths.

Soon
📊

Plugin Grafana

Tous ces insights directement dans votre Grafana existant — pas de nouvelle UI à apprendre.

Rejoignez la liste d'attente

Le service SAAS est en cours de développement. Inscrivez-vous pour être parmi les premiers à y accéder et influencer la roadmap.

Besoin d'aide ?

Une question, un bug ou une suggestion ? Ouvrez une demande de support — nous répondons en général sous 48 h.