Windows 10 UWP应用程序的日志记录器

24

我无法找到任何适用于Windows 10通用应用程序的记录器,我尝试了log4net、Microsoft企业库和Nlog等工具,但它们都不支持Windows 10通用平台。

有人能为Windows 10 UWP建议一个好的记录器吗?


NLog ver. 4.5支持UWP。 - Rolf Kristensen
5个回答

21

你尝试过使用MetroLog吗?你可以使用NuGet进行安装:

Install-Package MetroLog

这里是一个快速示例:

using MetroLog;
using MetroLog.Targets;

LogManagerFactory.DefaultConfiguration.AddTarget(LogLevel.Trace, LogLevel.Fatal, new FileStreamingTarget());

ILogger log = LogManagerFactory.DefaultLogManager.GetLogger<MainPage>();

log.Trace("This is a trace message.");

您可以在http://talkitbr.com/2015/06/11/adicionando-logs-em-universal-apps找到一个教程,解释如何在您的项目中添加它。另外也有关于检索这些日志的说明。


非常感谢 @talkitbr。 - Rashmin Javiya
3
同时,FileStreamingTarget 已经过时。建议使用 StreamingFileTarget 替代。 - tomab
您可以将应用程序洞察作为一种选项。我认为UWP应用程序默认带有AI。 - Emil

15

Serilog

使用Serilog作为中央日志接口的一种可能性,并配置一个与UWP兼容的Sink。

您可以使用众多提供的Sinks之一,也可以选择通过实现自定义sink来使用自己的日志基础设施。

为了使其更加有用,您可以使用Anotar.Serilog.Fody来使用Fody Code Weaver并使用Aspects使您的日志记录变得轻松。

通常,您需要使用一个中央日志提供程序进行应用程序生命周期管理(ALM),以及一个本地sink(文件)作为致命错误的后备。

MetroLog

MetroLog是在ETW和LocalState之上构建的简单日志基础架构。它快速且易于实施,但不支持集中式日志记录,因此无法帮助您进行ALM。

UWP Logging

通用Windows平台日志记录相对较新,仅适用于Windows 10和Windows Server 2016。您可以选择ETW和LocalStorage之间进行选择。它为您提供了对日志记录外观的大多数低级控制,但自然也需要最多的实施工作并且缺少ALM功能。

相关链接


之前使用过Metrolog。但是在从设备获取日志时遇到了问题。现在转而使用Serilog。 - Syaiful Nizam Yahya
1
你在使用 Serilog 和 UWP 时用的是哪个 sink?我无法从中获得任何输出。 - Erik Berkun-Drevnig
不幸的是,控制台日志记录基本上毫无用处。我主要使用Serilog将日志写入远程日志存储(Logstash / Elasticsearch;Seq和RayGun也是很好的选择)。在未来,Microsoft.Azure.Mobile将成为另一个选择。理想情况下,您可以使用Serilog作为主要日志记录层,并在MetroLog或UWP Logging之上实现自定义汇聚以进行本地日志记录输出,以便您可以配置哪些日志记录输出应针对远程日志,哪些应针对本地日志。如果您不想编写自定义汇聚,还可以考虑使用Serilog.Sinks.Observable。 - MovGP0
之前使用过Metrolog,在使用过程中遇到了与FileLoadException文件正在使用错误相关的错误。 - xyzWty

7

如果你想要记录到文件并且利用微软的轻量级DI框架,你可以使用Serilog。

在Nuget包管理器控制台中输入以下内容:

Install-Package Microsoft.Extensions.DependencyInjection
Install-Package Microsoft.Extensions.Logging
Install-Package Serilog.Extensions.Logging.File

在组合根处设置依赖注入容器。在我们的情况下,这是在App.xaml.cs文件中的OnLaunched方法。

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Windows.Storage;
...

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
     ...
    // Create IOC container and add logging feature to it.
    IServiceCollection services = new ServiceCollection();
    services.AddLogging();

    // Build provider to access the logging service.
    IServiceProvider provider = services.BuildServiceProvider();

    // UWP is very restrictive of where you can save files on the disk.
    // The preferred place to do that is app's local folder.
    StorageFolder folder = ApplicationData.Current.LocalFolder;
    string fullPath = $"{folder.Path}\\Logs\\App.log";

    // Tell the logging service to use Serilog.File extension.
    provider.GetService<ILoggerFactory>().AddFile(fullPath);
    ...
}

一旦设置完成,记录日志非常简单。只需将记录器注入到您的类中即可。

using Microsoft.Extensions.Logging;

class MyClass
{
    readonly ILogger<MyClass> logger;

    public MyClass(ILogger<MyClass> logger)
    {
        this.logger = logger;
        logger.LogInformation("Hello from MyClass.");
    }
}

你的日志文件应该创建在以下位置:

C:\Users\你的用户名\AppData\Local\Packages\f15fdadf-faae-4f4a-8445-5feb195ff692_68newbw0j54vy\LocalState\Logs\App-20171206.log,

f15fdadf-faae-4f4a-8445-5feb195ff692_68newbw0j54vy 是我的解决方案中 Package.appxmanifest 文件中的包名称。

请注意,默认情况下,AppData 文件夹在文件资源管理器中是隐藏的。

以下是其内容:

2017-12-06T17:06:33.1358005-06:00  [INF] Hello from MyClass. (25278b08)

1
当调用MyClass实例时,如何在类中注入Logger? - xyzWty
日志记录器注入由IOC容器自动处理。在上面的OnLaunched方法中,services.AddLogging()告诉IOC容器在MyClass实例化时为您注入日志记录器。 - Mariusz Bialobrzeski

4

我所了解的唯一解决方案是使用windows.foundation.diagnostics命名空间中的API进行ETW跟踪。

微软提供了这里的示例。


如何读取日志信息?我已经尝试了FileLoggingSession示例,并使用wpa.exe查看,我只能在Graph Explorer中看到事件,但诊断控制台没有显示LogMessage。 - Ryan
1
虽然事件跟踪类似于日志记录,但是它与日志记录不同。事件跟踪用于观察应用程序的执行和性能,并且可以随时按需开启或关闭。它会快速生成大量数据,因此默认情况下被禁用。日志记录是一种始终处于活动状态的东西,应该用于安全(例如用户登录和注销、访问受保护资源等)和稳定性(例如应用程序崩溃时的异常)。由于其安全性问题,必须始终处于活动状态。 - MovGP0

1

您可以在UWP中使用标准的Serilog滚动文件记录器,只需告诉记录器日志输出的位置即可。以下是一些设置代码(我正在使用Autofac):

private static void RegisterLogger(ContainerBuilder builder)
{
    const string fileOutputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level}] {Message}{NewLine}{Exception}";
    var logPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "Logs", "MyAppName-{Date}.log");

    var logConfiguration = new LoggerConfiguration()
                            .MinimumLevel.Verbose()
                            .WriteTo.RollingFile(logPath, outputTemplate: fileOutputTemplate);

    Log.Logger = logConfiguration.CreateLogger();

    builder.RegisterLogger();
}

```


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接