日志工具由來已久,是很受大家歡迎的debug工具。其中.NET平台上很出名的是log4net,但是由於Windows 10通用應用項目沒有了System.Configuration引用,所以也就不能很好使用log4net工具了。
Windows Runtime框架大家從它面世以來一直在吐槽,log4net也因為其缺少api不能使用,但是我們仍然可以找到替代方案。Windows.Foundation.Diagnostics命名空間下就提供了一套簡單的日志工具,能夠正常使用下去。
方案
根據MSDN查到的信息,Windows Runtime API中的LoggingChannel和logSession類提供了所需的功能,官方也封裝了一段示例代碼。在此基礎上,我又進一步封裝了一下:
public class LogManager { public static void Log(string message) { Logger.GetLogger().logChannel.LogMessage(message, LoggingLevel.Information); } public static void LogError(string message) { Logger.GetLogger().logChannel.LogMessage(message, LoggingLevel.Error); } public static void InitiateLogger() { Logger.GetLogger().InitiateLogger(); Logger.GetLogger().Deletefile(); } } class Logger { public LoggingChannel logChannel; public LoggingSession logSession; private StorageFolder logUploadFolder; public const string LOG_SESSION_RESROUCE_NAME = "LogSession"; static private Logger logger; private const int DAYS_TO_DELETE = 15; public async void InitiateLogger() { logChannel = new LoggingChannel("YSYChannel",null); logSession = new LoggingSession("YSY Session"); logSession.AddLoggingChannel(logChannel); await RegisterUnhandledErrorHandler(); } /// <summary> /// 單例 /// </summary> /// <returns></returns> static public Logger GetLogger() { if (logger == null) { logger = new Logger(); } return logger; } private async Task RegisterUnhandledErrorHandler() { logUploadFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("MyLogFile", CreationCollisionOption.OpenIfExists); CoreApplication.UnhandledErrorDetected += CoreApplication_UnhandledErrorDetected; } /// <summary> /// 處理任何未處理的異常 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void CoreApplication_UnhandledErrorDetected(object sender, UnhandledErrorDetectedEventArgs e) { try { logChannel.LogMessage("Caught the exception"); e.UnhandledError.Propagate(); } catch (Exception ex) { logChannel.LogMessage($"UnhandledErro: {ex.Message}", ex.Message), LoggingLevel.Critical); //logChannel.LogMessage(string.Format("Effor Message: {0}", ex.Message)); if (logSession != null) { //var filename = DateTime.Now.ToString("yyyyMMdd-HHmmssTzz") + ".etl"; var filename = DateTime.Now.ToString("yyyyMMdd") + ".etl"; var logSaveTast =await logSession .SaveToFileAsync(logUploadFolder, filename); } // throw; } } /// <summary> /// 刪除之前日期的日志 /// </summary> public async void Deletefile() { try { var logFiles = await logUploadFolder.GetFilesAsync(); foreach (var logFile in logFiles) { if ((DateTime.Now - logFile.DateCreated).Days > DAYS_TO_DELETE) { await logFile.DeleteAsync(); } } } catch (Exception ex) { logChannel.LogMessage(ex.Message); } } }
使用
Logger類采用單例寫法,使用之前我們需要先進行初始化。一般我們應當在App.xaml.cs文件中的OnLaunch方法中調用初始化方法,如下:
protected override void OnLaunched(LaunchActivatedEventArgs e) { //初始化日志工具 LogManager.InitiateLogger(); LogManager.Log("應用啟動"); }
初始化方法會在應用獨立存儲目錄下創建一個MyLogFile日志文件夾,當日的日志文件將會在此文件夾中創建。
下面代碼則會將http錯誤請求信息寫入進此日志文件,以供我們后續處理。
catch(Exception ex) { LogManager.LogError($"http請求錯誤:{ex.Message}"); }
我們可以在應用獨立存儲文件夾中看到我們的日志文件,如下:
雙擊打開日志文件后,即可在Windows行為分析器中查看詳細信息,如下:
總結
以上日志工具為目前可選的方案,同時我們也可很容易自己寫一套基於文本輸出的日志工具,隨着Windows 10的普及,會有更多更好用的框架出現。