Skip to content

Commit b9fffda

Browse files
mikemcdougallMike McDougall
andauthored
feat: implement .NET Aspire orchestration with OpenTelemetry (#49) (#87)
* feat: implement .NET Aspire orchestration with OpenTelemetry (#49) - Add Honua.AppHost project for local development orchestration - Configure PostgreSQL with PostGIS container (postgis/postgis:16-3.4) - Configure Redis container with Redis Commander for debugging - Add Honua.ServiceDefaults with shared OpenTelemetry configuration - Implement traces (ASP.NET Core, HttpClient), metrics (ASP.NET Core, runtime, custom) - Configure conditional OTLP export when OTEL_EXPORTER_OTLP_ENDPOINT is set - Add service discovery and health checks - Enable AOT compilation for production deployments - Update Honua.Server to integrate with ServiceDefaults Local development: dotnet run in src/Honua.AppHost starts full stack Production build: dotnet publish with native AOT compilation (24MB binary) * fix: resolve code style issues after merge - Added copyright headers to ServiceDefaults and AppHost projects - Removed unnecessary using statements via dotnet format - All builds pass with 0 warnings, 0 errors - All tests pass (104/104) - AOT build successful (27MB binary) --------- Co-authored-by: Mike McDougall <[email protected]>
1 parent c9dbf7c commit b9fffda

File tree

13 files changed

+260
-4
lines changed

13 files changed

+260
-4
lines changed

.gitignore

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Build results
22
[Dd]ebug/
3+
[Dd]ebugPublic/
34
[Rr]elease/
5+
[Rr]eleases/
46
x64/
57
x86/
68
[Ww][Ii][Nn]32/
@@ -16,13 +18,16 @@ msbuild.log
1618
msbuild.err
1719
msbuild.wrn
1820

19-
# Visual Studio
21+
# Visual Studio 2015/2017 cache/options directory
2022
.vs/
23+
.vscode/
24+
25+
# User-specific files
26+
*.rsuser
2127
*.suo
2228
*.user
2329
*.userosscache
2430
*.sln.docstates
25-
*.rsuser
2631
*.DotSettings.user
2732
_ReSharper*/
2833
*.[Rr]e[Ss]harper
@@ -218,3 +223,9 @@ appsettings.Development.json
218223
# AI assistant workspace files
219224
.serena/
220225
.claude/plans/
226+
227+
# Aspire
228+
.aspire/
229+
230+
# Coverage
231+
coverage*/
744 KB
Binary file not shown.
109 KB
Binary file not shown.

Honua.sln

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
Microsoft Visual Studio Solution File, Format Version 12.00
32
# Visual Studio Version 17
43
VisualStudioVersion = 17.0.31903.59
@@ -9,6 +8,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Honua.Core", "src\Honua.Cor
98
EndProject
109
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Honua.Postgres", "src\Honua.Postgres\Honua.Postgres.csproj", "{C3D4E5F6-A7B8-9012-CDEF-123456789012}"
1110
EndProject
11+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Honua.AppHost", "src\Honua.AppHost\Honua.AppHost.csproj", "{D4E5F6A7-B8C9-0123-DEF0-345678901234}"
12+
EndProject
13+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Honua.ServiceDefaults", "src\Honua.ServiceDefaults\Honua.ServiceDefaults.csproj", "{E5F6A7B8-C9D0-1234-EF01-456789012345}"
14+
EndProject
1215
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Honua.TestKit", "tests\Honua.TestKit\Honua.TestKit.csproj", "{D4E5F6A7-B8C9-0123-DEF0-234567890123}"
1316
EndProject
1417
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Honua.Server.Tests", "tests\Honua.Server.Tests\Honua.Server.Tests.csproj", "{E5F6A7B8-C9D0-1234-EF01-345678901234}"
@@ -65,6 +68,30 @@ Global
6568
{C3D4E5F6-A7B8-9012-CDEF-123456789012}.Release|x64.Build.0 = Release|Any CPU
6669
{C3D4E5F6-A7B8-9012-CDEF-123456789012}.Release|x86.ActiveCfg = Release|Any CPU
6770
{C3D4E5F6-A7B8-9012-CDEF-123456789012}.Release|x86.Build.0 = Release|Any CPU
71+
{D4E5F6A7-B8C9-0123-DEF0-345678901234}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
72+
{D4E5F6A7-B8C9-0123-DEF0-345678901234}.Debug|Any CPU.Build.0 = Debug|Any CPU
73+
{D4E5F6A7-B8C9-0123-DEF0-345678901234}.Debug|x64.ActiveCfg = Debug|Any CPU
74+
{D4E5F6A7-B8C9-0123-DEF0-345678901234}.Debug|x64.Build.0 = Debug|Any CPU
75+
{D4E5F6A7-B8C9-0123-DEF0-345678901234}.Debug|x86.ActiveCfg = Debug|Any CPU
76+
{D4E5F6A7-B8C9-0123-DEF0-345678901234}.Debug|x86.Build.0 = Debug|Any CPU
77+
{D4E5F6A7-B8C9-0123-DEF0-345678901234}.Release|Any CPU.ActiveCfg = Release|Any CPU
78+
{D4E5F6A7-B8C9-0123-DEF0-345678901234}.Release|Any CPU.Build.0 = Release|Any CPU
79+
{D4E5F6A7-B8C9-0123-DEF0-345678901234}.Release|x64.ActiveCfg = Release|Any CPU
80+
{D4E5F6A7-B8C9-0123-DEF0-345678901234}.Release|x64.Build.0 = Release|Any CPU
81+
{D4E5F6A7-B8C9-0123-DEF0-345678901234}.Release|x86.ActiveCfg = Release|Any CPU
82+
{D4E5F6A7-B8C9-0123-DEF0-345678901234}.Release|x86.Build.0 = Release|Any CPU
83+
{E5F6A7B8-C9D0-1234-EF01-456789012345}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
84+
{E5F6A7B8-C9D0-1234-EF01-456789012345}.Debug|Any CPU.Build.0 = Debug|Any CPU
85+
{E5F6A7B8-C9D0-1234-EF01-456789012345}.Debug|x64.ActiveCfg = Debug|Any CPU
86+
{E5F6A7B8-C9D0-1234-EF01-456789012345}.Debug|x64.Build.0 = Debug|Any CPU
87+
{E5F6A7B8-C9D0-1234-EF01-456789012345}.Debug|x86.ActiveCfg = Debug|Any CPU
88+
{E5F6A7B8-C9D0-1234-EF01-456789012345}.Debug|x86.Build.0 = Debug|Any CPU
89+
{E5F6A7B8-C9D0-1234-EF01-456789012345}.Release|Any CPU.ActiveCfg = Release|Any CPU
90+
{E5F6A7B8-C9D0-1234-EF01-456789012345}.Release|Any CPU.Build.0 = Release|Any CPU
91+
{E5F6A7B8-C9D0-1234-EF01-456789012345}.Release|x64.ActiveCfg = Release|Any CPU
92+
{E5F6A7B8-C9D0-1234-EF01-456789012345}.Release|x64.Build.0 = Release|Any CPU
93+
{E5F6A7B8-C9D0-1234-EF01-456789012345}.Release|x86.ActiveCfg = Release|Any CPU
94+
{E5F6A7B8-C9D0-1234-EF01-456789012345}.Release|x86.Build.0 = Release|Any CPU
6895
{D4E5F6A7-B8C9-0123-DEF0-234567890123}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
6996
{D4E5F6A7-B8C9-0123-DEF0-234567890123}.Debug|Any CPU.Build.0 = Debug|Any CPU
7097
{D4E5F6A7-B8C9-0123-DEF0-234567890123}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -108,4 +135,4 @@ Global
108135
GlobalSection(NestedProjects) = preSolution
109136
{15E10F2A-5805-4E70-ADE1-FEE7DA86AB54} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
110137
EndGlobalSection
111-
EndGlobal
138+
EndGlobal
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net10.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Aspire.Hosting" Version="13.0.0" />
12+
<PackageReference Include="Aspire.Hosting.PostgreSQL" Version="13.0.0" />
13+
<PackageReference Include="Aspire.Hosting.Redis" Version="13.0.0" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<ProjectReference Include="..\Honua.ServiceDefaults\Honua.ServiceDefaults.csproj" />
18+
</ItemGroup>
19+
20+
</Project>

src/Honua.AppHost/Program.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) Honua. All rights reserved.
2+
// Licensed under the Elastic License 2.0. See LICENSE in the project root.
3+
4+
using Aspire.Hosting;
5+
6+
var builder = DistributedApplication.CreateBuilder(args);
7+
8+
// PostgreSQL with PostGIS
9+
var postgres = builder.AddPostgres("postgres")
10+
.WithImage("postgis/postgis", "16-3.4")
11+
.WithDataVolume("honua-postgres-data")
12+
.WithPgAdmin();
13+
14+
var db = postgres.AddDatabase("honua");
15+
16+
// Optional Redis for caching
17+
var redis = builder.AddRedis("redis")
18+
.WithRedisCommander();
19+
20+
// Honua Server
21+
var honua = builder.AddProject("honua-server", "../Honua.Server/Honua.Server.csproj")
22+
.WithReference(db)
23+
.WithReference(redis)
24+
.WaitFor(db);
25+
26+
builder.Build().Run();

src/Honua.Server/Honua.Server.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<!-- Code follows dependency inversion: Server → Core ← Infrastructure -->
2121
<!-- ModuleInitializer in Postgres auto-registers services with Core -->
2222
<ProjectReference Include="..\Honua.Postgres\Honua.Postgres.csproj" />
23+
<ProjectReference Include="..\Honua.ServiceDefaults\Honua.ServiceDefaults.csproj" />
2324
</ItemGroup>
2425

2526
<ItemGroup>

src/Honua.Server/Program.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// ✅ DEPENDENCY INVERSION: Server uses Core abstractions only
77
using Honua.Server.Features.HealthCheck;
88
using Honua.Server.Features.Infrastructure.Middleware;
9+
using Honua.ServiceDefaults;
910
using Serilog;
1011
using Serilog.Enrichers.Span;
1112

@@ -18,6 +19,15 @@
1819

1920
var builder = WebApplication.CreateBuilder(args);
2021

22+
// Add Aspire service defaults (OTel, health, resilience)
23+
builder.AddServiceDefaults();
24+
25+
// Add Npgsql with connection from Aspire
26+
builder.AddNpgsqlDataSource("honua");
27+
28+
// Add Redis if configured
29+
builder.AddRedisDistributedCache("redis");
30+
2131
// Configure Serilog for structured logging with AOT compatibility
2232
builder.Host.UseSerilog((context, services, config) =>
2333
{
@@ -96,6 +106,9 @@
96106
// Configure health endpoints
97107
app.MapHealthEndpoints();
98108

109+
// Map health endpoints for Aspire dashboard
110+
app.MapDefaultEndpoints();
111+
99112
app.Run();
100113

101114
// Composition Root: Register Infrastructure implementations
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"iisSettings": {
3+
"windowsAuthentication": false,
4+
"anonymousAuthentication": true,
5+
"iisExpress": {
6+
"applicationUrl": "http://localhost:5000",
7+
"sslPort": 5001
8+
}
9+
},
10+
"profiles": {
11+
"Honua.Server": {
12+
"commandName": "Project",
13+
"dotnetRunMessages": true,
14+
"launchBrowser": true,
15+
"applicationUrl": "https://localhost:7000;http://localhost:5000",
16+
"environmentVariables": {
17+
"ASPNETCORE_ENVIRONMENT": "Development"
18+
}
19+
},
20+
"IIS Express": {
21+
"commandName": "IISExpress",
22+
"launchBrowser": true,
23+
"environmentVariables": {
24+
"ASPNETCORE_ENVIRONMENT": "Development"
25+
}
26+
}
27+
}
28+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
}
8+
}

0 commit comments

Comments
 (0)