diff --git a/LTEMvcApp/Models/LTEClient.cs b/LTEMvcApp/Models/LTEClient.cs
index c3a79bd..9efd851 100644
--- a/LTEMvcApp/Models/LTEClient.cs
+++ b/LTEMvcApp/Models/LTEClient.cs
@@ -287,32 +287,28 @@ public class LTEClient
#endregion
- #region 解析器私有字段
+ #region 依赖注入
///
- /// 字符串到ID的映射缓存
+ /// 日志管理器
///
- private readonly Dictionary _stringToIdCache = new();
+ private readonly LogsManager _logsManager;
///
- /// ID到字符串的映射缓存
+ /// 获取日志管理器实例
///
- private readonly Dictionary _idToStringCache = new();
-
- ///
- /// 字符串ID计数器
- ///
- private int _stringIdCounter = 0;
+ public LogsManager LogsManager => _logsManager;
#endregion
#region 构造函数
- public LTEClient(ClientConfig config)
+ public LTEClient(ClientConfig config, LogsManager logsManager)
{
Config = config;
Name = config.Name;
ClientId = GenerateClientId();
+ _logsManager = logsManager;
ResetParserState();
}
@@ -320,11 +316,13 @@ public class LTEClient
/// 使用名称创建客户端
///
/// 客户端名称
- public LTEClient(string name)
+ /// 日志管理器
+ public LTEClient(string name, LogsManager logsManager)
{
Config = new ClientConfig { Name = name, Enabled = true };
Name = name;
ClientId = GenerateClientId();
+ _logsManager = logsManager;
ResetParserState();
}
@@ -436,27 +434,19 @@ public class LTEClient
}
///
- /// 字符串转ID
+ /// 字符串转ID - 委托给LogsManager
///
public int StringToId(string str)
{
- if (_stringToIdCache.TryGetValue(str, out var id))
- {
- return id;
- }
-
- id = ++_stringIdCounter;
- _stringToIdCache[str] = id;
- _idToStringCache[id] = str;
- return id;
+ return _logsManager.String2Id(str);
}
///
- /// ID转字符串
+ /// ID转字符串 - 委托给LogsManager
///
public string IdToString(int id)
{
- return _idToStringCache.TryGetValue(id, out var str) ? str : "";
+ return _logsManager.Id2String(id);
}
#endregion
@@ -969,10 +959,8 @@ public class LTEClient
TimestampOffset = 0;
LastCell = null;
- // 重置解析器缓存
- _stringToIdCache.Clear();
- _idToStringCache.Clear();
- _stringIdCounter = 0;
+ // 注意:LogsManager 的字符串ID缓存是全局的,不需要重置
+ // 这样可以保持字符串ID的一致性
}
///
diff --git a/LTEMvcApp/Models/LogChannelConfig.cs b/LTEMvcApp/Models/LogChannelConfig.cs
deleted file mode 100644
index 4defd7c..0000000
--- a/LTEMvcApp/Models/LogChannelConfig.cs
+++ /dev/null
@@ -1,121 +0,0 @@
-namespace LTEMvcApp.Models
-{
- ///
- /// 日志信道配置
- ///
- public static class LogChannelConfig
- {
- ///
- /// 信道定义列表
- ///
- public static readonly List ChannelDefinitions = new()
- {
- new() { Name = "PRACH", Color = "#ffff00" },
- new() { Name = "NPRACH", Color = "#ffff00" },
- new() { Name = "SRS", Color = "#ffff80" },
- new() { Name = "PUCCH", Color = "#00ff00" },
- new() { Name = "PUSCH", Color = "#ff0000" },
- new() { Name = "NPUSCH", Color = "#ff0000" },
- new() { Name = "PDSCH", Color = "#0000ff" },
- new() { Name = "NPDSCH", Color = "#0000ff" },
- new() { Name = "PDCCH", Color = "#00ffff" },
- new() { Name = "EPDCCH", Color = "#00ffff" },
- new() { Name = "NPDCCH", Color = "#00ffff" },
- new() { Name = "PMCH", Color = "#ff80ff" },
- new() { Name = "INV", Color = "#D0D0D0" }
- };
-
- ///
- /// 信道定义字典(按名称索引)
- ///
- public static readonly Dictionary ChannelsByName = ChannelDefinitions
- .ToDictionary(c => c.Name, c => c);
-
- ///
- /// 信道定义字典(按ID索引)
- ///
- public static readonly Dictionary ChannelsById = ChannelDefinitions
- .Select((c, i) => new { Channel = c, Index = i })
- .ToDictionary(x => x.Index, x => x.Channel);
-
- ///
- /// 获取信道定义
- ///
- /// 信道名称
- /// 信道定义
- public static ChannelDefinition? GetChannelByName(string name)
- {
- return ChannelsByName.TryGetValue(name, out var channel) ? channel : null;
- }
-
- ///
- /// 获取信道定义
- ///
- /// 信道ID
- /// 信道定义
- public static ChannelDefinition? GetChannelById(int id)
- {
- return ChannelsById.TryGetValue(id, out var channel) ? channel : null;
- }
-
- ///
- /// 获取所有信道名称
- ///
- /// 信道名称列表
- public static List GetAllChannelNames()
- {
- return ChannelDefinitions.Select(c => c.Name).ToList();
- }
-
- ///
- /// 验证信道名称是否有效
- ///
- /// 信道名称
- /// 是否有效
- public static bool IsValidChannel(string name)
- {
- return ChannelsByName.ContainsKey(name);
- }
-
- ///
- /// 获取信道ID
- ///
- /// 信道名称
- /// 信道ID,如果不存在返回-1
- public static int GetChannelId(string name)
- {
- for (int i = 0; i < ChannelDefinitions.Count; i++)
- {
- if (ChannelDefinitions[i].Name == name)
- return i;
- }
- return -1;
- }
- }
-
- ///
- /// 信道定义
- ///
- public class ChannelDefinition
- {
- ///
- /// 信道名称
- ///
- public string Name { get; set; } = string.Empty;
-
- ///
- /// 颜色代码
- ///
- public string Color { get; set; } = "#000000";
-
- ///
- /// 信道ID
- ///
- public int Id { get; set; }
-
- ///
- /// 信道索引
- ///
- public int Index { get; set; }
- }
-}
\ No newline at end of file
diff --git a/LTEMvcApp/Models/LogConstants.cs b/LTEMvcApp/Models/LogConstants.cs
deleted file mode 100644
index a7e3e08..0000000
--- a/LTEMvcApp/Models/LogConstants.cs
+++ /dev/null
@@ -1,254 +0,0 @@
-namespace LTEMvcApp.Models
-{
- ///
- /// 日志常量
- ///
- public static class LogConstants
- {
- #region 全局常量
-
- ///
- /// 最大日志数量
- ///
- public const int LOGS_MAX = 2000000;
-
- ///
- /// 日志范围
- ///
- public static readonly List LOGS_RANGE = new();
-
- ///
- /// 日志信息
- ///
- public static readonly List LOGS_INFO = new();
-
- ///
- /// 日志层
- ///
- public static readonly List LOGS_LAYERS = new();
-
- ///
- /// 导出时间格式
- ///
- public static string EXPORT_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.fff";
-
- ///
- /// 是否启用内联缓存
- ///
- public static bool INLINE_CACHE_ENABLED = false;
-
- #endregion
-
- #region 应用模式
-
- ///
- /// 应用模式
- ///
- public static class AppMode
- {
- public const string Web = "web";
- public const string App = "app";
- }
-
- ///
- /// 导出模式
- ///
- public static class ExportMode
- {
- public const string Zip = "zip";
- public const string Text = "text";
- }
-
- #endregion
-
- #region 字体和样式
-
- ///
- /// 默认字体
- ///
- public const string DEFAULT_FONT = "13px helvetica, arial, verdana, sans-serif";
-
- ///
- /// 默认颜色
- ///
- public const string DEFAULT_COLOR = "#000000";
-
- #endregion
-
- #region 时间相关
-
- ///
- /// 时间戳基准(2000-01-01 00:00:00)
- ///
- public const long TIMESTAMP_BASE = 946681200000;
-
- ///
- /// 默认时间原点
- ///
- public const string DEFAULT_TIME_ORIGIN = "00:00:00.000";
-
- #endregion
-
- #region 客户端相关
-
- ///
- /// 默认重连延迟(毫秒)
- ///
- public const int DEFAULT_RECONNECT_DELAY = 2500;
-
- ///
- /// 默认重连延迟(毫秒)
- ///
- public const int DEFAULT_RECONNECT_DELAY_APP = 5000;
-
- ///
- /// HFN回绕阈值
- ///
- public const int HFN_WRAP_THRESHOLD = 512;
-
- #endregion
-
- #region 日志级别
-
- ///
- /// 日志级别名称
- ///
- public static readonly string[] LOG_LEVEL_NAMES = { "none", "error", "warn", "info", "debug" };
-
- ///
- /// 日志方法名称
- ///
- public static readonly string[] LOG_METHODS = { "error", "warn", "info", "debug", "prof" };
-
- #endregion
-
- #region 性能相关
-
- ///
- /// 大日志列表阈值
- ///
- public const int LARGE_LOG_THRESHOLD = 500000;
-
- ///
- /// 小日志列表阈值
- ///
- public const int SMALL_LOG_THRESHOLD = 50000;
-
- ///
- /// 日志模块列表最大长度
- ///
- public const int LOG_MODULE_LIST_MAX = 20;
-
- #endregion
-
- #region 文件相关
-
- ///
- /// 支持的文件类型
- ///
- public static class FileTypes
- {
- public const string Binary = "bin";
- public const string Base64 = "base64";
- }
-
- ///
- /// 文件大小单位
- ///
- public static class FileSizeUnits
- {
- public const string Kilobyte = "K";
- public const string Megabyte = "M";
- public const string Gigabyte = "G";
- }
-
- #endregion
-
- #region 正则表达式
-
- ///
- /// 参数解析正则表达式
- ///
- public const string PARAMS_REGEX = @"\s*([^=]+)=([^,\s]+)";
-
- #endregion
-
- #region 事件相关
-
- ///
- /// 事件类型
- ///
- public static class EventTypes
- {
- public const string NewLogs = "newLogs";
- public const string SelectLog = "selectLog";
- public const string All = "*";
- }
-
- #endregion
-
- #region 浏览器相关
-
- ///
- /// 鼠标滚轮事件
- ///
- public static class MouseWheelEvents
- {
- public const string Firefox = "DOMMouseScroll";
- public const string Other = "mousewheel";
- }
-
- #endregion
-
- #region 工具方法
-
- ///
- /// 获取日志级别名称
- ///
- /// 级别值
- /// 级别名称
- public static string GetLogLevelName(int level)
- {
- if (level >= 0 && level < LOG_LEVEL_NAMES.Length)
- return LOG_LEVEL_NAMES[level];
- return "unknown";
- }
-
- ///
- /// 获取日志级别值
- ///
- /// 级别名称
- /// 级别值
- public static int GetLogLevelValue(string levelName)
- {
- for (int i = 0; i < LOG_LEVEL_NAMES.Length; i++)
- {
- if (LOG_LEVEL_NAMES[i] == levelName)
- return i;
- }
- return -1;
- }
-
- ///
- /// 检查是否为持续时间戳
- ///
- /// 时间戳
- /// 是否为持续时间
- public static bool IsDurationTimestamp(long timestamp)
- {
- return timestamp < TIMESTAMP_BASE;
- }
-
- ///
- /// 获取默认重连延迟
- ///
- /// 应用模式
- /// 重连延迟
- public static int GetDefaultReconnectDelay(string mode)
- {
- return mode == AppMode.App ? DEFAULT_RECONNECT_DELAY_APP : DEFAULT_RECONNECT_DELAY;
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/LTEMvcApp/Models/LogDirection.cs b/LTEMvcApp/Models/LogDirection.cs
deleted file mode 100644
index ebf4e3f..0000000
--- a/LTEMvcApp/Models/LogDirection.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-namespace LTEMvcApp.Models
-{
- ///
- /// 日志传输方向常量
- ///
- public static class LogDirection
- {
- ///
- /// 无方向
- ///
- public const int None = 0;
-
- ///
- /// 上行传输
- ///
- public const int UL = 1;
-
- ///
- /// 下行传输
- ///
- public const int DL = 2;
-
- ///
- /// 从某处传输
- ///
- public const int From = 3;
-
- ///
- /// 传输到某处
- ///
- public const int To = 4;
-
- ///
- /// 获取方向名称
- ///
- /// 方向值
- /// 方向名称
- public static string GetDirectionName(int direction)
- {
- return direction switch
- {
- None => "-",
- UL => "UL",
- DL => "DL",
- From => "FROM",
- To => "TO",
- _ => "UNKNOWN"
- };
- }
-
- ///
- /// 获取所有方向选项
- ///
- /// 方向选项列表
- public static List GetDirectionOptions()
- {
- return new List
- {
- new() { Value = None, Text = "-" },
- new() { Value = DL, Text = "DL" },
- new() { Value = UL, Text = "UL" }
- };
- }
- }
-
- ///
- /// 方向选项
- ///
- public class DirectionOption
- {
- public int Value { get; set; }
- public string Text { get; set; } = string.Empty;
- }
-}
\ No newline at end of file
diff --git a/LTEMvcApp/Models/LogEventManager.cs b/LTEMvcApp/Models/LogEventManager.cs
deleted file mode 100644
index 9370f41..0000000
--- a/LTEMvcApp/Models/LogEventManager.cs
+++ /dev/null
@@ -1,229 +0,0 @@
-namespace LTEMvcApp.Models
-{
- ///
- /// 日志事件管理器
- ///
- public class LogEventManager
- {
- ///
- /// 事件监听器字典
- ///
- private readonly Dictionary _eventListeners = new();
-
- ///
- /// 事件监听器ID计数器
- ///
- private int _eventListenerId = 0;
-
- ///
- /// 注册事件监听器
- ///
- /// 事件类型
- /// 回调函数
- /// 监听器ID
- public int RegisterEventListener(string type, Action callback)
- {
- var id = _eventListenerId++;
- _eventListeners[id] = new EventListener
- {
- Type = type,
- Callback = callback
- };
- return id;
- }
-
- ///
- /// 注销事件监听器
- ///
- /// 监听器ID
- public void UnregisterEventListener(int id)
- {
- _eventListeners.Remove(id);
- }
-
- ///
- /// 发送事件
- ///
- /// 事件对象
- public void SendEvent(LogEvent @event)
- {
- var type = @event.Type;
- foreach (var kvp in _eventListeners)
- {
- var listener = kvp.Value;
- switch (listener.Type)
- {
- case var t when t == type:
- case LogConstants.EventTypes.All:
- listener.Callback(@event);
- break;
- }
- }
- }
-
- ///
- /// 发送新日志事件
- ///
- /// 日志列表
- public void SendNewLogsEvent(List logs)
- {
- SendEvent(new LogEvent
- {
- Type = LogConstants.EventTypes.NewLogs,
- Data = new { Logs = logs }
- });
- }
-
- ///
- /// 发送选择日志事件
- ///
- /// 选中的日志
- public void SendSelectLogEvent(LTELog log)
- {
- SendEvent(new LogEvent
- {
- Type = LogConstants.EventTypes.SelectLog,
- Data = new { Log = log }
- });
- }
-
- ///
- /// 清除所有事件监听器
- ///
- public void ClearAllListeners()
- {
- _eventListeners.Clear();
- _eventListenerId = 0;
- }
-
- ///
- /// 获取监听器数量
- ///
- /// 监听器数量
- public int GetListenerCount()
- {
- return _eventListeners.Count;
- }
-
- ///
- /// 获取指定类型的事件监听器数量
- ///
- /// 事件类型
- /// 监听器数量
- public int GetListenerCountByType(string type)
- {
- return _eventListeners.Values.Count(l => l.Type == type || l.Type == LogConstants.EventTypes.All);
- }
- }
-
- ///
- /// 事件监听器
- ///
- public class EventListener
- {
- ///
- /// 事件类型
- ///
- public string Type { get; set; } = string.Empty;
-
- ///
- /// 回调函数
- ///
- public Action Callback { get; set; } = _ => { };
- }
-
- ///
- /// 日志事件
- ///
- public class LogEvent
- {
- ///
- /// 事件类型
- ///
- public string Type { get; set; } = string.Empty;
-
- ///
- /// 事件数据
- ///
- public object? Data { get; set; }
-
- ///
- /// 时间戳
- ///
- public DateTime Timestamp { get; set; } = DateTime.Now;
-
- ///
- /// 事件源
- ///
- public string? Source { get; set; }
- }
-
- ///
- /// 日志事件类型
- ///
- public static class LogEventTypes
- {
- ///
- /// 新日志事件
- ///
- public const string NewLogs = "newLogs";
-
- ///
- /// 选择日志事件
- ///
- public const string SelectLog = "selectLog";
-
- ///
- /// 过滤器更新事件
- ///
- public const string FilterUpdate = "filterUpdate";
-
- ///
- /// 客户端状态变化事件
- ///
- public const string ClientStateChange = "clientStateChange";
-
- ///
- /// 日志清除事件
- ///
- public const string LogsCleared = "logsCleared";
-
- ///
- /// 错误事件
- ///
- public const string Error = "error";
-
- ///
- /// 警告事件
- ///
- public const string Warning = "warning";
-
- ///
- /// 信息事件
- ///
- public const string Info = "info";
-
- ///
- /// 调试事件
- ///
- public const string Debug = "debug";
-
- ///
- /// 所有事件
- ///
- public const string All = "*";
-
- ///
- /// 获取所有事件类型
- ///
- /// 事件类型列表
- public static List GetAllEventTypes()
- {
- return new List
- {
- NewLogs, SelectLog, FilterUpdate, ClientStateChange, LogsCleared,
- Error, Warning, Info, Debug, All
- };
- }
- }
-}
\ No newline at end of file
diff --git a/LTEMvcApp/Models/LogFilterConfig.cs b/LTEMvcApp/Models/LogFilterConfig.cs
deleted file mode 100644
index d1ca598..0000000
--- a/LTEMvcApp/Models/LogFilterConfig.cs
+++ /dev/null
@@ -1,270 +0,0 @@
-namespace LTEMvcApp.Models
-{
- ///
- /// 日志过滤器配置
- ///
- public class LogFilterConfig
- {
- ///
- /// 全局UE ID列表
- ///
- public List GlobalUeIds { get; set; } = new();
-
- ///
- /// 小区ID列表
- ///
- public List CellIds { get; set; } = new();
-
- ///
- /// IMSI列表
- ///
- public List ImsiList { get; set; } = new();
-
- ///
- /// IMEI列表
- ///
- public List ImeiList { get; set; } = new();
-
- ///
- /// 信息类型列表
- ///
- public List InfoTypes { get; set; } = new();
-
- ///
- /// 层类型列表
- ///
- public List LayerTypes { get; set; } = new();
-
- ///
- /// 日志级别列表
- ///
- public List LogLevels { get; set; } = new();
-
- ///
- /// 方向过滤器(false表示过滤掉,true表示保留)
- ///
- public bool[] DirectionFilter { get; set; } = { false, false, false };
-
- ///
- /// 开始时间戳
- ///
- public long StartTime { get; set; } = 0;
-
- ///
- /// 结束时间戳
- ///
- public long EndTime { get; set; } = long.MaxValue;
-
- ///
- /// 时间原点
- ///
- public string TimeOrigin { get; set; } = "00:00:00.000";
-
- ///
- /// 是否分组UE ID
- ///
- public bool GroupUeId { get; set; } = true;
-
- ///
- /// 搜索文本
- ///
- public string? SearchText { get; set; }
-
- ///
- /// 是否使用正则表达式搜索
- ///
- public bool UseRegexSearch { get; set; } = false;
-
- ///
- /// 是否忽略大小写
- ///
- public bool IgnoreCase { get; set; } = true;
-
- ///
- /// 是否只显示错误
- ///
- public bool ShowErrorsOnly { get; set; } = false;
-
- ///
- /// 是否只显示警告
- ///
- public bool ShowWarningsOnly { get; set; } = false;
-
- ///
- /// 客户端过滤器
- ///
- public Dictionary ClientFilters { get; set; } = new();
-
- ///
- /// 是否启用过滤器
- ///
- public bool IsEnabled { get; set; } = true;
-
- ///
- /// 过滤器名称
- ///
- public string? FilterName { get; set; }
-
- ///
- /// 是否持久化
- ///
- public bool IsPersistent { get; set; } = false;
-
- ///
- /// 创建时间
- ///
- public DateTime CreatedAt { get; set; } = DateTime.Now;
-
- ///
- /// 更新时间
- ///
- public DateTime UpdatedAt { get; set; } = DateTime.Now;
-
- ///
- /// 清除所有过滤器
- ///
- public void ClearAll()
- {
- GlobalUeIds.Clear();
- CellIds.Clear();
- ImsiList.Clear();
- ImeiList.Clear();
- InfoTypes.Clear();
- LayerTypes.Clear();
- LogLevels.Clear();
- DirectionFilter = new bool[] { false, false, false };
- StartTime = 0;
- EndTime = long.MaxValue;
- TimeOrigin = "00:00:00.000";
- SearchText = null;
- ClientFilters.Clear();
- UpdatedAt = DateTime.Now;
- }
-
- ///
- /// 重置为默认值
- ///
- public void ResetToDefault()
- {
- ClearAll();
- GroupUeId = true;
- IsEnabled = true;
- UseRegexSearch = false;
- IgnoreCase = true;
- ShowErrorsOnly = false;
- ShowWarningsOnly = false;
- }
-
- ///
- /// 复制过滤器配置
- ///
- /// 新的过滤器配置
- public LogFilterConfig Clone()
- {
- return new LogFilterConfig
- {
- GlobalUeIds = new List(GlobalUeIds),
- CellIds = new List(CellIds),
- ImsiList = new List(ImsiList),
- ImeiList = new List(ImeiList),
- InfoTypes = new List(InfoTypes),
- LayerTypes = new List(LayerTypes),
- LogLevels = new List(LogLevels),
- DirectionFilter = (bool[])DirectionFilter.Clone(),
- StartTime = StartTime,
- EndTime = EndTime,
- TimeOrigin = TimeOrigin,
- GroupUeId = GroupUeId,
- SearchText = SearchText,
- UseRegexSearch = UseRegexSearch,
- IgnoreCase = IgnoreCase,
- ShowErrorsOnly = ShowErrorsOnly,
- ShowWarningsOnly = ShowWarningsOnly,
- ClientFilters = new Dictionary(ClientFilters),
- IsEnabled = IsEnabled,
- FilterName = FilterName,
- IsPersistent = IsPersistent,
- CreatedAt = CreatedAt,
- UpdatedAt = DateTime.Now
- };
- }
-
- ///
- /// 检查是否为空过滤器
- ///
- /// 是否为空
- public bool IsEmpty()
- {
- return GlobalUeIds.Count == 0 &&
- CellIds.Count == 0 &&
- ImsiList.Count == 0 &&
- ImeiList.Count == 0 &&
- InfoTypes.Count == 0 &&
- LayerTypes.Count == 0 &&
- LogLevels.Count == 0 &&
- DirectionFilter.All(x => !x) &&
- StartTime == 0 &&
- EndTime == long.MaxValue &&
- string.IsNullOrEmpty(SearchText) &&
- ClientFilters.Count == 0 &&
- !ShowErrorsOnly &&
- !ShowWarningsOnly;
- }
- }
-
- ///
- /// 过滤器选项
- ///
- public class FilterOption
- {
- ///
- /// 值
- ///
- public object Value { get; set; } = string.Empty;
-
- ///
- /// 显示文本
- ///
- public string Text { get; set; } = string.Empty;
-
- ///
- /// 样式
- ///
- public string Style { get; set; } = string.Empty;
-
- ///
- /// 是否被选中
- ///
- public bool IsSelected { get; set; } = false;
- }
-
- ///
- /// 过滤器类型
- ///
- public static class FilterTypes
- {
- public const string GlobalUeId = "global_ue_id";
- public const string Cell = "cell";
- public const string Imsi = "imsi";
- public const string Imei = "imei";
- public const string Info = "info";
- public const string Layer = "layer";
- public const string Level = "level";
- public const string Direction = "dir";
- public const string Time = "time";
- public const string Search = "search";
- public const string Client = "client";
-
- ///
- /// 获取所有过滤器类型
- ///
- /// 过滤器类型列表
- public static List GetAllFilterTypes()
- {
- return new List
- {
- GlobalUeId, Cell, Imsi, Imei, Info, Layer, Level, Direction, Time, Search, Client
- };
- }
- }
-}
\ No newline at end of file
diff --git a/LTEMvcApp/Models/LogModelConfig.cs b/LTEMvcApp/Models/LogModelConfig.cs
deleted file mode 100644
index 8b79928..0000000
--- a/LTEMvcApp/Models/LogModelConfig.cs
+++ /dev/null
@@ -1,121 +0,0 @@
-using System.Text.RegularExpressions;
-
-namespace LTEMvcApp.Models
-{
- ///
- /// 日志模型配置
- ///
- public static class LogModelConfig
- {
- ///
- /// 模型列表(顺序重要)
- ///
- public static readonly string[] ModelList =
- {
- "RUE", "UE", "PROBE", "ENB", "N3IWF", "MBMSGW", "MME", "IMS", "LICENSE", "MONITOR"
- };
-
- ///
- /// 模型配置字典
- ///
- public static readonly Dictionary Models = new()
- {
- ["RUE"] = new() { Icon = "icon-ue2" },
- ["UE"] = new() { Icon = "icon-ue" },
- ["PROBE"] = new() { },
- ["ENB"] = new()
- {
- Icon = "icon-air",
- ModelHint = new Regex(@"enb|gnb|bbu", RegexOptions.IgnoreCase),
- Title = "RAN"
- },
- ["N3IWF"] = new()
- {
- Icon = "icon-air",
- ModelHint = new Regex(@"n3iwf", RegexOptions.IgnoreCase),
- Title = "N3IWF"
- },
- ["MME"] = new()
- {
- Icon = "icon-server",
- ModelHint = new Regex(@"epc|mme|amf", RegexOptions.IgnoreCase),
- Title = "CN"
- },
- ["MBMSGW"] = new()
- {
- Icon = "icon-download",
- ModelHint = new Regex(@"mbms", RegexOptions.IgnoreCase)
- },
- ["IMS"] = new() { Icon = "icon-dial" },
- ["MONITOR"] = new() { Icon = "icon-monitor" },
- ["LICENSE"] = new() { Icon = "icon-file" }
- };
-
- ///
- /// 获取模型配置
- ///
- /// 模型名称
- /// 模型配置
- public static ModelConfig? GetModelConfig(string modelName)
- {
- return Models.TryGetValue(modelName, out var config) ? config : null;
- }
-
- ///
- /// 根据提示匹配模型
- ///
- /// 提示文本
- /// 匹配的模型名称
- public static string? MatchModelByHint(string hint)
- {
- foreach (var kvp in Models)
- {
- if (kvp.Value.ModelHint?.IsMatch(hint) == true)
- {
- return kvp.Key;
- }
- }
- return null;
- }
-
- ///
- /// 获取所有模型名称
- ///
- /// 模型名称列表
- public static List GetAllModelNames()
- {
- return ModelList.ToList();
- }
-
- ///
- /// 验证模型名称是否有效
- ///
- /// 模型名称
- /// 是否有效
- public static bool IsValidModel(string modelName)
- {
- return Models.ContainsKey(modelName);
- }
- }
-
- ///
- /// 模型配置
- ///
- public class ModelConfig
- {
- ///
- /// 图标类名
- ///
- public string? Icon { get; set; }
-
- ///
- /// 模型提示正则表达式
- ///
- public Regex? ModelHint { get; set; }
-
- ///
- /// 显示标题
- ///
- public string? Title { get; set; }
- }
-}
\ No newline at end of file
diff --git a/LTEMvcApp/Models/LogState.cs b/LTEMvcApp/Models/LogState.cs
deleted file mode 100644
index 8c14fe3..0000000
--- a/LTEMvcApp/Models/LogState.cs
+++ /dev/null
@@ -1,314 +0,0 @@
-namespace LTEMvcApp.Models
-{
- ///
- /// 日志状态管理类
- ///
- public class LogState
- {
- ///
- /// 日志列表
- ///
- public List Logs { get; set; } = new();
-
- ///
- /// 客户端列表
- ///
- public List ClientList { get; set; } = new();
-
- ///
- /// 新日志列表
- ///
- public List NewLogs { get; set; } = new();
-
- ///
- /// 是否重置元数据
- ///
- public bool ResetMetadata { get; set; } = false;
-
- ///
- /// 检测到的最小日志级别
- ///
- public int MinLevelDetected { get; set; } = 10;
-
- ///
- /// 是否启用过滤器
- ///
- public bool Filter { get; set; } = false;
-
- ///
- /// 是否更新网格
- ///
- public bool UpdateGrid { get; set; } = false;
-
- ///
- /// 是否跟随最新日志
- ///
- public bool Follow { get; set; } = false;
-
- ///
- /// 过滤器锁定状态
- ///
- public string FilterLock { get; set; } = string.Empty;
-
- ///
- /// 日志总数
- ///
- public int LogCount => Logs.Count;
-
- ///
- /// 客户端总数
- ///
- public int ClientCount => ClientList.Count;
-
- ///
- /// 新日志数量
- ///
- public int NewLogCount => NewLogs.Count;
-
- ///
- /// 启用的客户端数量
- ///
- public int EnabledClientCount => ClientList.Count(c => c.State == ClientState.Connected || c.State == ClientState.Start);
-
- ///
- /// 添加日志
- ///
- /// 日志对象
- public void AddLog(LTELog log)
- {
- Logs.Add(log);
- NewLogs.Add(log);
- }
-
- ///
- /// 添加客户端
- ///
- /// 客户端对象
- public void AddClient(LTEClient client)
- {
- ClientList.Add(client);
- }
-
- ///
- /// 移除客户端
- ///
- /// 客户端对象
- /// 是否成功移除
- public bool RemoveClient(LTEClient client)
- {
- var removed = ClientList.Remove(client);
- if (removed)
- {
- // 移除该客户端的日志
- Logs.RemoveAll(log => log.Client == client);
- NewLogs.RemoveAll(log => log.Client == client);
- }
- return removed;
- }
-
- ///
- /// 清除所有日志
- ///
- public void ClearLogs()
- {
- Logs.Clear();
- NewLogs.Clear();
- ResetMetadata = true;
- UpdateGrid = true;
- }
-
- ///
- /// 清除新日志
- ///
- public void ClearNewLogs()
- {
- NewLogs.Clear();
- }
-
- ///
- /// 重置状态
- ///
- public void Reset()
- {
- Logs.Clear();
- NewLogs.Clear();
- ResetMetadata = true;
- MinLevelDetected = 10;
- Filter = false;
- UpdateGrid = false;
- Follow = false;
- FilterLock = string.Empty;
- }
-
- ///
- /// 获取指定客户端的日志
- ///
- /// 客户端对象
- /// 日志列表
- public List GetLogsByClient(LTEClient client)
- {
- return Logs.Where(log => log.Client == client).ToList();
- }
-
- ///
- /// 获取启用的客户端
- ///
- /// 启用的客户端列表
- public List GetEnabledClients()
- {
- return ClientList.Where(c => c.State == ClientState.Connected || c.State == ClientState.Start).ToList();
- }
-
- ///
- /// 获取错误状态的客户端
- ///
- /// 错误状态的客户端列表
- public List GetErrorClients()
- {
- return ClientList.Where(c => c.State == ClientState.Error).ToList();
- }
-
- ///
- /// 获取连接状态的客户端
- ///
- /// 连接状态的客户端列表
- public List GetConnectedClients()
- {
- return ClientList.Where(c => c.State == ClientState.Connected).ToList();
- }
-
- ///
- /// 检查是否有实时客户端
- ///
- /// 是否有实时客户端
- public bool HasRealTimeClients()
- {
- return ClientList.Any(c => c.State == ClientState.Connected);
- }
-
- ///
- /// 获取日志统计信息
- ///
- /// 统计信息
- public LogStatistics GetStatistics()
- {
- return new LogStatistics
- {
- TotalLogs = LogCount,
- NewLogs = NewLogCount,
- TotalClients = ClientCount,
- EnabledClients = EnabledClientCount,
- ConnectedClients = GetConnectedClients().Count,
- ErrorClients = GetErrorClients().Count,
- MinLevel = MinLevelDetected,
- HasRealTime = HasRealTimeClients()
- };
- }
-
- ///
- /// 更新最小日志级别
- ///
- /// 日志级别
- public void UpdateMinLevel(int level)
- {
- if (level < MinLevelDetected)
- {
- MinLevelDetected = level;
- }
- }
-
- ///
- /// 设置过滤器状态
- ///
- /// 是否启用
- public void SetFilter(bool enabled)
- {
- Filter = enabled;
- if (enabled)
- {
- UpdateGrid = true;
- }
- }
-
- ///
- /// 锁定过滤器
- ///
- /// 锁定名称
- public void LockFilter(string lockName)
- {
- FilterLock = lockName;
- }
-
- ///
- /// 解锁过滤器
- ///
- public void UnlockFilter()
- {
- FilterLock = string.Empty;
- }
-
- ///
- /// 检查过滤器是否被锁定
- ///
- /// 是否被锁定
- public bool IsFilterLocked()
- {
- return !string.IsNullOrEmpty(FilterLock);
- }
- }
-
- ///
- /// 日志统计信息
- ///
- public class LogStatistics
- {
- ///
- /// 总日志数
- ///
- public int TotalLogs { get; set; }
-
- ///
- /// 新日志数
- ///
- public int NewLogs { get; set; }
-
- ///
- /// 总客户端数
- ///
- public int TotalClients { get; set; }
-
- ///
- /// 启用的客户端数
- ///
- public int EnabledClients { get; set; }
-
- ///
- /// 连接的客户端数
- ///
- public int ConnectedClients { get; set; }
-
- ///
- /// 错误的客户端数
- ///
- public int ErrorClients { get; set; }
-
- ///
- /// 最小日志级别
- ///
- public int MinLevel { get; set; }
-
- ///
- /// 是否有实时客户端
- ///
- public bool HasRealTime { get; set; }
-
- ///
- /// 获取统计信息字符串
- ///
- /// 统计信息字符串
- public override string ToString()
- {
- return $"日志: {TotalLogs} (新: {NewLogs}), 客户端: {EnabledClients}/{TotalClients} (连接: {ConnectedClients}, 错误: {ErrorClients}), 最小级别: {MinLevel}";
- }
- }
-}
\ No newline at end of file
diff --git a/LTEMvcApp/Models/LogUtils.cs b/LTEMvcApp/Models/LogUtils.cs
deleted file mode 100644
index 04784a3..0000000
--- a/LTEMvcApp/Models/LogUtils.cs
+++ /dev/null
@@ -1,331 +0,0 @@
-using System.Text.RegularExpressions;
-
-namespace LTEMvcApp.Models
-{
- ///
- /// 日志工具类
- ///
- public static class LogUtils
- {
- ///
- /// 日志级别常量
- ///
- public static class LogLevels
- {
- public const int None = 0;
- public const int Error = 1;
- public const int Warn = 2;
- public const int Info = 3;
- public const int Debug = 4;
-
- ///
- /// 获取级别名称
- ///
- /// 级别值
- /// 级别名称
- public static string GetLevelName(int level)
- {
- return level switch
- {
- None => "none",
- Error => "error",
- Warn => "warn",
- Info => "info",
- Debug => "debug",
- _ => "unknown"
- };
- }
-
- ///
- /// 获取级别值
- ///
- /// 级别名称
- /// 级别值
- public static int GetLevelValue(string levelName)
- {
- return levelName?.ToLower() switch
- {
- "none" => None,
- "error" => Error,
- "warn" => Warn,
- "info" => Info,
- "debug" => Debug,
- _ => None
- };
- }
-
- ///
- /// 获取所有级别选项
- ///
- /// 级别选项列表
- public static List GetLevelOptions()
- {
- return new List
- {
- new() { Value = Error, Text = "Error" },
- new() { Value = Warn, Text = "Warning" },
- new() { Value = Info, Text = "Info" },
- new() { Value = Debug, Text = "Debug" }
- };
- }
- }
-
- ///
- /// 级别选项
- ///
- public class LevelOption
- {
- public int Value { get; set; }
- public string Text { get; set; } = string.Empty;
- }
-
- ///
- /// 时间戳转换为时间字符串
- ///
- /// 时间戳(毫秒)
- /// 是否显示完整日期
- /// 时间字符串
- public static string TimestampToTime(long timestamp, bool full = false)
- {
- // 持续时间 (< 2000-01-01 00:00:00)
- if (timestamp < 946681200000)
- {
- return TimestampToDuration(timestamp);
- }
-
- var dateTime = DateTimeOffset.FromUnixTimeMilliseconds(timestamp).DateTime;
- if (full)
- {
- return dateTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
- }
- return dateTime.ToString("HH:mm:ss.fff");
- }
-
- ///
- /// 时间戳转换为持续时间字符串
- ///
- /// 时间戳(毫秒)
- /// 持续时间字符串
- public static string TimestampToDuration(long timestamp)
- {
- var prefix = timestamp < 0 ? "-" : "";
- var absTimestamp = Math.Abs(timestamp);
- var timeSpan = TimeSpan.FromMilliseconds(absTimestamp);
- return $"{prefix}{timeSpan.Hours:D2}:{timeSpan.Minutes:D2}:{timeSpan.Seconds:D2}.{timeSpan.Milliseconds:D3}";
- }
-
- ///
- /// 时间字符串转换为时间戳
- ///
- /// 时间字符串
- /// 时间戳,转换失败返回null
- public static long? TimeStringToTimestamp(string timeString)
- {
- if (string.IsNullOrEmpty(timeString))
- return null;
-
- // 匹配格式: HH:mm:ss.fff 或 mm:ss.fff 或 ss.fff
- var match = Regex.Match(timeString, @"^(((\d+):)?(\d+):)?(\d+)(\.(\d+))?$");
- if (!match.Success)
- return null;
-
- var hours = int.Parse(match.Groups[3].Success ? match.Groups[3].Value : "0");
- var minutes = int.Parse(match.Groups[4].Success ? match.Groups[4].Value : "0");
- var seconds = int.Parse(match.Groups[5].Value);
- var milliseconds = match.Groups[7].Success ? int.Parse(match.Groups[7].Value.PadRight(3, '0')) : 0;
-
- return (hours * 3600000L) + (minutes * 60000L) + (seconds * 1000L) + milliseconds;
- }
-
- ///
- /// 获取日期偏移量
- ///
- /// 时间戳
- /// 日期偏移量
- public static long GetDayOffset(long timestamp)
- {
- if (timestamp < 946681200000)
- return 0;
-
- var dateTime = DateTimeOffset.FromUnixTimeMilliseconds(timestamp).DateTime;
- var dayStart = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 0, 0, 0, DateTimeKind.Utc);
- return new DateTimeOffset(dayStart).ToUnixTimeMilliseconds();
- }
-
- ///
- /// 字符串转ID
- ///
- /// 字符串
- /// ID值
- public static int StringToId(string str)
- {
- if (string.IsNullOrEmpty(str))
- return 0;
-
- var hash = 5381;
- foreach (var c in str)
- {
- hash = ((hash << 5) + hash) ^ c;
- }
- return hash;
- }
-
- ///
- /// 创建正则表达式
- ///
- /// 模式
- /// 是否忽略大小写
- /// 正则表达式,创建失败返回null
- public static Regex? CreateRegex(string pattern, bool ignoreCase = true)
- {
- if (string.IsNullOrEmpty(pattern))
- return null;
-
- try
- {
- var options = ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None;
-
- // 检查是否是正则表达式格式 /pattern/flags
- var regexMatch = Regex.Match(pattern, @"^/(.+)/([gi]*)$");
- if (regexMatch.Success)
- {
- var regexPattern = regexMatch.Groups[1].Value;
- var flags = regexMatch.Groups[2].Value;
-
- if (flags.Contains('i'))
- options |= RegexOptions.IgnoreCase;
- if (flags.Contains('g'))
- options |= RegexOptions.Multiline;
-
- return new Regex(regexPattern, options);
- }
-
- // 普通文本搜索,添加转义
- var escapedPattern = Regex.Escape(pattern);
- return new Regex(escapedPattern, options);
- }
- catch
- {
- return null;
- }
- }
-
- ///
- /// 高亮搜索文本
- ///
- /// 原文本
- /// 搜索模式
- /// 高亮后的文本
- public static string HighlightSearchText(string text, string searchPattern)
- {
- if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(searchPattern))
- return text;
-
- var regex = CreateRegex(searchPattern);
- if (regex == null)
- return text;
-
- return regex.Replace(text, "$&");
- }
-
- ///
- /// 格式化文件大小
- ///
- /// 字节数
- /// 格式化后的字符串
- public static string FormatFileSize(long bytes)
- {
- string[] sizes = { "B", "KB", "MB", "GB", "TB" };
- double len = bytes;
- int order = 0;
- while (len >= 1024 && order < sizes.Length - 1)
- {
- order++;
- len = len / 1024;
- }
- return $"{len:0.##} {sizes[order]}";
- }
-
- ///
- /// 解析大小字符串
- ///
- /// 大小字符串
- /// 字节数
- public static long ParseSizeString(string sizeString)
- {
- if (string.IsNullOrEmpty(sizeString))
- return 0;
-
- var match = Regex.Match(sizeString, @"^(\d+)([KMG])?$", RegexOptions.IgnoreCase);
- if (!match.Success)
- return 0;
-
- var size = long.Parse(match.Groups[1].Value);
- var unit = match.Groups[2].Value.ToUpper();
-
- return unit switch
- {
- "K" => size * 1024,
- "M" => size * 1024 * 1024,
- "G" => size * 1024 * 1024 * 1024,
- _ => size
- };
- }
-
- ///
- /// 获取颜色亮度
- ///
- /// 颜色代码
- /// 亮度值 (0-1)
- public static double GetColorBrightness(string color)
- {
- var match = Regex.Match(color, @"#([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})");
- if (!match.Success)
- return 1;
-
- var r = int.Parse(match.Groups[1].Value, System.Globalization.NumberStyles.HexNumber);
- var g = int.Parse(match.Groups[2].Value, System.Globalization.NumberStyles.HexNumber);
- var b = int.Parse(match.Groups[3].Value, System.Globalization.NumberStyles.HexNumber);
-
- return (r * r * 0.299 + g * g * 0.587 + b * b * 0.114) / (255.0 * 255.0);
- }
-
- ///
- /// 获取文本颜色
- ///
- /// 背景颜色
- /// 文本颜色
- public static string GetTextColor(string backgroundColor)
- {
- var brightness = GetColorBrightness(backgroundColor);
- return brightness >= 0.15 ? "black" : "white";
- }
-
- ///
- /// 生成唯一ID
- ///
- /// 唯一ID
- public static string GenerateUniqueId()
- {
- return Guid.NewGuid().ToString("N");
- }
-
- ///
- /// 安全地执行操作
- ///
- /// 要执行的操作
- /// 默认值
- /// 操作结果或默认值
- public static T SafeExecute(Func action, T defaultValue)
- {
- try
- {
- return action();
- }
- catch
- {
- return defaultValue;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/LTEMvcApp/Models/LogsManager.cs b/LTEMvcApp/Models/LogsManager.cs
new file mode 100644
index 0000000..69ce53c
--- /dev/null
+++ b/LTEMvcApp/Models/LogsManager.cs
@@ -0,0 +1,895 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace LTEMvcApp.Models
+{
+ ///
+ /// 日志管理器 - 从JavaScript logs.js迁移
+ ///
+ public class LogsManager
+ {
+ #region 常量定义
+
+ public const int DIR_NONE = 0;
+ public const int DIR_UL = 1;
+ public const int DIR_DL = 2;
+ public const int DIR_FROM = 3;
+ public const int DIR_TO = 4;
+
+ #endregion
+
+ #region 静态字段
+
+ private static readonly string[] modelList = { "RUE", "UE", "PROBE", "ENB", "N3IWF", "MBMSGW", "MME", "IMS", "LICENSE", "MONITOR" };
+
+ private static readonly Dictionary modelConfig = new()
+ {
+ { "RUE", new { icon = "icon-ue2" } },
+ { "UE", new { icon = "icon-ue" } },
+ { "PROBE", new { } },
+ { "ENB", new { icon = "icon-air", modelHint = "enb|gnb|bbu", title = "RAN" } },
+ { "N3IWF", new { icon = "icon-air", modelHint = "n3iwf", title = "N3IWF" } },
+ { "MME", new { icon = "icon-server", modelHint = "epc|mme|amf", title = "CN" } },
+ { "MBMSGW", new { icon = "icon-download", modelHint = "mbms" } },
+ { "IMS", new { icon = "icon-dial" } },
+ { "MONITOR", new { icon = "icon-monitor" } },
+ { "LICENSE", new { icon = "icon-file" } }
+ };
+
+ private static readonly Dictionary layerConfig = new()
+ {
+ { "PHY", new { color = "#606070", dir = new Dictionary { { "UE", 2 }, { "PROBE", 3 }, { "ENB", 1 } }, debug = new { level = "debug", max_size = 1 } } },
+ { "MAC", new { color = "#10A0FF", dir = new Dictionary { { "UE", 2 }, { "PROBE", 3 }, { "ENB", 1 } }, debug = new { level = "debug", max_size = 1 } } },
+ { "RLC", new { color = "#FFFF80", dir = new Dictionary { { "UE", 2 }, { "PROBE", 3 }, { "ENB", 1 } } } },
+ { "PDCP", new { color = "#B0D0B0", dir = new Dictionary { { "UE", 2 }, { "PROBE", 3 }, { "ENB", 1 } } } },
+ { "RRC", new { color = "#00FF60", dir = new Dictionary { { "UE", 2 }, { "PROBE", 3 }, { "ENB", 1 } }, debug = new { level = "debug", max_size = 1 } } },
+ { "NAS", new { color = "#90FFC0", dir = new Dictionary { { "UE", 2 }, { "PROBE", 3 }, { "ENB", 3 }, { "N3IWF", 3 }, { "MME", 1 } }, debug = new { level = "debug", max_size = 1 } } },
+ { "GTPU", new { color = "#FF80FF", dir = new Dictionary { { "ENB", 2 }, { "N3IWF", 2 }, { "MME", 1 }, { "MBMSGW", 1 }, { "UE", 1 }, { "RUE", 2 } }, epc = true, max = new { max_size = 32 } } },
+ { "GTPC", new { color = "#FFC0FF", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "IP", new { color = "#E0E0E0", dir = new Dictionary { { "RUE", 2 }, { "UE", 2 }, { "N3IWF", 3 }, { "PROBE", 3 }, { "MME", 3 } }, max = new { max_size = 32 } } },
+ { "S1AP", new { color = "#80FF00", dir = new Dictionary { { "ENB", 2 }, { "MME", 1 } }, epc = true, debug = new { level = "debug", max_size = 1 } } },
+ { "NGAP", new { color = "#5DD122", dir = new Dictionary { { "ENB", 2 }, { "MME", 1 }, { "N3IWF", 2 } }, epc = true, debug = new { level = "debug", max_size = 1 } } },
+ { "X2AP", new { color = "#FF8000", dir = new Dictionary { { "ENB", 2 } } } },
+ { "XnAP", new { color = "#FFB020", dir = new Dictionary { { "ENB", 2 } } } },
+ { "M2AP", new { color = "#7F675B", dir = new Dictionary { { "ENB", 2 }, { "MBMSGW", 1 } }, epc = true } },
+ { "IMS", new { color = "#C0FF80", dir = new Dictionary { { "MME", 2 }, { "IMS", 1 } }, debug = new { level = "debug", max_size = 1 }, epc = true } },
+ { "CX", new { color = "#F49542", dir = new Dictionary { { "MME", 2 }, { "IMS", 1 } }, epc = true } },
+ { "RX", new { color = "#D4A190", dir = new Dictionary { { "MME", 2 }, { "IMS", 1 } }, epc = true } },
+ { "COM", new { color = "#C000FF", dir = new Dictionary { { "*", 2 } } } },
+ { "SIP", new { color = "#C080FF", dir = new Dictionary { { "IMS", 1 } }, epc = true, debug = new { level = "debug", max_size = 1 } } },
+ { "MEDIA", new { color = "#800040", dir = new Dictionary { { "IMS", 1 } }, epc = true } },
+ { "RTP", new { color = "#FF00C0", dir = new Dictionary { { "IMS", 1 } }, epc = true } },
+ { "PROD", new { color = "#80C0FF", dir = new Dictionary { } } },
+ { "S6", new { color = "#F44B42", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "S13", new { color = "#D6F953", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "SGsAP", new { color = "#FF7DB8", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "SBcAP", new { color = "#8FA00F", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "N8", new { color = "#106020", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "N12", new { color = "#602020", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "N13", new { color = "#202060", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "N17", new { color = "#D6F953", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "N50", new { color = "#8FA00F", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "MMS", new { color = "#B4D98F", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "HTTP2", new { color = "#644824", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "LCSAP", new { color = "#cfd50d", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "LPPa", new { color = "#0dcfd5", dir = new Dictionary { { "ENB", 2 }, { "MME", 3 } }, epc = true } },
+ { "NL1", new { color = "#d040cf", dir = new Dictionary { { "MME", 2 } }, epc = true } },
+ { "NRPPa", new { color = "#0dd5cf", dir = new Dictionary { { "ENB", 2 }, { "MME", 3 } }, epc = true } },
+ { "IKEV2", new { color = "#C0B732", dir = new Dictionary { { "UE", 2 }, { "MME", 1 }, { "N3IWF", 1 } } } },
+ { "SWU", new { color = "#101080", dir = new Dictionary { { "UE", 2 }, { "MME", 1 } } } },
+ { "NWU", new { color = "#2080B8", dir = new Dictionary { { "UE", 2 }, { "MME", 1 } } } },
+ { "IPSEC", new { color = "#F04010", dir = new Dictionary { { "UE", 2 }, { "IMS", 1 }, { "N3IWF", 1 }, { "MME", 1 } }, epc = true, max = new { max_size = 32 } } },
+ { "N3IWF", new { color = "#C080C0", dir = new Dictionary { { "UE", 2 }, { "N3IWF", 1 } } } },
+ { "TRX", new { color = "#42C0a0", dir = new Dictionary { { "UE", 2 }, { "ENB", 1 } }, debug = new { level = "debug" } } },
+ { "MON", new { color = "#C0C080", dir = new Dictionary { } } },
+ { "EVENT", new { color = "#80C0FF", dir = new Dictionary { } } },
+ { "ALARM", new { color = "#FF8040", dir = new Dictionary { } } },
+ { "LIC", new { color = "#ff80c0", dir = new Dictionary { { "LICENSE", 1 } } } },
+ { "OTS", new { color = "#8080FF", dir = new Dictionary { } } },
+ { "ERROR", new { color = "#ff0000", dir = new Dictionary { } } }
+ };
+
+ #endregion
+
+ #region 实例字段
+
+ private readonly Dictionary _logs = new();
+ private readonly int _logDefaultLevel = 0; // localStorage.debug >> 0
+ private readonly string[] _logsMethods = { "error", "warn", "info", "debug", "prof" };
+ private readonly long _startDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+ private readonly Dictionary _stringIDs = new();
+ private readonly List _stringList = new();
+
+ private readonly Dictionary _eventListeners = new();
+ private int _eventListenerId = 0;
+
+ #endregion
+
+ #region 属性
+
+ public string Mode { get; set; } = "web";
+ public string FontDef { get; set; } = "13px helvetica, arial, verdana, sans-serif";
+ public int LastClientId { get; set; } = 0;
+ public int LogsMax { get; set; } = 100000;
+ public List LogsRange { get; set; } = new();
+ public List LogsInfo { get; set; } = new();
+ public List LogsLayers { get; set; } = new();
+ public string ExportTimeFormat { get; set; } = "HH:mm:ss.fff";
+
+ #endregion
+
+ #region 构造函数
+
+ public LogsManager()
+ {
+ Init();
+ }
+
+ #endregion
+
+ #region 初始化方法
+
+ public void Init()
+ {
+ // 初始化通道定义
+ var def = new Dictionary();
+ var ids = new Dictionary();
+
+ // 这里可以添加通道定义的初始化逻辑
+ // 对应JavaScript中的_channelsDef.forEach逻辑
+ }
+
+ #endregion
+
+ #region 日志相关方法
+
+ public void SetLogger(string name, object instance)
+ {
+ var module = new { level = _logDefaultLevel, list = new List