监控模块 优化
This commit is contained in:
+48
-16
@@ -27,24 +27,24 @@ internal static class Program
|
||||
// 无参数 → 默认 serve(最常见用法)
|
||||
if (args.Length == 0)
|
||||
{
|
||||
return await ServeAsync(DefaultPort, basic: true, DefaultFastMs, DefaultSlowMs);
|
||||
return await ServeAsync(DefaultPort, null, DefaultFastMs, DefaultSlowMs, null);
|
||||
}
|
||||
|
||||
// serve 子命令
|
||||
var serveCmd = new Command("serve", "启动 HTTP 服务");
|
||||
var portOpt = new Option<int>("--port", () => DefaultPort, "监听端口");
|
||||
var basicOpt = new Option<bool>("--basic", "仅启用核心四类硬件,降低冷启动耗时");
|
||||
var fullOpt = new Option<bool>("--full", "启用全部硬件(含主板/控制器/网络等)");
|
||||
var configOpt = new Option<FileInfo?>("--config", "硬件监控配置文件路径(JSON)");
|
||||
var fastOpt = new Option<int>("--fast-ms", () => DefaultFastMs, "快通道采样间隔(毫秒)");
|
||||
var slowOpt = new Option<int>("--slow-ms", () => DefaultSlowMs, "慢通道采样间隔(毫秒)");
|
||||
var logFileOpt = new Option<FileInfo?>("--log-file", "将 stderr 日志写入指定文件(提权模式下控制台隐藏时使用)");
|
||||
serveCmd.AddOption(portOpt);
|
||||
serveCmd.AddOption(basicOpt);
|
||||
serveCmd.AddOption(fullOpt);
|
||||
serveCmd.AddOption(configOpt);
|
||||
serveCmd.AddOption(fastOpt);
|
||||
serveCmd.AddOption(slowOpt);
|
||||
serveCmd.SetHandler((port, basic, full, fast, slow) =>
|
||||
ServeAsync(port, basic || !full, fast, slow),
|
||||
portOpt, basicOpt, fullOpt, fastOpt, slowOpt);
|
||||
serveCmd.AddOption(logFileOpt);
|
||||
serveCmd.SetHandler((port, config, fast, slow, logFile) =>
|
||||
ServeAsync(port, config?.FullName, fast, slow, logFile),
|
||||
portOpt, configOpt, fastOpt, slowOpt, logFileOpt);
|
||||
|
||||
// scan 子命令(阶段一覆盖矩阵测试,保留)
|
||||
var scanCmd = new Command("scan", "扫描一次并输出覆盖矩阵(阶段一验证用)");
|
||||
@@ -58,17 +58,37 @@ internal static class Program
|
||||
root.Add(serveCmd);
|
||||
root.Add(scanCmd);
|
||||
// 兼容阶段一的旧用法:ThingHK.exe --json --basic
|
||||
root.SetHandler(() => ServeAsync(DefaultPort, basic: true, DefaultFastMs, DefaultSlowMs));
|
||||
root.SetHandler(() => ServeAsync(DefaultPort, null, DefaultFastMs, DefaultSlowMs, null));
|
||||
|
||||
return await root.InvokeAsync(args);
|
||||
}
|
||||
|
||||
private static async Task<int> ServeAsync(int port, bool basic, int fastMs, int slowMs)
|
||||
private static async Task<int> ServeAsync(int port, string? configPath, int fastMs, int slowMs, FileInfo? logFile)
|
||||
{
|
||||
Console.Error.WriteLine($"[ThingHK] serve 模式: port={port} basic={basic} fast={fastMs}ms slow={slowMs}ms");
|
||||
// 如果指定了 --log-file,将 stderr 重定向到文件(提权模式下控制台隐藏,需要日志排查崩溃)
|
||||
if (logFile != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var logStream = new StreamWriter(logFile.Open(FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||
{
|
||||
AutoFlush = true,
|
||||
};
|
||||
Console.SetError(logStream);
|
||||
// 同时重定向 stdout(避免 ASP.NET 的某些输出到 stdout)
|
||||
Console.SetOut(logStream);
|
||||
Console.Error.WriteLine($"[ThingHK] 日志输出到: {logFile.FullName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine($"[ThingHK] 无法写入日志文件 {logFile.FullName}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
Console.Error.WriteLine($"[ThingHK] serve 模式: port={port} config={configPath ?? "(默认)"} fast={fastMs}ms slow={slowMs}ms");
|
||||
|
||||
using var kernel = new KernelHost();
|
||||
await kernel.StartAsync(basic, fastMs, slowMs);
|
||||
await kernel.StartAsync(configPath, fastMs, slowMs);
|
||||
|
||||
var builder = WebApplication.CreateBuilder();
|
||||
builder.WebHost.UseUrls($"http://127.0.0.1:{port}/");
|
||||
@@ -78,15 +98,16 @@ internal static class Program
|
||||
builder.Logging.AddProvider(new StderrLoggerProvider());
|
||||
|
||||
var app = builder.Build();
|
||||
app.MapThingHKEndpoints(kernel);
|
||||
|
||||
// Ctrl+C 优雅关闭
|
||||
// Ctrl+C 优雅关闭(cts 同时用于 /shutdown 接口触发退出)
|
||||
var cts = new CancellationTokenSource();
|
||||
Console.CancelKeyPress += (_, e) => { e.Cancel = true; cts.Cancel(); };
|
||||
AppDomain.CurrentDomain.ProcessExit += (_, _) => cts.Cancel();
|
||||
|
||||
app.MapThingHKEndpoints(kernel, cts);
|
||||
|
||||
Console.Error.WriteLine($"[ThingHK] HTTP 服务监听: http://127.0.0.1:{port}/");
|
||||
Console.Error.WriteLine("[ThingHK] 路由: GET / GET /status GET /snapshot GET /stream POST /config");
|
||||
Console.Error.WriteLine("[ThingHK] 路由: GET / GET /status GET /snapshot GET /stream POST /config POST /shutdown");
|
||||
|
||||
try
|
||||
{
|
||||
@@ -103,7 +124,18 @@ internal static class Program
|
||||
private static async Task<int> ScanAsync(bool json, bool basic)
|
||||
{
|
||||
Console.Error.WriteLine($"[ThingHK] scan 模式: json={json} basic={basic}");
|
||||
using var hw = new HardwareManager(basic);
|
||||
// scan 命令保留旧 basic 参数:basic=true 用默认配置,basic=false 用全部启用配置
|
||||
var config = basic ? HardwareConfig.Default : new HardwareConfig
|
||||
{
|
||||
Hardware = new Dictionary<string, bool>
|
||||
{
|
||||
["cpu"] = true, ["gpu"] = true, ["memory"] = true, ["storage"] = true,
|
||||
["motherboard"] = true, ["controller"] = true, ["battery"] = true,
|
||||
["network"] = true, ["psu"] = true,
|
||||
},
|
||||
SensorTypes = HardwareConfig.Default.SensorTypes,
|
||||
};
|
||||
using var hw = new HardwareManager(config);
|
||||
|
||||
// 第二轮 Update:部分传感器首轮才初始化
|
||||
hw.UpdateAll();
|
||||
|
||||
Reference in New Issue
Block a user