You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
331 lines
11 KiB
331 lines
11 KiB
using System.Text.RegularExpressions;
|
|
|
|
namespace LTEMvcApp.Models
|
|
{
|
|
/// <summary>
|
|
/// 日志工具类
|
|
/// </summary>
|
|
public static class LogUtils
|
|
{
|
|
/// <summary>
|
|
/// 日志级别常量
|
|
/// </summary>
|
|
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;
|
|
|
|
/// <summary>
|
|
/// 获取级别名称
|
|
/// </summary>
|
|
/// <param name="level">级别值</param>
|
|
/// <returns>级别名称</returns>
|
|
public static string GetLevelName(int level)
|
|
{
|
|
return level switch
|
|
{
|
|
None => "none",
|
|
Error => "error",
|
|
Warn => "warn",
|
|
Info => "info",
|
|
Debug => "debug",
|
|
_ => "unknown"
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取级别值
|
|
/// </summary>
|
|
/// <param name="levelName">级别名称</param>
|
|
/// <returns>级别值</returns>
|
|
public static int GetLevelValue(string levelName)
|
|
{
|
|
return levelName?.ToLower() switch
|
|
{
|
|
"none" => None,
|
|
"error" => Error,
|
|
"warn" => Warn,
|
|
"info" => Info,
|
|
"debug" => Debug,
|
|
_ => None
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取所有级别选项
|
|
/// </summary>
|
|
/// <returns>级别选项列表</returns>
|
|
public static List<LevelOption> GetLevelOptions()
|
|
{
|
|
return new List<LevelOption>
|
|
{
|
|
new() { Value = Error, Text = "Error" },
|
|
new() { Value = Warn, Text = "Warning" },
|
|
new() { Value = Info, Text = "Info" },
|
|
new() { Value = Debug, Text = "Debug" }
|
|
};
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 级别选项
|
|
/// </summary>
|
|
public class LevelOption
|
|
{
|
|
public int Value { get; set; }
|
|
public string Text { get; set; } = string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 时间戳转换为时间字符串
|
|
/// </summary>
|
|
/// <param name="timestamp">时间戳(毫秒)</param>
|
|
/// <param name="full">是否显示完整日期</param>
|
|
/// <returns>时间字符串</returns>
|
|
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");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 时间戳转换为持续时间字符串
|
|
/// </summary>
|
|
/// <param name="timestamp">时间戳(毫秒)</param>
|
|
/// <returns>持续时间字符串</returns>
|
|
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}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// 时间字符串转换为时间戳
|
|
/// </summary>
|
|
/// <param name="timeString">时间字符串</param>
|
|
/// <returns>时间戳,转换失败返回null</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取日期偏移量
|
|
/// </summary>
|
|
/// <param name="timestamp">时间戳</param>
|
|
/// <returns>日期偏移量</returns>
|
|
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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 字符串转ID
|
|
/// </summary>
|
|
/// <param name="str">字符串</param>
|
|
/// <returns>ID值</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建正则表达式
|
|
/// </summary>
|
|
/// <param name="pattern">模式</param>
|
|
/// <param name="ignoreCase">是否忽略大小写</param>
|
|
/// <returns>正则表达式,创建失败返回null</returns>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 高亮搜索文本
|
|
/// </summary>
|
|
/// <param name="text">原文本</param>
|
|
/// <param name="searchPattern">搜索模式</param>
|
|
/// <returns>高亮后的文本</returns>
|
|
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, "<highlight>$&</highlight>");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 格式化文件大小
|
|
/// </summary>
|
|
/// <param name="bytes">字节数</param>
|
|
/// <returns>格式化后的字符串</returns>
|
|
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]}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// 解析大小字符串
|
|
/// </summary>
|
|
/// <param name="sizeString">大小字符串</param>
|
|
/// <returns>字节数</returns>
|
|
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
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取颜色亮度
|
|
/// </summary>
|
|
/// <param name="color">颜色代码</param>
|
|
/// <returns>亮度值 (0-1)</returns>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取文本颜色
|
|
/// </summary>
|
|
/// <param name="backgroundColor">背景颜色</param>
|
|
/// <returns>文本颜色</returns>
|
|
public static string GetTextColor(string backgroundColor)
|
|
{
|
|
var brightness = GetColorBrightness(backgroundColor);
|
|
return brightness >= 0.15 ? "black" : "white";
|
|
}
|
|
|
|
/// <summary>
|
|
/// 生成唯一ID
|
|
/// </summary>
|
|
/// <returns>唯一ID</returns>
|
|
public static string GenerateUniqueId()
|
|
{
|
|
return Guid.NewGuid().ToString("N");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 安全地执行操作
|
|
/// </summary>
|
|
/// <param name="action">要执行的操作</param>
|
|
/// <param name="defaultValue">默认值</param>
|
|
/// <returns>操作结果或默认值</returns>
|
|
public static T SafeExecute<T>(Func<T> action, T defaultValue)
|
|
{
|
|
try
|
|
{
|
|
return action();
|
|
}
|
|
catch
|
|
{
|
|
return defaultValue;
|
|
}
|
|
}
|
|
}
|
|
}
|