|
@ -16,7 +16,6 @@ namespace Apewer |
|
|
public class Logger |
|
|
public class Logger |
|
|
{ |
|
|
{ |
|
|
|
|
|
|
|
|
private string _key = Guid.NewGuid().ToString("n"); |
|
|
|
|
|
private string _target = ""; |
|
|
private string _target = ""; |
|
|
private bool _enabled = true; |
|
|
private bool _enabled = true; |
|
|
private Func<string, bool> _preoutput = null; |
|
|
private Func<string, bool> _preoutput = null; |
|
@ -25,15 +24,15 @@ namespace Apewer |
|
|
private bool _usefile = false; |
|
|
private bool _usefile = false; |
|
|
private bool _uselock = false; |
|
|
private bool _uselock = false; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>当前日志记录器的名称。</summary>
|
|
|
|
|
|
public virtual string Name { get; set; } |
|
|
|
|
|
|
|
|
/// <summary>已启用。</summary>
|
|
|
/// <summary>已启用。</summary>
|
|
|
public virtual bool Enabled { get; set; } |
|
|
public virtual bool Enabled { get; set; } |
|
|
|
|
|
|
|
|
/// <summary>在后台线程处理日志。默认值:FALSE。</summary>
|
|
|
/// <summary>在后台线程处理日志。默认值:FALSE。</summary>
|
|
|
internal virtual bool Background { get; set; } = false; |
|
|
internal virtual bool Background { get; set; } = false; |
|
|
|
|
|
|
|
|
/// <summary>捕获并丢弃事件中的异常。默认值:FALSE。</summary>
|
|
|
|
|
|
public virtual bool Catch { get; set; } = false; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>使用控制台输出。默认值:TRUE。</summary>
|
|
|
/// <summary>使用控制台输出。默认值:TRUE。</summary>
|
|
|
public virtual bool UseConsole |
|
|
public virtual bool UseConsole |
|
|
{ |
|
|
{ |
|
@ -70,15 +69,17 @@ namespace Apewer |
|
|
{ |
|
|
{ |
|
|
if (Background) |
|
|
if (Background) |
|
|
{ |
|
|
{ |
|
|
RuntimeUtility.InBackground(action); |
|
|
RuntimeUtility.InBackground(action, true); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
action.Invoke(); |
|
|
try { action.Invoke(); } catch { } |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// <summary>记录异常。</summary>
|
|
|
/// <summary>记录异常。</summary>
|
|
|
public virtual void Exception(object sender, Exception exception) => Invoke(() => |
|
|
public virtual void Exception(object sender, Exception exception) => Invoke(() => |
|
|
{ |
|
|
{ |
|
|
|
|
|
if (!Enabled) return; |
|
|
|
|
|
|
|
|
if (OnException != null) |
|
|
if (OnException != null) |
|
|
{ |
|
|
{ |
|
|
OnException(sender, exception); |
|
|
OnException(sender, exception); |
|
@ -109,11 +110,13 @@ namespace Apewer |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (UseConsole) ToConsole(item); |
|
|
if (UseConsole) ToConsole(item); |
|
|
if (UseFile) ToFile(item); |
|
|
if (UseFile) ToFile(item, this); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
private void Colorful(object sender, string tag, Nullable<ConsoleColor> color, object[] content, Event<string> defined) => Invoke(() => |
|
|
private void Colorful(object sender, string tag, Nullable<ConsoleColor> color, object[] content, Event<string> defined) => Invoke(() => |
|
|
{ |
|
|
{ |
|
|
|
|
|
if (!Enabled) return; |
|
|
|
|
|
|
|
|
if (defined != null) |
|
|
if (defined != null) |
|
|
{ |
|
|
{ |
|
|
defined.Invoke(sender, MergeContent(content)); |
|
|
defined.Invoke(sender, MergeContent(content)); |
|
@ -127,7 +130,7 @@ namespace Apewer |
|
|
item.Content = MergeContent(content); |
|
|
item.Content = MergeContent(content); |
|
|
|
|
|
|
|
|
if (UseConsole) ToConsole(item); |
|
|
if (UseConsole) ToConsole(item); |
|
|
if (UseFile) ToFile(item); |
|
|
if (UseFile) ToFile(item, this); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
/// <summary>记录错误。多个 Content 参数将以“ | ”分隔。</summary>
|
|
|
/// <summary>记录错误。多个 Content 参数将以“ | ”分隔。</summary>
|
|
@ -149,8 +152,9 @@ namespace Apewer |
|
|
/// <summary>创建新实例。</summary>
|
|
|
/// <summary>创建新实例。</summary>
|
|
|
public Logger() { } |
|
|
public Logger() { } |
|
|
|
|
|
|
|
|
internal Logger(bool useConsole, bool useFile, bool enabled) |
|
|
private Logger(string name, bool useConsole, bool useFile, bool enabled) |
|
|
{ |
|
|
{ |
|
|
|
|
|
Name = name; |
|
|
_useconsole = useConsole; |
|
|
_useconsole = useConsole; |
|
|
_usefile = useFile; |
|
|
_usefile = useFile; |
|
|
_uselock = true; |
|
|
_uselock = true; |
|
@ -162,6 +166,9 @@ namespace Apewer |
|
|
internal static object FileLocker = new object(); |
|
|
internal static object FileLocker = new object(); |
|
|
internal static object ConsoleLocker = new object(); |
|
|
internal static object ConsoleLocker = new object(); |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>获取用于保存日志文件的路径。</summary>
|
|
|
|
|
|
public static Func<string> FilePathGetter { get; set; } |
|
|
|
|
|
|
|
|
private static string MergeContent(params object[] content) => TextUtility.Join(" | ", content); |
|
|
private static string MergeContent(params object[] content) => TextUtility.Join(" | ", content); |
|
|
|
|
|
|
|
|
private static string FormatSender(object sender) |
|
|
private static string FormatSender(object sender) |
|
@ -254,29 +261,30 @@ namespace Apewer |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 向日志文件输出文本,文件名按日期自动生成。
|
|
|
// 向日志文件输出文本,文件名按日期自动生成。
|
|
|
private static string ToFile(string plain) |
|
|
private static string ToFile(string plain, Logger logger) |
|
|
{ |
|
|
{ |
|
|
var text2 = TextUtility.Trim(plain) + "\r\n"; |
|
|
var text2 = TextUtility.Trim(plain) + "\r\n"; |
|
|
lock (FileLocker) |
|
|
lock (FileLocker) |
|
|
{ |
|
|
{ |
|
|
var path = GetFileDir(); |
|
|
var path = GetFilePath(logger); |
|
|
if (string.IsNullOrEmpty(path)) return "写入日志文件失败:无法获取日志文件路径。"; |
|
|
if (string.IsNullOrEmpty(path)) return "写入日志文件失败:无法获取日志文件路径。"; |
|
|
|
|
|
|
|
|
var bytes = TextUtility.ToBinary(TextUtility.Merge(plain, "\r\n")); |
|
|
var bytes = TextUtility.ToBinary(TextUtility.Merge(plain, "\r\n")); |
|
|
if (!StorageUtility.AppendFile(path, bytes)) return "写入日志文件失败。"; |
|
|
if (!StorageUtility.AppendFile(path, bytes)) return "写入日志文件失败。"; |
|
|
} |
|
|
} |
|
|
return null; |
|
|
return null; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 向日志文件输出文本,文件名按日期自动生成。
|
|
|
// 向日志文件输出文本,文件名按日期自动生成。
|
|
|
private static string ToFile(LogItem item) => ToFile(ToText(item)); |
|
|
private static string ToFile(LogItem item, Logger logger) => ToFile(ToText(item), logger); |
|
|
|
|
|
|
|
|
/// <summary>获取日志文件路径发生错误时返回 NULL 值。</summary>
|
|
|
/// <summary>获取日志文件路径发生错误时返回 NULL 值。</summary>
|
|
|
/// <remarks>d:\app\log\2020-02-02.log</remarks>
|
|
|
/// <remarks>默认例:<br/>d:\app\log\1970-01-01.log<br/>d:\www\app_data\log\1970-01-01.log</remarks>
|
|
|
/// <remarks>d:\www\app_data\log\2020-02-02.log</remarks>
|
|
|
public static string GetFilePath(Logger logger = null) |
|
|
public static string GetFileDir() |
|
|
|
|
|
{ |
|
|
{ |
|
|
|
|
|
var getter = FilePathGetter; |
|
|
|
|
|
if (getter != null) try { return getter.Invoke(); } catch { } |
|
|
|
|
|
|
|
|
// 找到 App_Data 目录。
|
|
|
// 找到 App_Data 目录。
|
|
|
var appDir = RuntimeUtility.ApplicationPath; |
|
|
var appDir = RuntimeUtility.ApplicationPath; |
|
|
var dataDir = Path.Combine(appDir, "app_data"); |
|
|
var dataDir = Path.Combine(appDir, "app_data"); |
|
@ -303,18 +311,18 @@ namespace Apewer |
|
|
|
|
|
|
|
|
#region 默认实列。
|
|
|
#region 默认实列。
|
|
|
|
|
|
|
|
|
private static Logger _default = new Logger(true, false, true); |
|
|
private static Logger _default = new Logger("Apewer.Logger.Default", true, false, true); |
|
|
private static Logger _console = new Logger(true, false, true); |
|
|
private static Logger _console = new Logger("Apewer.Logger.Console", true, false, true); |
|
|
private static Logger _web = new Logger(true, false, true); |
|
|
private static Logger _web = new Logger("Apewer.Logger.Web", true, false, true); |
|
|
|
|
|
|
|
|
#if DEBUG
|
|
|
#if DEBUG
|
|
|
internal static Logger _internals = new Logger(true, true, true); |
|
|
internal static Logger _internals = new Logger("Apewer.Logger.Internals", true, true, true); |
|
|
#else
|
|
|
#else
|
|
|
internal static Logger _internals = new Logger(true, false, false); |
|
|
internal static Logger _internals = new Logger("Apewer.Logger.Internals", true, false, false); |
|
|
#endif
|
|
|
#endif
|
|
|
|
|
|
|
|
|
/// <summary>内部的日志记录程序。</summary>
|
|
|
/// <summary>内部的日志记录程序。</summary>
|
|
|
public static Logger Internals { get => _internals; } |
|
|
internal static Logger Internals { get => _internals; } |
|
|
|
|
|
|
|
|
/// <summary>默认的日志记录程序。</summary>
|
|
|
/// <summary>默认的日志记录程序。</summary>
|
|
|
public static Logger Default { get => _default; } |
|
|
public static Logger Default { get => _default; } |
|
@ -325,9 +333,9 @@ namespace Apewer |
|
|
/// <summary>用于 Web 的日志记录程序。</summary>
|
|
|
/// <summary>用于 Web 的日志记录程序。</summary>
|
|
|
public static Logger Web { get => _web; } |
|
|
public static Logger Web { get => _web; } |
|
|
|
|
|
|
|
|
#endregion
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
#region 静态调用。
|
|
|
#region 静态调用。
|
|
|
|
|
|
|
|
|
/// <summary>使用 Logger.Default 写入日志,自动添加时间和日期,多个 Content 参数将以“ | ”分隔。</summary>
|
|
|
/// <summary>使用 Logger.Default 写入日志,自动添加时间和日期,多个 Content 参数将以“ | ”分隔。</summary>
|
|
|
public static void Write(params object[] content) => Default.Invoke(() => |
|
|
public static void Write(params object[] content) => Default.Invoke(() => |
|
@ -340,7 +348,7 @@ namespace Apewer |
|
|
item.Content = MergeContent(content); |
|
|
item.Content = MergeContent(content); |
|
|
|
|
|
|
|
|
if (console) ToConsole(item); |
|
|
if (console) ToConsole(item); |
|
|
if (file) ToFile(item); |
|
|
if (file) ToFile(item, Default); |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
@ -356,11 +364,11 @@ namespace Apewer |
|
|
item.Content = MergeContent(content); |
|
|
item.Content = MergeContent(content); |
|
|
|
|
|
|
|
|
if (console) ToConsole(item); |
|
|
if (console) ToConsole(item); |
|
|
if (file) ToFile(item); |
|
|
if (file) ToFile(item, Default); |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
#endregion
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|