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
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);
|
|
}
|
|
}
|