|
|
@@ -5,202 +5,205 @@ using Masuit.Tools;
|
|
|
using Masuit.Tools.DateTimeExt;
|
|
|
using Masuit.Tools.Hardware;
|
|
|
using Masuit.Tools.Systems;
|
|
|
+using Microsoft.EntityFrameworkCore;
|
|
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
|
|
|
|
-namespace Masuit.MyBlogs.Core.Common
|
|
|
+namespace Masuit.MyBlogs.Core.Common;
|
|
|
+
|
|
|
+public interface IPerfCounter
|
|
|
{
|
|
|
- public interface IPerfCounter
|
|
|
- {
|
|
|
- public static ConcurrentLimitedQueue<PerformanceCounter> List { get; } = new(50000);
|
|
|
+ public static ConcurrentLimitedQueue<PerformanceCounter> List { get; } = new(50000);
|
|
|
|
|
|
- public static readonly DateTime StartTime = DateTime.Now;
|
|
|
+ public static readonly DateTime StartTime = DateTime.Now;
|
|
|
|
|
|
- public static void Init()
|
|
|
+ public static void Init()
|
|
|
+ {
|
|
|
+ Task.Run(() =>
|
|
|
{
|
|
|
- Task.Run(() =>
|
|
|
+ int errorCount = 0;
|
|
|
+ while (true)
|
|
|
{
|
|
|
- int errorCount = 0;
|
|
|
- while (true)
|
|
|
+ try
|
|
|
{
|
|
|
- try
|
|
|
- {
|
|
|
- List.Enqueue(GetCurrentPerformanceCounter());
|
|
|
- }
|
|
|
- catch (Exception e)
|
|
|
+ List.Enqueue(GetCurrentPerformanceCounter());
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ if (errorCount > 20)
|
|
|
{
|
|
|
- if (errorCount > 20)
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
- Console.ForegroundColor = ConsoleColor.Red;
|
|
|
- Console.WriteLine(e.Message);
|
|
|
- Console.ForegroundColor = ConsoleColor.White;
|
|
|
- errorCount++;
|
|
|
+ break;
|
|
|
}
|
|
|
- Thread.Sleep(5000);
|
|
|
+ Console.ForegroundColor = ConsoleColor.Red;
|
|
|
+ Console.WriteLine(e.Message);
|
|
|
+ Console.ForegroundColor = ConsoleColor.White;
|
|
|
+ errorCount++;
|
|
|
}
|
|
|
- });
|
|
|
- }
|
|
|
+ Thread.Sleep(5000);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
- public static PerformanceCounter GetCurrentPerformanceCounter()
|
|
|
+ public static PerformanceCounter GetCurrentPerformanceCounter()
|
|
|
+ {
|
|
|
+ var time = DateTime.Now.GetTotalMilliseconds();
|
|
|
+ var load = SystemInfo.CpuLoad;
|
|
|
+ var mem = (1 - SystemInfo.MemoryAvailable.ConvertTo<float>() / SystemInfo.PhysicalMemory.ConvertTo<float>()) * 100;
|
|
|
+
|
|
|
+ var read = SystemInfo.GetDiskData(DiskData.Read) / 1024f;
|
|
|
+ var write = SystemInfo.GetDiskData(DiskData.Write) / 1024;
|
|
|
+
|
|
|
+ var up = SystemInfo.GetNetData(NetData.Received) / 1024;
|
|
|
+ var down = SystemInfo.GetNetData(NetData.Sent) / 1024;
|
|
|
+ return new PerformanceCounter()
|
|
|
{
|
|
|
- var time = DateTime.Now.GetTotalMilliseconds();
|
|
|
- var load = SystemInfo.CpuLoad;
|
|
|
- var mem = (1 - SystemInfo.MemoryAvailable.ConvertTo<float>() / SystemInfo.PhysicalMemory.ConvertTo<float>()) * 100;
|
|
|
+ Time = time,
|
|
|
+ CpuLoad = load,
|
|
|
+ MemoryUsage = mem,
|
|
|
+ DiskRead = read,
|
|
|
+ DiskWrite = write,
|
|
|
+ Download = down,
|
|
|
+ Upload = up
|
|
|
+ };
|
|
|
+ }
|
|
|
|
|
|
- var read = SystemInfo.GetDiskData(DiskData.Read) / 1024f;
|
|
|
- var write = SystemInfo.GetDiskData(DiskData.Write) / 1024;
|
|
|
+ IQueryable<PerformanceCounter> CreateDataSource();
|
|
|
|
|
|
- var up = SystemInfo.GetNetData(NetData.Received) / 1024;
|
|
|
- var down = SystemInfo.GetNetData(NetData.Sent) / 1024;
|
|
|
- return new PerformanceCounter()
|
|
|
- {
|
|
|
- Time = time,
|
|
|
- CpuLoad = load,
|
|
|
- MemoryUsage = mem,
|
|
|
- DiskRead = read,
|
|
|
- DiskWrite = write,
|
|
|
- Download = down,
|
|
|
- Upload = up
|
|
|
- };
|
|
|
- }
|
|
|
+ void Process();
|
|
|
+}
|
|
|
|
|
|
- IQueryable<PerformanceCounter> CreateDataSource();
|
|
|
+public class DefaultPerfCounter : IPerfCounter
|
|
|
+{
|
|
|
+ static DefaultPerfCounter()
|
|
|
+ {
|
|
|
+ }
|
|
|
|
|
|
- void Process();
|
|
|
+ public IQueryable<PerformanceCounter> CreateDataSource()
|
|
|
+ {
|
|
|
+ return IPerfCounter.List.AsQueryable();
|
|
|
}
|
|
|
|
|
|
- public class DefaultPerfCounter : IPerfCounter
|
|
|
+ public void Process()
|
|
|
{
|
|
|
- static DefaultPerfCounter()
|
|
|
- {
|
|
|
- }
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- public IQueryable<PerformanceCounter> CreateDataSource()
|
|
|
- {
|
|
|
- return IPerfCounter.List.AsQueryable();
|
|
|
- }
|
|
|
+public class PerfCounterInDatabase : IPerfCounter
|
|
|
+{
|
|
|
+ public static ConcurrentLimitedQueue<PerformanceCounter> List { get; } = new(50000);
|
|
|
|
|
|
- public void Process()
|
|
|
- {
|
|
|
- }
|
|
|
- }
|
|
|
+ private readonly LoggerDbContext _dbContext;
|
|
|
|
|
|
- public class PerfCounterInDatabase : IPerfCounter
|
|
|
+ public PerfCounterInDatabase(LoggerDbContext dbContext)
|
|
|
{
|
|
|
- public static ConcurrentLimitedQueue<PerformanceCounter> List { get; } = new(50000);
|
|
|
+ _dbContext = dbContext;
|
|
|
+ }
|
|
|
|
|
|
- private readonly LoggerDbContext _dbContext;
|
|
|
+ public IQueryable<PerformanceCounter> CreateDataSource()
|
|
|
+ {
|
|
|
+ return _dbContext.Set<PerformanceCounter>();
|
|
|
+ }
|
|
|
|
|
|
- public PerfCounterInDatabase(LoggerDbContext dbContext)
|
|
|
+ public void Process()
|
|
|
+ {
|
|
|
+ if (Debugger.IsAttached)
|
|
|
{
|
|
|
- _dbContext = dbContext;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- public IQueryable<PerformanceCounter> CreateDataSource()
|
|
|
+ while (IPerfCounter.List.TryDequeue(out var result))
|
|
|
{
|
|
|
- return _dbContext.Set<PerformanceCounter>();
|
|
|
+ _dbContext.Add(result);
|
|
|
}
|
|
|
|
|
|
- public void Process()
|
|
|
+ if (_dbContext.SaveChanges() > 0)
|
|
|
{
|
|
|
- if (Debugger.IsAttached)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- while (IPerfCounter.List.TryDequeue(out var result))
|
|
|
- {
|
|
|
- _dbContext.Add(result);
|
|
|
- }
|
|
|
-
|
|
|
- _dbContext.SaveChanges();
|
|
|
var start = DateTime.Now.AddMonths(-6).GetTotalMilliseconds();
|
|
|
- _dbContext.Set<PerformanceCounter>().Where(e => e.Time < start).DeleteFromQuery();
|
|
|
+ var tableName = _dbContext.Model.FindEntityType(typeof(PerformanceCounter)).GetTableName();
|
|
|
+ _dbContext.Database.ExecuteSqlRaw($"DELETE FROM \"{tableName}\" WHERE \"{nameof(PerformanceCounter.Time)}\" <{start}");
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- public class PerfCounterBackService : BackgroundService
|
|
|
- {
|
|
|
- private readonly IPerfCounter _manager;
|
|
|
+public class PerfCounterBackService : ScheduledService
|
|
|
+{
|
|
|
+ private readonly IServiceScopeFactory _serviceScopeFactory;
|
|
|
|
|
|
- public PerfCounterBackService(IPerfCounter manager)
|
|
|
- {
|
|
|
- _manager = manager;
|
|
|
- }
|
|
|
+ public PerfCounterBackService(IServiceScopeFactory serviceScopeFactory) : base(TimeSpan.FromSeconds(5))
|
|
|
+ {
|
|
|
+ _serviceScopeFactory = serviceScopeFactory;
|
|
|
+ }
|
|
|
|
|
|
- protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
|
- {
|
|
|
- while (true)
|
|
|
- {
|
|
|
- _manager.Process();
|
|
|
- await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
|
|
|
- }
|
|
|
- }
|
|
|
+ protected override Task ExecuteAsync()
|
|
|
+ {
|
|
|
+ using var scope = _serviceScopeFactory.CreateAsyncScope();
|
|
|
+ var counter = scope.ServiceProvider.GetRequiredService<IPerfCounter>();
|
|
|
+ counter.Process();
|
|
|
+ return Task.CompletedTask;
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- public static class PerfCounterServiceExtension
|
|
|
+public static class PerfCounterServiceExtension
|
|
|
+{
|
|
|
+ public static IServiceCollection AddPerfCounterManager(this IServiceCollection services, IConfiguration configuration)
|
|
|
{
|
|
|
- public static IServiceCollection AddPerfCounterManager(this IServiceCollection services, IConfiguration configuration)
|
|
|
+ IPerfCounter.Init();
|
|
|
+ switch (configuration["PerfCounterStorage"])
|
|
|
{
|
|
|
- IPerfCounter.Init();
|
|
|
- switch (configuration["PerfCounterStorage"])
|
|
|
- {
|
|
|
- case "database":
|
|
|
- services.AddScoped<IPerfCounter, PerfCounterInDatabase>();
|
|
|
- services.TryAddScoped<PerfCounterInDatabase>();
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- services.AddSingleton<IPerfCounter, DefaultPerfCounter>();
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- services.AddHostedService<PerfCounterBackService>();
|
|
|
- return services;
|
|
|
+ case "database":
|
|
|
+ services.AddScoped<IPerfCounter, PerfCounterInDatabase>();
|
|
|
+ services.TryAddScoped<PerfCounterInDatabase>();
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ services.AddSingleton<IPerfCounter, DefaultPerfCounter>();
|
|
|
+ break;
|
|
|
}
|
|
|
+
|
|
|
+ services.Configure<HostOptions>(options => options.BackgroundServiceExceptionBehavior = BackgroundServiceExceptionBehavior.Ignore);
|
|
|
+ services.AddHostedService<PerfCounterBackService>();
|
|
|
+ return services;
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
+/// <summary>
|
|
|
+/// 性能计数器
|
|
|
+/// </summary>
|
|
|
+[Table(nameof(PerformanceCounter))]
|
|
|
+public class PerformanceCounter
|
|
|
+{
|
|
|
/// <summary>
|
|
|
- /// 性能计数器
|
|
|
+ /// 当前时间戳
|
|
|
/// </summary>
|
|
|
- [Table(nameof(PerformanceCounter))]
|
|
|
- public class PerformanceCounter
|
|
|
- {
|
|
|
- /// <summary>
|
|
|
- /// 当前时间戳
|
|
|
- /// </summary>
|
|
|
- [HypertableColumn]
|
|
|
- public long Time { get; set; }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// CPU当前负载
|
|
|
- /// </summary>
|
|
|
- public float CpuLoad { get; set; }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 内存使用率
|
|
|
- /// </summary>
|
|
|
- public float MemoryUsage { get; set; }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 磁盘读
|
|
|
- /// </summary>
|
|
|
- public float DiskRead { get; set; }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 磁盘写
|
|
|
- /// </summary>
|
|
|
- public float DiskWrite { get; set; }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 网络上行
|
|
|
- /// </summary>
|
|
|
- public float Upload { get; set; }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 网络下行
|
|
|
- /// </summary>
|
|
|
- public float Download { get; set; }
|
|
|
- }
|
|
|
+ [HypertableColumn]
|
|
|
+ public long Time { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// CPU当前负载
|
|
|
+ /// </summary>
|
|
|
+ public float CpuLoad { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 内存使用率
|
|
|
+ /// </summary>
|
|
|
+ public float MemoryUsage { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 磁盘读
|
|
|
+ /// </summary>
|
|
|
+ public float DiskRead { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 磁盘写
|
|
|
+ /// </summary>
|
|
|
+ public float DiskWrite { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 网络上行
|
|
|
+ /// </summary>
|
|
|
+ public float Upload { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 网络下行
|
|
|
+ /// </summary>
|
|
|
+ public float Download { get; set; }
|
|
|
}
|