Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .wiki
Submodule .wiki updated from 0b5c63 to 4229e3
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.

## [3.2.3](https://github.com/purview-dev/purview-telemetry-sourcegenerator/compare/v3.2.1...v3.2.3) (2025-07-08)

## [3.2.2](https://github.com/purview-dev/purview-telemetry-sourcegenerator/compare/v3.2.1...v3.2.2) (2025-07-08)

## [3.2.1](https://github.com/purview-dev/purview-telemetry-sourcegenerator/compare/v3.2.0...v3.2.1) (2025-07-08)


### Bug Fixes

* fixed issue [#73](https://github.com/purview-dev/purview-telemetry-sourcegenerator/issues/73), also finally used CSharpier for formatting ([e0f4cc1](https://github.com/purview-dev/purview-telemetry-sourcegenerator/commit/e0f4cc114786cf99a80b96233abcde256b6c96a1))

## [3.2.0](https://github.com/purview-dev/purview-telemetry-sourcegenerator/compare/v3.2.0-prerelease.0...v3.2.0) (2025-04-24)

### Features
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Use the latest version available on [NuGet](https://www.nuget.org/packages/Purvi
Reference in your `Directory.Build.props` or `.csproj` file:

```xml
<PackageReference Include="Purview.Telemetry.SourceGenerator" Version="3.2.0">
<PackageReference Include="Purview.Telemetry.SourceGenerator" Version="3.2.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "purview-telemetry-sourcegenerator",
"version": "3.2.0",
"version": "3.2.3",
"description": "Generates [`ActivitySource`](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.activitysource), [`ILogger`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger), and [`Metrics`](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.metrics) based on interface methods.",
"readme": "README.md",
"main": "index.js",
Expand Down
4 changes: 1 addition & 3 deletions samples/SampleApp/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@
<LangVersion>13.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
<AnalysisLevel>latest</AnalysisLevel>

<NoWarn>$(NoWarn);CA1031;CA1515;CA1724;CA2007;CA2201;</NoWarn>
</PropertyGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<Sdk Name="Aspire.AppHost.Sdk" Version="9.2.0" />

<PropertyGroup>
<OutputType>Exe</OutputType>
<IsAspireHost>true</IsAspireHost>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.2.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\SampleApp.Host\SampleApp.Host.csproj" />
</ItemGroup>
Expand Down
6 changes: 4 additions & 2 deletions samples/SampleApp/SampleApp.Host/APIs/Models.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

record DefaultWeatherRequest(
[FromServices] IWeatherService WeatherService,
CancellationToken Token);
CancellationToken Token
);

record WeatherRequest(
int RequestCount,
[FromServices] IWeatherService WeatherService,
CancellationToken Token);
CancellationToken Token
);
33 changes: 16 additions & 17 deletions samples/SampleApp/SampleApp.Host/APIs/WeatherAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,47 @@ static class WeatherAPI
{
public static IEndpointRouteBuilder MapWeatherAPIv1(this IEndpointRouteBuilder app)
{
var api = app
.MapGroup("/weatherforecast")
var api = app.MapGroup("/weatherforecast")
//.MapToApiVersion(1.0)
.WithDisplayName("Weather APIs")
;
.WithDisplayName("Weather APIs");

api.MapGet("/", GetDefaultWeatherRequestAsync)
.WithDescription("Gets the weather forecasts, defaults to 5.")
.WithDisplayName("5 Weather Forecasts")
;
.WithDisplayName("5 Weather Forecasts");

api.MapGet("/{requestCount:int}", GetWeatherRequestAsync)
.WithDescription("Gets the weather forecasts.")
.WithDisplayName("Weather Forecasts")
;
.WithDisplayName("Weather Forecasts");

return api;
}

static async Task<Results<Ok<WeatherForecast[]>, NoContent, ProblemHttpResult>> GetDefaultWeatherRequestAsync([AsParameters] DefaultWeatherRequest request)
static async Task<
Results<Ok<WeatherForecast[]>, NoContent, ProblemHttpResult>
> GetDefaultWeatherRequestAsync([AsParameters] DefaultWeatherRequest request)
{
try
{
var results = await request.WeatherService.GetWeatherForecastsAsync(5, request.Token);
return results.Any()
? TypedResults.Ok(results.ToArray())
: TypedResults.NoContent();
return results.Any() ? TypedResults.Ok(results.ToArray()) : TypedResults.NoContent();
}
catch (Exception ex)
{
return TypedResults.Problem(detail: ex.Message, statusCode: 502);
}
}

static async Task<Results<Ok<WeatherForecast[]>, NoContent, ProblemHttpResult, BadRequest<string>>> GetWeatherRequestAsync([AsParameters] WeatherRequest request)
static async Task<
Results<Ok<WeatherForecast[]>, NoContent, ProblemHttpResult, BadRequest<string>>
> GetWeatherRequestAsync([AsParameters] WeatherRequest request)
{
try
{
var results = await request.WeatherService.GetWeatherForecastsAsync(request.RequestCount, request.Token);
return results.Any()
? TypedResults.Ok(results.ToArray())
: TypedResults.NoContent();
var results = await request.WeatherService.GetWeatherForecastsAsync(
request.RequestCount,
request.Token
);
return results.Any() ? TypedResults.Ok(results.ToArray()) : TypedResults.NoContent();
}
catch (ArgumentOutOfRangeException ex)
{
Expand Down
8 changes: 2 additions & 6 deletions samples/SampleApp/SampleApp.Host/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@
.AddServiceDefaults()
.AddDefaultOpenAPI(
//builder.Services.AddApiVersioning()
)
;
);

builder.Services
.AddScoped<IWeatherService, WeatherService>()
.AddWeatherServiceTelemetry()
;
builder.Services.AddScoped<IWeatherService, WeatherService>().AddWeatherServiceTelemetry();

var app = builder.Build();

Expand Down
5 changes: 1 addition & 4 deletions samples/SampleApp/SampleApp.Host/SampleApp.Host.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,19 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);CS1591</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Purview.Telemetry.SourceGenerator" Version="3.2.0">
<PackageReference Include="Purview.Telemetry.SourceGenerator" Version="3.2.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
<_Parameter1>DynamicProxyGenAssembly2</_Parameter1>
</AssemblyAttribute>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
<_Parameter1>SampleApp.UnitTests</_Parameter1>
</AssemblyAttribute>

<ProjectReference Include="..\SampleApp.ServiceDefaults\SampleApp.ServiceDefaults.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@

public interface IWeatherService
{
Task<IEnumerable<WeatherForecast>> GetWeatherForecastsAsync(int requestCount, CancellationToken cancellationToken = default);
Task<IEnumerable<WeatherForecast>> GetWeatherForecastsAsync(
int requestCount,
CancellationToken cancellationToken = default
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

namespace SampleApp.Host.Services;

/*
/*
* A multi-target interface that defines
* the telemetry methods for the WeatherService, including
* Activities, Events, Logs, and Metrics.
*
*
* As it's multi-target, each target (method) needs to be
* explicitly defined.
*/
Expand All @@ -22,7 +22,10 @@ public interface IWeatherServiceTelemetry
// --> Start: Activities

[Activity(ActivityKind.Client)]
Activity? GettingWeatherForecastFromUpstreamService([Baggage] string someRandomBaggageInfo, int requestedCount);
Activity? GettingWeatherForecastFromUpstreamService(
[Baggage] string someRandomBaggageInfo,
int requestedCount
);

[Event]
void ForecastReceived(Activity? activity, int minTempInC, int maxTempInC);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
namespace SampleApp.Host.Services;

readonly public record struct WeatherForecast(
DateOnly Date,
int TemperatureC,
string? Summary)
public readonly record struct WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{

public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
52 changes: 36 additions & 16 deletions samples/SampleApp/SampleApp.Host/Services/WeatherService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,29 @@

namespace SampleApp.Host.Services;

sealed class WeatherService(IWeatherServiceTelemetry telemetry, Func<int>? rng = null) : IWeatherService
sealed class WeatherService(IWeatherServiceTelemetry telemetry, Func<int>? rng = null)
: IWeatherService
{
const int TooColdTempInC = -10;

static readonly string[] Summaries = [
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
static readonly string[] Summaries =
[
"Freezing",
"Bracing",
"Chilly",
"Cool",
"Mild",
"Warm",
"Balmy",
"Hot",
"Sweltering",
"Scorching",
];

public Task<IEnumerable<WeatherForecast>> GetWeatherForecastsAsync(int requestCount, CancellationToken cancellationToken = default)
public Task<IEnumerable<WeatherForecast>> GetWeatherForecastsAsync(
int requestCount,
CancellationToken cancellationToken = default
)
{
const int minRequestCount = 5;
const int maxRequestCount = 20;
Expand All @@ -20,11 +34,17 @@ public Task<IEnumerable<WeatherForecast>> GetWeatherForecastsAsync(int requestCo
{
telemetry.RequestedCountIsTooSmall(requestCount);

throw new ArgumentOutOfRangeException(nameof(requestCount), $"Requested count must be at least {minRequestCount}, and no greater than {maxRequestCount}.");
throw new ArgumentOutOfRangeException(
nameof(requestCount),
$"Requested count must be at least {minRequestCount}, and no greater than {maxRequestCount}."
);
}

var sw = Stopwatch.StartNew();
using var activity = telemetry.GettingWeatherForecastFromUpstreamService($"{Guid.NewGuid()}", requestCount);
using var activity = telemetry.GettingWeatherForecastFromUpstreamService(
$"{Guid.NewGuid()}",
requestCount
);

telemetry.WeatherForecastRequested();

Expand All @@ -42,21 +62,21 @@ public Task<IEnumerable<WeatherForecast>> GetWeatherForecastsAsync(int requestCo
throw ex;
}

var results = Enumerable.Range(1, requestCount).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.UtcNow.AddDays(--index)),
TemperatureC = RandomNumberGenerator.GetInt32(-20, 55),
Summary = Summaries[RandomNumberGenerator.GetInt32(Summaries.Length)]
}).ToArray();
var results = Enumerable
.Range(1, requestCount)
.Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.UtcNow.AddDays(--index)),
TemperatureC = RandomNumberGenerator.GetInt32(-20, 55),
Summary = Summaries[RandomNumberGenerator.GetInt32(Summaries.Length)],
})
.ToArray();

foreach (var wf in results)
telemetry.HistogramOfTemperature(wf.TemperatureC);

var minTempInC = results.Min(m => m.TemperatureC);
telemetry.ForecastReceived(activity,
minTempInC,
results.Max(wf => wf.TemperatureC)
);
telemetry.ForecastReceived(activity, minTempInC, results.Max(wf => wf.TemperatureC));

if (minTempInC < TooColdTempInC)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@

#pragma warning disable IDE0130 // Namespace does not match folder structure
namespace Microsoft.Extensions.Configuration;

#pragma warning restore IDE0130 // Namespace does not match folder structure

public static class ConfigurationExtensions
{
public static string GetRequiredValue([NotNull] this IConfiguration configuration, string name) =>
public static string GetRequiredValue(
[NotNull] this IConfiguration configuration,
string name
) =>
configuration[name]
?? throw new InvalidOperationException(
$"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":" + name : name)}");

?? throw new InvalidOperationException(
$"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":" + name : name)}"
);
}
Loading
Loading