412da27c5f
v2-ci / unit-tests (push) Has been cancelled
Pins ZB.MOM.WW.Telemetry(.Serilog) 0.1.0 -> 0.3.0. The OTel Resource now names the node: site.id = its application Cluster id (the cluster-<ClusterId> role suffix, omitted on a legacy node), node.role = its plain roles in canonical order (admin / driver / admin,driver), service.version = the entry assembly's informational version (the git SHA). Program passes its resolved EffectiveRoles. The whole OtOpcUa:Telemetry section goes through the shared ApplyConfiguration, so SiteId / NodeRole / ServiceVersion / ResourceAttributes:* are operator overrides, and Exporter=Otlp now also sends the Serilog logs to the same collector. ObservabilityResourceIdentityTests cover the mapping and the built container's Resource. Host.Tests 288/288, Host.IntegrationTests 325/327 (2 skipped). Claude-Session: https://claude.ai/code/session_01GT67ACmpMR7b9LGRPLijMi
72 lines
2.6 KiB
C#
72 lines
2.6 KiB
C#
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using OpenTelemetry;
|
|
using OpenTelemetry.Trace;
|
|
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.Cluster;
|
|
using ZB.MOM.WW.OtOpcUa.Host.Observability;
|
|
using ZB.MOM.WW.Telemetry;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Host.IntegrationTests;
|
|
|
|
/// <summary>
|
|
/// scadaproj#55 — the OTel Resource carries <c>site.id</c> (the node's application Cluster id),
|
|
/// <c>node.role</c> (its plain roles) and <c>service.version</c> (entry-assembly default), so two
|
|
/// OtOpcUa nodes are distinguishable by more than <c>service.instance.id</c>.
|
|
/// </summary>
|
|
public sealed class ObservabilityResourceIdentityTests
|
|
{
|
|
private static IConfiguration EmptyConfig() => new ConfigurationBuilder().Build();
|
|
|
|
[Fact]
|
|
public void FusedNode_ReportsClusterIdAndCanonicalRoles()
|
|
{
|
|
var roles = EffectiveRoles.Resolve(["driver", "cluster-SITE-A", "admin"], envRoles: null);
|
|
var o = new ZbTelemetryOptions();
|
|
|
|
ObservabilityExtensions.ConfigureTelemetry(o, EmptyConfig(), roles);
|
|
|
|
o.SiteId.ShouldBe("SITE-A");
|
|
o.NodeRole.ShouldBe("admin,driver");
|
|
o.ServiceVersion.ShouldBeNull(); // null = the library's entry-assembly default
|
|
}
|
|
|
|
[Fact]
|
|
public void LegacyNodeWithoutClusterRole_OmitsSiteId()
|
|
{
|
|
var roles = EffectiveRoles.Resolve(["driver"], envRoles: null);
|
|
var o = new ZbTelemetryOptions();
|
|
|
|
ObservabilityExtensions.ConfigureTelemetry(o, EmptyConfig(), roles);
|
|
|
|
o.SiteId.ShouldBeNull();
|
|
o.NodeRole.ShouldBe("driver");
|
|
}
|
|
|
|
[Fact]
|
|
public void NoRoles_OmitsNodeRole()
|
|
{
|
|
ObservabilityExtensions.NodeRoleOf(EffectiveRoles.Resolve(null, null)).ShouldBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void BuiltContainer_ResourceCarriesIdentityAndVersion()
|
|
{
|
|
var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = [] });
|
|
builder.Services.AddOtOpcUaObservability(
|
|
builder.Configuration, EffectiveRoles.Resolve(["admin", "driver", "cluster-MAIN"], null));
|
|
using var app = builder.Build();
|
|
|
|
var attributes = app.Services.GetRequiredService<TracerProvider>().GetResource().Attributes
|
|
.ToDictionary(a => a.Key, a => a.Value);
|
|
|
|
attributes["service.name"].ShouldBe("otopcua");
|
|
attributes["site.id"].ShouldBe("MAIN");
|
|
attributes["node.role"].ShouldBe("admin,driver");
|
|
attributes["service.version"].ShouldBe(ZbResource.DefaultServiceVersion);
|
|
((string)attributes["service.version"]).ShouldNotBeNullOrWhiteSpace();
|
|
}
|
|
}
|