MES-ETL/MesETL.App/HostedServices/TaskMonitorService.cs

140 lines
5.6 KiB
C#
Raw Normal View History

2023-12-29 16:16:05 +08:00
using System.Diagnostics;
2024-02-09 19:08:57 +08:00
using System.Text;
using MesETL.App.Services;
using MesETL.App.Services.Loggers;
2023-12-29 16:16:05 +08:00
using Microsoft.Extensions.DependencyInjection;
namespace MesETL.App.HostedServices;
2023-12-29 16:16:05 +08:00
2024-01-04 09:00:44 +08:00
/// <summary>
/// 任务监控
/// </summary>
2024-02-01 15:25:42 +08:00
public class TaskMonitorService
2023-12-29 16:16:05 +08:00
{
2024-01-29 09:29:16 +08:00
private readonly IEnumerable<ITaskMonitorLogger> _monitorLoggers;
2023-12-29 16:16:05 +08:00
private readonly ProcessContext _context;
private readonly DataRecordQueue _producerQueue;
2024-01-29 09:29:16 +08:00
private readonly RecordQueuePool _queuePool;
2024-02-09 19:08:57 +08:00
private string _outputPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log/progress.txt");
2023-12-29 16:16:05 +08:00
2024-02-01 15:25:42 +08:00
public TaskMonitorService(ProcessContext context,
2024-02-06 15:37:21 +08:00
[FromKeyedServices(Const.ConstVar.Producer)]
2023-12-29 16:16:05 +08:00
DataRecordQueue producerQueue,
2024-01-29 09:29:16 +08:00
RecordQueuePool queuePool,
2024-02-15 16:18:50 +08:00
IEnumerable<ITaskMonitorLogger> monitorLoggers)
2023-12-29 16:16:05 +08:00
{
_context = context;
_producerQueue = producerQueue;
2024-01-29 09:29:16 +08:00
_queuePool = queuePool;
_monitorLoggers = monitorLoggers;
2023-12-29 16:16:05 +08:00
}
2024-02-01 15:25:42 +08:00
public async Task Monitor(CancellationToken stoppingToken)
2023-12-29 16:16:05 +08:00
{
var sw = Stopwatch.StartNew();
var lastTime = sw.ElapsedMilliseconds;
var lastInputCount = _context.InputCount;
var lastTransformCount = _context.TransformCount;
var lastOutputCount = _context.OutputCount;
bool endCheck = false;
2024-01-29 09:29:16 +08:00
while (!stoppingToken.IsCancellationRequested)
2023-12-29 16:16:05 +08:00
{
EndCheck:
// var running = 0;
// var error = 0;
// var completed = 0;
// var canceled = 0;
// foreach (var task in _taskManager.Tasks)
// {
// switch (task.Status)
// {
// case TaskStatus.Canceled:
// canceled++;
// break;
// case TaskStatus.Faulted:
// error++;
// break;
// case TaskStatus.RanToCompletion:
// completed++;
// break;
// default:
// running++;
// break;
// }
// }
var time = sw.ElapsedMilliseconds;
var inputCount = _context.InputCount;
var transformCount = _context.TransformCount;
var outputCount = _context.OutputCount;
var elapseTime = (time - lastTime) / 1000f;
var inputSpeed = (inputCount - lastInputCount) / elapseTime;
var transformSpeed = (transformCount - lastTransformCount) / elapseTime;
var outputSpeed = (outputCount - lastOutputCount) / elapseTime;
2024-01-29 09:29:16 +08:00
2023-12-29 16:16:05 +08:00
// _logger.LogInformation(
// "Task monitor: running: {Running}, error: {Error}, completed: {Completed}, canceled: {Canceled}, outputSpeed: {Speed} records/s",
// running, error, completed, canceled, outputSpeed);
2024-01-29 09:29:16 +08:00
foreach (var logger in _monitorLoggers)
{
2024-12-10 14:03:09 +08:00
var memory = GC.GetTotalMemory(false) / 1024 / 1024;
_context.MaxMemoryUsage = Math.Max(_context.MaxMemoryUsage, memory);
logger.LogStatus("系统监控", new Dictionary<string, string>
2024-01-29 09:29:16 +08:00
{
{ "输入速度", _context.IsInputCompleted ? "OK" : $"{inputSpeed:F2}/s" },
{ "转换速度", _context.IsTransformCompleted ? "OK" : $"{transformSpeed:F2}/s" },
{ "输出速度", _context.IsOutputCompleted ? "OK" : $"{outputSpeed:F2}/s" },
{ "| 输入队列长度", _producerQueue.Count.ToString() },
{ "输出队列长度", _queuePool.Queues.Values.Sum(queue => queue.Count).ToString() },
{ "内存使用", $"{memory} MiB" },
2024-01-29 09:29:16 +08:00
});
2023-12-29 16:16:05 +08:00
2024-02-09 19:08:57 +08:00
var dict = _context.TableProgress
.ToDictionary(kv => kv.Key, kv => $"{kv.Value.input}:{kv.Value.output}");
logger.LogStatus("系统监控: 表处理进度(I:O)", dict, ITaskMonitorLogger.LogLevel.Progress);
logger.LogStatus("系统监控:输出队列状态",
_queuePool.Queues.ToDictionary(q => q.Key, q => q.Value.Count.ToString()),
ITaskMonitorLogger.LogLevel.Progress);
2024-12-10 14:03:09 +08:00
var sb = new StringBuilder("表处理进度:\n");
2024-02-10 17:12:26 +08:00
foreach (var kv in dict)
2024-02-09 19:08:57 +08:00
{
2024-02-10 17:12:26 +08:00
sb.Append(kv.Key).AppendLine(kv.Value);
2024-02-09 19:08:57 +08:00
}
2024-02-10 00:05:50 +08:00
2024-12-10 14:03:09 +08:00
sb.AppendLine($"数据记录字段的最大长度:{_producerQueue.LongestFieldCharCount}");
2024-02-09 19:08:57 +08:00
await File.WriteAllTextAsync(_outputPath, sb.ToString(), CancellationToken.None);
2024-01-29 09:29:16 +08:00
2024-02-10 17:12:26 +08:00
// logger.LogStatus("Monitor: Process count", new Dictionary<string, string>
// {
// {"Input", inputCount.ToString()},
// {"Transform", transformCount.ToString()},
// {"Output", outputCount.ToString()}
// }, ITaskMonitorLogger.LogLevel.Progress);
2024-01-29 09:29:16 +08:00
}
2024-02-09 19:08:57 +08:00
2024-01-29 09:29:16 +08:00
await Task.Delay(5000, stoppingToken);
2023-12-29 16:16:05 +08:00
lastTime = time;
lastInputCount = inputCount;
lastTransformCount = transformCount;
lastOutputCount = outputCount;
if (_context is { IsInputCompleted: true, IsTransformCompleted: true, IsOutputCompleted: true })
{
if (!endCheck)
{
endCheck = true;
goto EndCheck;
}
break;
}
}
}
2024-01-29 09:29:16 +08:00
2023-12-29 16:16:05 +08:00
}