root 1 month ago
parent
commit
fb9eb80cba
  1. 96
      LTEMvcApp/Services/WebSocketManagerService.cs
  2. 46
      LTEMvcApp/Views/Home/TestClientConfig.cshtml

96
LTEMvcApp/Services/WebSocketManagerService.cs

@ -7,6 +7,8 @@ using LTEMvcApp.Models;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.IO;
using System.Text.Json;
namespace LTEMvcApp.Services namespace LTEMvcApp.Services
{ {
@ -25,6 +27,7 @@ namespace LTEMvcApp.Services
private ClientConfig _testClientConfig; private ClientConfig _testClientConfig;
private const int LogCacheSize = 10000; // 服务器最多缓存10000条最新日志 private const int LogCacheSize = 10000; // 服务器最多缓存10000条最新日志
private readonly ConcurrentQueue<LTELog> _logCache = new ConcurrentQueue<LTELog>(); private readonly ConcurrentQueue<LTELog> _logCache = new ConcurrentQueue<LTELog>();
private readonly string _configFilePath = "test_client_config.json";
#endregion #endregion
@ -65,41 +68,87 @@ namespace LTEMvcApp.Services
_logger = logger; _logger = logger;
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
// 初始化测试客户端配置 LoadTestClientConfig();
_testClientConfig = new ClientConfig
_logger.LogInformation("WebSocketManagerService 初始化");
}
/// <summary>
/// 加载测试客户端配置
/// </summary>
private void LoadTestClientConfig()
{
try
{
if (File.Exists(_configFilePath))
{
var json = File.ReadAllText(_configFilePath);
_testClientConfig = JsonSerializer.Deserialize<ClientConfig>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true })!;
_logger.LogInformation("成功从 {FilePath} 加载测试客户端配置。", _configFilePath);
}
else
{
_logger.LogWarning("配置文件 {FilePath} 未找到,将创建并使用默认配置。", _configFilePath);
_testClientConfig = GetDefaultTestConfig();
SaveTestClientConfig();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "加载或创建测试客户端配置文件时出错。将使用默认配置。");
_testClientConfig = GetDefaultTestConfig();
}
}
/// <summary>
/// 保存测试客户端配置到文件
/// </summary>
private void SaveTestClientConfig()
{
try
{
var options = new JsonSerializerOptions { WriteIndented = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
var json = JsonSerializer.Serialize(_testClientConfig, options);
File.WriteAllText(_configFilePath, json);
_logger.LogInformation("测试客户端配置已成功保存到 {FilePath}。", _configFilePath);
}
catch (Exception ex)
{
_logger.LogError(ex, "保存测试客户端配置文件失败。");
}
}
private ClientConfig GetDefaultTestConfig()
{
return new ClientConfig
{ {
Name = "TestClient", Name = "TestClient",
Enabled = true, Enabled = true,
Address = "192.168.13.12:9001", Address = "192.168.13.12:9001",
Ssl = false, Ssl = false,
ReconnectDelay = 15000, ReconnectDelay = 15000,
Pause = false, Password = "test123",
Readonly = false,
SkipLogMenu = false,
Locked = false,
Active = true,
Logs = new Dictionary<string, object> Logs = new Dictionary<string, object>
{ {
["layers"] = new Dictionary<string, object> ["layers"] = new Dictionary<string, object>
{ {
["PHY"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = true, ["filter"] = "info" }, ["PHY"] = new LogLayerConfig { Level = "info", Filter = "warn", MaxSize = 1000, Payload = true },
["MAC"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = true, ["filter"] = "info" }, ["MAC"] = new LogLayerConfig { Level = "info", Filter = "warn", MaxSize = 1000, Payload = true },
["RLC"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = false, ["filter"] = "info" }, ["RLC"] = new LogLayerConfig { Level = "info", Filter = "warn", MaxSize = 1000, Payload = false },
["PDCP"] = new Dictionary<string, object> { ["level"] = "warn", ["max_size"] = 1, ["payload"] = false, ["filter"] = "warn" }, ["PDCP"] = new LogLayerConfig { Level = "warn", Filter = "warn", MaxSize = 1000, Payload = false },
["RRC"] = new Dictionary<string, object> { ["level"] = "debug", ["max_size"] = 1, ["payload"] = true, ["filter"] = "debug" }, ["RRC"] = new LogLayerConfig { Level = "debug", Filter = "warn", MaxSize = 1000, Payload = true },
["NAS"] = new Dictionary<string, object> { ["level"] = "debug", ["max_size"] = 1, ["payload"] = true, ["filter"] = "debug" }, ["NAS"] = new LogLayerConfig { Level = "debug", Filter = "warn", MaxSize = 1000, Payload = true },
["S1AP"] = new Dictionary<string, object> { ["level"] = "debug", ["max_size"] = 1, ["payload"] = false, ["filter"] = "debug" }, ["S1AP"] = new LogLayerConfig { Level = "debug", Filter = "warn", MaxSize = 1000, Payload = false },
["NGAP"] = new Dictionary<string, object> { ["level"] = "debug", ["max_size"] = 1, ["payload"] = false, ["filter"] = "debug" }, ["NGAP"] = new LogLayerConfig { Level = "debug", Filter = "warn", MaxSize = 1000, Payload = false },
["GTPU"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = false, ["filter"] = "info" }, ["GTPU"] = new LogLayerConfig { Level = "info", Filter = "warn", MaxSize = 1000, Payload = false },
["X2AP"] = new Dictionary<string, object> { ["level"] = "debug", ["max_size"] = 1, ["payload"] = false, ["filter"] = "debug" }, ["X2AP"] = new LogLayerConfig { Level = "debug", Filter = "warn", MaxSize = 1000, Payload = false },
["XnAP"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = false, ["filter"] = "info" }, ["XnAP"] = new LogLayerConfig { Level = "info", Filter = "warn", MaxSize = 1000, Payload = false },
["M2AP"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = false, ["filter"] = "info" }, ["M2AP"] = new LogLayerConfig { Level = "info", Filter = "warn", MaxSize = 1000, Payload = false }
["EVENT"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = false, ["filter"] = "info" } },
} ["signal"] = true,
["cch"] = true
} }
}; };
_logger.LogInformation("WebSocketManagerService 初始化");
} }
#endregion #endregion
@ -408,6 +457,7 @@ namespace LTEMvcApp.Services
_logger.LogInformation($"更新测试客户端配置: {config.Name}"); _logger.LogInformation($"更新测试客户端配置: {config.Name}");
_testClientConfig = config; _testClientConfig = config;
SaveTestClientConfig();
return true; return true;
} }

