refactor(logging): adopt ZB.MOM.WW.Telemetry.Serilog bootstrap

Swap the gateway process logging from the default Microsoft.Extensions.Logging
provider onto the shared ZB.MOM.WW.Telemetry.Serilog two-stage bootstrap.

- Add a cross-repo ProjectReference to ZB.MOM.WW.Telemetry.Serilog (transitively
  brings the Telemetry core package); the referenced project resolves its own
  Directory.Build.props / Directory.Packages.props so it does not perturb this build.
- Replace MEL wiring in GatewayApplication with builder.AddZbSerilog(ServiceName=
  "mxgateway"; SiteId/NodeRole read from MxGateway:Telemetry when present) and add
  app.UseSerilogRequestLogging().
- Add a Serilog section (Console + daily rolling File sinks, MinimumLevel) to
  appsettings.json and a MinimumLevel override to appsettings.Development.json,
  replacing the old MEL Logging sections.

The net48/x86 worker is untouched. Correlation scope + redaction move to the
shared ILogRedactor seam in the follow-up commit.
This commit is contained in:
Joseph Doherty
2026-06-01 08:03:49 -04:00
parent b4a7bac4c0
commit 4bf71a0b2c
4 changed files with 64 additions and 7 deletions
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Hosting.StaticWebAssets;
using Serilog;
using ZB.MOM.WW.MxGateway.Contracts;
using ZB.MOM.WW.MxGateway.Server.Alarms;
using ZB.MOM.WW.MxGateway.Server.Configuration;
@@ -11,6 +12,7 @@ using ZB.MOM.WW.MxGateway.Server.Security.Authentication;
using ZB.MOM.WW.MxGateway.Server.Security.Authorization;
using ZB.MOM.WW.MxGateway.Server.Sessions;
using ZB.MOM.WW.MxGateway.Server.Workers;
using ZB.MOM.WW.Telemetry.Serilog;
namespace ZB.MOM.WW.MxGateway.Server;
@@ -31,7 +33,10 @@ public static class GatewayApplication
WebApplicationBuilder builder = CreateBuilder(args);
WebApplication app = builder.Build();
// Push the per-request correlation properties (via Serilog LogContext) before the
// request-logging middleware emits its completion event, so those properties appear on it.
app.UseGatewayRequestLoggingScope();
app.UseSerilogRequestLogging();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
@@ -55,6 +60,8 @@ public static class GatewayApplication
});
StaticWebAssetsLoader.UseStaticWebAssets(builder.Environment, builder.Configuration);
ConfigureSerilog(builder);
builder.Services.AddGatewayConfiguration();
builder.Services.AddSqliteAuthStore();
builder.Services.AddGatewayGrpcAuthorization();
@@ -72,6 +79,26 @@ public static class GatewayApplication
return builder;
}
/// <summary>
/// Replaces the default Microsoft.Extensions.Logging provider with the shared
/// <c>ZB.MOM.WW.Telemetry.Serilog</c> bootstrap (<see cref="ZbSerilogExtensions.AddZbSerilog"/>).
/// Sinks and minimum level come from the <c>Serilog</c> configuration section; identity
/// (<c>SiteId</c>/<c>NodeRole</c>) is read from <c>MxGateway:Telemetry</c> when present.
/// </summary>
/// <param name="builder">The web application builder being configured.</param>
private static void ConfigureSerilog(WebApplicationBuilder builder)
{
string? siteId = builder.Configuration["MxGateway:Telemetry:SiteId"];
string? nodeRole = builder.Configuration["MxGateway:Telemetry:NodeRole"];
builder.AddZbSerilog(options =>
{
options.ServiceName = "mxgateway";
options.SiteId = string.IsNullOrWhiteSpace(siteId) ? null : siteId;
options.NodeRole = string.IsNullOrWhiteSpace(nodeRole) ? null : nodeRole;
});
}
private static string ResolveContentRootPath()
{
string? configuredContentRootPath = Environment.GetEnvironmentVariable("ASPNETCORE_CONTENTROOT");
@@ -15,6 +15,13 @@
<ItemGroup>
<ProjectReference Include="..\ZB.MOM.WW.MxGateway.Contracts\ZB.MOM.WW.MxGateway.Contracts.csproj" />
<!--
Shared structured-logging bootstrap (ZB.MOM.WW.Telemetry.Serilog) lives in the sibling
scadaproj workspace. Cross-repo ProjectReference: the referenced project resolves its own
Directory.Build.props / Directory.Packages.props from its own tree, so it does not perturb
this repo's build settings. It transitively brings the ZB.MOM.WW.Telemetry core package.
-->
<ProjectReference Include="..\..\..\scadaproj\ZB.MOM.WW.Telemetry\src\ZB.MOM.WW.Telemetry.Serilog\ZB.MOM.WW.Telemetry.Serilog.csproj" />
</ItemGroup>
</Project>
@@ -1,8 +1,10 @@
{
"Logging": {
"LogLevel": {
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
"Override": {
"Microsoft.AspNetCore": "Warning"
}
}
}
}
@@ -1,9 +1,30 @@
{
"Logging": {
"LogLevel": {
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"MinimumLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
"Override": {
"Microsoft.AspNetCore": "Warning"
}
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] [{NodeRole}/{NodeHostname}] {Message:lj} {Properties:j}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "logs/mxgateway-.log",
"rollingInterval": "Day"
}
}
]
},
"AllowedHosts": "*",
"MxGateway": {