You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
3.4 KiB

using System;
using System.Collections.Concurrent;
using System.Threading;
using Microsoft.Extensions.Logging;
namespace CellularManagement.WebSocket.Monitor;
/// <summary>
/// WebSocket 性能监控器
/// 用于收集和记录 WebSocket 连接的性能指标
/// </summary>
public class WebSocketPerformanceMonitor
{
private readonly ILogger _logger;
private readonly ConcurrentDictionary<string, ConnectionMetrics> _metrics = new();
public class ConnectionMetrics
{
private long _totalMessages;
private long _totalBytes;
private long _processingTime;
private int _errorCount;
public long TotalMessages => _totalMessages;
public long TotalBytes => _totalBytes;
public long ProcessingTime => _processingTime;
public long LastMessageTime { get; set; }
public int ErrorCount => _errorCount;
public void IncrementMessages() => Interlocked.Increment(ref _totalMessages);
public void AddBytes(long bytes) => Interlocked.Add(ref _totalBytes, bytes);
public void AddProcessingTime(long time) => Interlocked.Add(ref _processingTime, time);
public void IncrementErrors() => Interlocked.Increment(ref _errorCount);
}
public WebSocketPerformanceMonitor(ILogger logger)
{
_logger = logger;
}
/// <summary>
/// 记录消息处理性能指标
/// </summary>
/// <param name="connectionId">连接ID</param>
/// <param name="messageSize">消息大小</param>
/// <param name="processingTime">处理时间(毫秒)</param>
public void RecordMessage(string connectionId, int messageSize, long processingTime)
{
var metrics = _metrics.GetOrAdd(connectionId, _ => new ConnectionMetrics());
metrics.IncrementMessages();
metrics.AddBytes(messageSize);
metrics.AddProcessingTime(processingTime);
metrics.LastMessageTime = DateTime.UtcNow.Ticks;
if (metrics.TotalMessages % 100 == 0)
{
LogMetrics(connectionId, metrics);
}
}
/// <summary>
/// 记录错误
/// </summary>
/// <param name="connectionId">连接ID</param>
public void RecordError(string connectionId)
{
if (_metrics.TryGetValue(connectionId, out var metrics))
{
metrics.IncrementErrors();
}
}
/// <summary>
/// 获取连接的性能指标
/// </summary>
/// <param name="connectionId">连接ID</param>
/// <returns>性能指标</returns>
public ConnectionMetrics GetMetrics(string connectionId)
{
return _metrics.TryGetValue(connectionId, out var metrics) ? metrics : null;
}
/// <summary>
/// 清理连接的性能指标
/// </summary>
/// <param name="connectionId">连接ID</param>
public void ClearMetrics(string connectionId)
{
_metrics.TryRemove(connectionId, out _);
}
private void LogMetrics(string connectionId, ConnectionMetrics metrics)
{
_logger.LogInformation(
"连接性能指标 - ID: {ConnectionId}, 消息数: {MessageCount}, " +
"总字节数: {TotalBytes}, 平均处理时间: {AvgProcessingTime}ms, " +
"错误数: {ErrorCount}",
connectionId,
metrics.TotalMessages,
metrics.TotalBytes,
metrics.ProcessingTime / metrics.TotalMessages,
metrics.ErrorCount);
}
}