Skip to content

Sample Application

Kieron Lanning edited this page Mar 16, 2026 · 7 revisions

Sample Application

The sample app is a complete weather forecast application demonstrating the Purview Telemetry Source Generator in a real-world .NET Aspire setup. It covers all three telemetry targets — Activities, Logging, and Metrics — including multi-target methods that generate multiple telemetry types from a single method call.

The solution lives in samples/SampleApp/.

Project Structure

Project Description
SampleApp.AppHost .NET Aspire orchestrator — wires up all resources and the Aspire dashboard
SampleApp.APIService RESTful weather API backend; contains the primary telemetry interfaces
SampleApp.Web Blazor Server frontend that calls the API and has its own HTTP client telemetry
SampleApp.Shared Shared WeatherForecast DTO used by both API and frontend
SampleApp.ServiceDefaults Common Aspire service defaults (OpenTelemetry, health checks, resilience)
SampleApp.APIService.UnitTests Unit tests demonstrating how to mock and assert against generated telemetry interfaces

Telemetry Interfaces

There are three generated telemetry interfaces across the solution:

IEntityStoreTelemetry (SampleApp.APIService) — the interface from the Quick Start guide; shows the full multi-target pattern with Activity + Logging + Metrics on a single method:

[ActivitySource]
[Logger]
[Meter]
interface IEntityStoreTelemetry
{
    [Activity]
    [Info]
    [AutoCounter]
    Activity? GettingEntityFromStore(int entityId, [Baggage] string serviceUrl);

    [Event]
    [Trace]
    void GetDuration(Activity? activity, int durationInMS);

    [Context]
    void RetrievedEntity(Activity? activity, float totalValue, int lastUpdatedByUserId);

    [Warning]
    void EntityNotFound(int entityId);

    [Histogram]
    void RecordEntitySize(int sizeInBytes);
}

IWeatherServiceTelemetry (SampleApp.APIService.Services) — the primary telemetry for the weather service; demonstrates more advanced patterns including enumerable expansion and [ExcludeTargets]:

[ActivitySource]
[Logger]
[Meter]
public interface IWeatherServiceTelemetry
{
    [Activity(ActivityKind.Client)]
    [Trace]
    Activity? GettingWeatherForecast([Baggage] string someRandomBaggageInfo, int requestedCount);

    [Event]
    void ForecastReceived(Activity? activity, int minTempInC, int maxTempInC);

    [AutoCounter]
    [Warning]
    [Event]
    void ItsTooCold(Activity? activity, int minTempInC, int tooColdCount);

    [Histogram]
    void HistogramOfTemperature(int temperature);

    [Error]
    [AutoCounter]
    void RequestedCountIsOutOfRange(int requestCount);
}

IWeatherAPIClientTelemetry (SampleApp.Web.Clients) — telemetry for the Blazor frontend's HTTP client; uses [ExcludeTargets] to prevent certain parameters appearing in specific telemetry targets:

[ActivitySource]
[Logger]
[Meter(InstrumentPrefix = "weather")]
public interface IWeatherAPIClientTelemetry
{
    [Activity(ActivityKind.Client)]
    [Info]
    [AutoCounter]
    Activity? GetWeatherForecasts(int? count);

    [Event]
    [Error]
    [AutoCounter]
    void FailedToGetForecast(Activity? activity, Exception ex,
        [ExcludeTargets(Targets.Activities)] int? count);

    [Event(ActivityStatusCode.Ok)]
    [Debug]
    void ForecastsRecieved(Activity? activity, int forecastCount,
        [ExpandEnumerable(100), ExcludeTargets(Targets.Activities)] WeatherForecast[] weatherForecasts);
}

Unit Testing

The SampleApp.APIService.UnitTests project demonstrates how to unit test code that depends on generated telemetry. Since the generator works from interfaces, you simply mock the interface with any compatible mocking library:

// Using NSubstitute
static IWeatherServiceTelemetry CreateTelemetry() =>
    Substitute.For<IWeatherServiceTelemetry>();

// Use the mock in the system under test
var sut = new WeatherService(telemetry: CreateTelemetry(), ...);

Tests are split across WeatherServiceTests.Success.cs, WeatherServiceTests.Failure.cs, and WeatherServiceTests.Validation.cs.


Running the Dashboard and Viewing Telemetry

  1. Open the solution (samples/SampleApp/SampleApp.slnx) and run the SampleApp.AppHost project.
  2. The .NET Aspire dashboard opens automatically — it shows all resources: api-service, web, and a dedicated scalar resource.
  3. To generate telemetry, use one of two approaches:
    • Web Frontend: Click the web resource endpoint to open the Blazor app, navigate to the Weather page, and click Load Weather (or trigger error scenarios).
    • Scalar API Docs: Click the scalar resource endpoint to open the Scalar UI, then test the API endpoints directly.
Step Image
The Aspire dashboard shows all resources — api-service, web, and scalar. Click any endpoint link. .NET Aspire Dashboard showing the running application
In the Scalar UI, scroll to the endpoint you want to test and click Test Request. Showing the Scalar Endpoint view
Press the Scalar Play Button (Play) button several times to generate telemetry data. Use error scenarios to see failure paths. Showing the Scalar Play button to send a request to the service.

The resulting telemetry appears in the various sections of the Aspire dashboard:

Dashboard view Image
Failed requests visible in the resource list. Failures visible in the .NET Aspire project list
Console logs for the running service. Console logs view
Structured logs with full property context. Structured logs view
Distributed traces across the request path. Traces view
Trace detail showing Activity spans, ActivityEvents, and baggage/tag properties. Activity and ActivityEvent details
Metrics dashboard with counters and histograms. Metrics view
Histogram distribution view. Metrics histogram view

Viewing Generated Code

The sample projects have <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> enabled, so generated files appear in your IDE under:

SampleApp.APIService/
  obj/Release/net10.0/generated/
    Purview.Telemetry.SourceGenerator/
      Purview.Telemetry.SourceGenerator.TelemetrySourceGenerator/
        SampleApp.APIService.WeatherServiceTelemetryCore.Activity.g.cs
        SampleApp.APIService.WeatherServiceTelemetryCore.Logging.g.cs
        SampleApp.APIService.WeatherServiceTelemetryCore.Metric.g.cs
        SampleApp.APIService.WeatherServiceTelemetryCoreDIExtension.DependencyInjection.g.cs
        SampleApp.APIService.TelemetryNames.g.cs

See Generated Output for full annotated examples of the generated code.

Clone this wiki locally