46
LTEMvcApp/Views/Home/TestClientConfig.cshtml

@ -3,40 +3,30 @@
var testConfig = ViewBag.TestConfig as LTEMvcApp.Models.ClientConfig; var testConfig = ViewBag.TestConfig as LTEMvcApp.Models.ClientConfig;
// 只保留不含 EVENT 的日志层 // 只保留不含 EVENT 的日志层
var allLayers = LTEMvcApp.Models.LogLayerTypes.AllLayers.Where(l => l != "EVENT").ToArray(); var allLayers = LTEMvcApp.Models.LogLayerTypes.AllLayers.Where(l => l != "EVENT").ToArray();
var layerConfigs = new Dictionary<string, Dictionary<string, object>>(); var layerConfigs = new Dictionary<string, LTEMvcApp.Models.LogLayerConfig>();
if (testConfig?.Logs?.ContainsKey("layers") == true && testConfig.Logs["layers"] is Dictionary<string, object> layers)
if (testConfig?.Logs?.ContainsKey("layers") == true && testConfig.Logs["layers"] is System.Text.Json.JsonElement layersElement)
{ {
foreach (var layer in allLayers) var layers = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, LTEMvcApp.Models.LogLayerConfig>>(layersElement.GetRawText(), new System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true })
?? new Dictionary<string, LTEMvcApp.Models.LogLayerConfig>();
foreach (var layerName in allLayers)
{ {
var config = new Dictionary<string, object>(); if (layers.TryGetValue(layerName, out var config))
if (layers.ContainsKey(layer) && layers[layer] is Dictionary<string, object> layerConfig)
{ {
config["level"] = layerConfig.ContainsKey("level") ? layerConfig["level"]?.ToString() : LTEMvcApp.Models.LogLayerTypes.GetDefaultLevel(layer); layerConfigs[layerName] = config;
config["filter"] = layerConfig.ContainsKey("filter") ? layerConfig["filter"]?.ToString() : "warn";
config["maxSize"] = layerConfig.ContainsKey("max_size") && layerConfig["max_size"] != null ? Convert.ToInt32(layerConfig["max_size"]) : 1;
config["payload"] = layerConfig.ContainsKey("payload") && layerConfig["payload"] != null ? Convert.ToBoolean(layerConfig["payload"]) : false;
} }
else else
{ {
config["level"] = LTEMvcApp.Models.LogLayerTypes.GetDefaultLevel(layer); layerConfigs[layerName] = new LTEMvcApp.Models.LogLayerConfig { Level = LTEMvcApp.Models.LogLayerTypes.GetDefaultLevel(layerName) };
config["filter"] = "warn";
config["maxSize"] = 1;
config["payload"] = false;
} }
layerConfigs[layer] = config;
} }
} }
else else
{ {
foreach (var layer in allLayers) foreach (var layerName in allLayers)
{ {
layerConfigs[layer] = new Dictionary<string, object> layerConfigs[layerName] = new LTEMvcApp.Models.LogLayerConfig { Level = LTEMvcApp.Models.LogLayerTypes.GetDefaultLevel(layerName) };
{
["level"] = LTEMvcApp.Models.LogLayerTypes.GetDefaultLevel(layer),
["filter"] = "warn",
["maxSize"] = 1,
["payload"] = false
};
} }
} }
} }
@ -127,17 +117,13 @@
@foreach (var layer in allLayers) @foreach (var layer in allLayers)
{ {
var config = layerConfigs[layer]; var config = layerConfigs[layer];
var level = config["level"]?.ToString();
var filter = config["filter"]?.ToString();
var maxSize = Convert.ToInt32(config["maxSize"]);
var payload = Convert.ToBoolean(config["payload"]);
<tr> <tr>
<td><strong>@layer</strong></td> <td><strong>@layer</strong></td>
<td> <td>
<select class="form-control form-control-sm" name="layers[@layer][level]"> <select class="form-control form-control-sm" name="layers[@layer][level]">
@foreach (var logLevel in LTEMvcApp.Models.LogLayerTypes.LogLevels) @foreach (var logLevel in LTEMvcApp.Models.LogLayerTypes.LogLevels)
{ {
if (logLevel == level) if (logLevel == config.Level)
{ {
<option value="@logLevel" selected>@logLevel.ToUpper()</option> <option value="@logLevel" selected>@logLevel.ToUpper()</option>
} }
@ -152,7 +138,7 @@
<select class="form-control form-control-sm" name="layers[@layer][filter]"> <select class="form-control form-control-sm" name="layers[@layer][filter]">
@foreach (var logLevel in LTEMvcApp.Models.LogLayerTypes.LogLevels) @foreach (var logLevel in LTEMvcApp.Models.LogLayerTypes.LogLevels)
{ {
if (logLevel == filter) if (logLevel == config.Filter)
{ {
<option value="@logLevel" selected>@logLevel.ToUpper()</option> <option value="@logLevel" selected>@logLevel.ToUpper()</option>
} }
@ -164,11 +150,11 @@
</select> </select>
</td> </td>
<td> <td>
<input type="number" class="form-control form-control-sm" name="layers[@layer][max_size]" value="@maxSize" min="1" max="1000"> <input type="number" class="form-control form-control-sm" name="layers[@layer][max_size]" value="@config.MaxSize" min="1" max="1000">
</td> </td>
<td> <td>
<div class="form-check"> <div class="form-check">
<input type="checkbox" class="form-check-input" name="layers[@layer][payload]" @(payload ? "checked" : "")> <input type="checkbox" class="form-check-input" name="layers[@layer][payload]" @(config.Payload ? "checked" : "")>
</div> </div>
</td> </td>
</tr> </tr>

Loading…
Cancel
Save