gpt4 book ai didi

c# - LoggingSession.SaveToFileAsync 有时会创建以 .etl.tmp 结尾的文件

转载 作者:行者123 更新时间:2023-11-30 16:08:38 25 4
gpt4 key购买 nike

我有一个通用的 Windows/WindowsPhone 8.1 应用程序,我在其中使用 LoggingSession 在我的应用程序运行时记录消息。

当发生未处理的异常时,我会记录该异常,然后等待对 LoggingSession.SaveToFileAsync 的调用以将日志转储到文件中。下次启动我的应用程序时,我会上传日志文件并在我这边接收它。

我看到的问题是,有时我的日志文件以 .etl.tmp 结尾(通常文件大小为 50 - 100 Kb),当我尝试打开它们时(使用 tracerpt 或 Windows 事件查看器)我没有看不到任何日志。其他时候,我打开 .etl.tmp 文件,通常大小约为 200Kb,我会看到一些日志条目。还有一些时候,日志文件(通常小于 20Kb)正确地以 .etl 扩展名结尾(没有 .tmp)并且所有记录的消息都在那里。

1) 为什么 LoggingSession.SaveToFileAsync 有时会生成扩展名为 .etl.tmp 的文件?

2) 关于如何解决这个问题有什么建议吗?在将它们保存到文件之前,我需要捕获所有日志(甚至是未处理的异常),这就是我在我的应用程序的未处理异常事件处理程序中调用 LoggingSession.SaveToFileAsync 的原因。我还需要我的日志记录解决方案具有高性能,并且不会过多地降低我的应用程序的速度。

谢谢


这是精简的示例代码:

public sealed partial class App : Application
{
.
.
.

public static ETWLogger Logger;
public App()
{
InitializeComponent();

Logger = new ETWLogger();

Suspending += OnSuspending;
UnhandledException += OnUnhandledExceptionAsync;
}

private async void OnUnhandledExceptionAsync(object sender, UnhandledExceptionEventArgs args)
{
await Logger.SaveToFileAsync();
}

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
// Check to see if there are files in the Log folder. If so
// then upload them and then delete all files in the Log folder.
}

.
.
.
}

public class ETWLogger
{
private LoggingSession _session;
private LoggingChannel _channel;
private StorageFolder _logFolder;
.
.
.

public ETWLogger()
{
.
.
.
_session = new LoggingSession("DefaultSession");
_channel = new LoggingChannel("DefaultChannel");
_session.AddLoggingChannel(_channel);

_logFolder = StorageHelper.CreateSubFolder(ApplicationData.Current.LocalFolder, "LogFiles", CreationCollisionOption.OpenIfExists);
.
.
.
}

public async Task SaveToFileAsync()
{
if (_session == null) return;

var fileName = DateTime.Now.ToString("yyyyMMdd-HHmmssTzz", CultureInfo.InvariantCulture) + ".etl";
await _session.SaveToFileAsync(_logUploadFolder, fileName);
}

.
.
.
}

最佳答案

我很清楚这里发生了什么。您描述了 Microsoft 使用的一种常用技术,它可以防止文件损坏和数据丢失。它不是创建您要求的 foo.etl 文件,而是首先创建具有不同名称的文件。像 foo.etl.tmp。只有当文件写入成功,或者换句话说,异步方法真正完成时,它才会将文件从 foo.etl.tmp 重命名为 foo.etl。

您现在可以很好地保证您始终获得完整编写的“好”文件。没有腐败。如果您以前有一个同名文件,那么它不会被损坏的半写文件替换。没有数据丢失。

When an unhandled exception occurs, I log the exception and then I await a call

“未处理的异常”是问题所在。仅当异常不足以阻止异步/等待管道继续工作时,您的日志文件才能被完整写入。或者换句话说,您现在只能获得“温和”的异常信息。坏的产生了写了一半的 foo.etl.tmp 文件,应用程序在完成之前就崩溃了。

如果你想知道“坏”的,你不能在这里使用await。 SaveToFileAsync() 调用必须同步完成。

关于c# - LoggingSession.SaveToFileAsync 有时会创建以 .etl.tmp 结尾的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28888479/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com