feat(lmxproxy): phase 4 — host health monitoring, metrics, status web server
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,8 +3,10 @@ using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core;
|
||||
using GrpcStatus = Grpc.Core.Status;
|
||||
using Serilog;
|
||||
using ZB.MOM.WW.LmxProxy.Host.Domain;
|
||||
using ZB.MOM.WW.LmxProxy.Host.Metrics;
|
||||
using ZB.MOM.WW.LmxProxy.Host.Sessions;
|
||||
using ZB.MOM.WW.LmxProxy.Host.Subscriptions;
|
||||
|
||||
@@ -21,15 +23,18 @@ namespace ZB.MOM.WW.LmxProxy.Host.Grpc.Services
|
||||
private readonly IScadaClient _scadaClient;
|
||||
private readonly SessionManager _sessionManager;
|
||||
private readonly SubscriptionManager _subscriptionManager;
|
||||
private readonly PerformanceMetrics? _performanceMetrics;
|
||||
|
||||
public ScadaGrpcService(
|
||||
IScadaClient scadaClient,
|
||||
SessionManager sessionManager,
|
||||
SubscriptionManager subscriptionManager)
|
||||
SubscriptionManager subscriptionManager,
|
||||
PerformanceMetrics? performanceMetrics = null)
|
||||
{
|
||||
_scadaClient = scadaClient;
|
||||
_sessionManager = sessionManager;
|
||||
_subscriptionManager = subscriptionManager;
|
||||
_performanceMetrics = performanceMetrics;
|
||||
}
|
||||
|
||||
// -- Connection Management ------------------------------------
|
||||
@@ -121,6 +126,7 @@ namespace ZB.MOM.WW.LmxProxy.Host.Grpc.Services
|
||||
};
|
||||
}
|
||||
|
||||
using var timing = _performanceMetrics?.BeginOperation("Read");
|
||||
try
|
||||
{
|
||||
var vtq = await _scadaClient.ReadAsync(request.Tag, context.CancellationToken);
|
||||
@@ -133,6 +139,7 @@ namespace ZB.MOM.WW.LmxProxy.Host.Grpc.Services
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
timing?.SetSuccess(false);
|
||||
Log.Error(ex, "Read failed for tag {Tag}", request.Tag);
|
||||
return new Scada.ReadResponse
|
||||
{
|
||||
@@ -155,6 +162,7 @@ namespace ZB.MOM.WW.LmxProxy.Host.Grpc.Services
|
||||
};
|
||||
}
|
||||
|
||||
using var timing = _performanceMetrics?.BeginOperation("ReadBatch");
|
||||
try
|
||||
{
|
||||
var results = await _scadaClient.ReadBatchAsync(request.Tags, context.CancellationToken);
|
||||
@@ -182,6 +190,7 @@ namespace ZB.MOM.WW.LmxProxy.Host.Grpc.Services
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
timing?.SetSuccess(false);
|
||||
Log.Error(ex, "ReadBatch failed");
|
||||
return new Scada.ReadBatchResponse
|
||||
{
|
||||
@@ -201,6 +210,7 @@ namespace ZB.MOM.WW.LmxProxy.Host.Grpc.Services
|
||||
return new Scada.WriteResponse { Success = false, Message = "Invalid session" };
|
||||
}
|
||||
|
||||
using var timing = _performanceMetrics?.BeginOperation("Write");
|
||||
try
|
||||
{
|
||||
var value = TypedValueConverter.FromTypedValue(request.Value);
|
||||
@@ -209,6 +219,7 @@ namespace ZB.MOM.WW.LmxProxy.Host.Grpc.Services
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
timing?.SetSuccess(false);
|
||||
Log.Error(ex, "Write failed for tag {Tag}", request.Tag);
|
||||
return new Scada.WriteResponse { Success = false, Message = ex.Message };
|
||||
}
|
||||
@@ -222,6 +233,7 @@ namespace ZB.MOM.WW.LmxProxy.Host.Grpc.Services
|
||||
return new Scada.WriteBatchResponse { Success = false, Message = "Invalid session" };
|
||||
}
|
||||
|
||||
using var timing = _performanceMetrics?.BeginOperation("WriteBatch");
|
||||
var response = new Scada.WriteBatchResponse { Success = true, Message = "" };
|
||||
|
||||
foreach (var item in request.Items)
|
||||
@@ -245,6 +257,11 @@ namespace ZB.MOM.WW.LmxProxy.Host.Grpc.Services
|
||||
}
|
||||
}
|
||||
|
||||
if (!response.Success)
|
||||
{
|
||||
timing?.SetSuccess(false);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -336,7 +353,7 @@ namespace ZB.MOM.WW.LmxProxy.Host.Grpc.Services
|
||||
{
|
||||
if (!_sessionManager.ValidateSession(request.SessionId))
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unauthenticated, "Invalid session"));
|
||||
throw new RpcException(new GrpcStatus(StatusCode.Unauthenticated, "Invalid session"));
|
||||
}
|
||||
|
||||
var reader = _subscriptionManager.Subscribe(
|
||||
@@ -360,7 +377,7 @@ namespace ZB.MOM.WW.LmxProxy.Host.Grpc.Services
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Subscribe stream error for session {SessionId}", request.SessionId);
|
||||
throw new RpcException(new Status(StatusCode.Internal, ex.Message));
|
||||
throw new RpcException(new GrpcStatus(StatusCode.Internal, ex.Message));
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user