2015-03-05 2 views
3

У меня есть универсальное приложение Windows/WindowsPhone 8.1, где я использую LoggingSession для регистрации сообщений по мере запуска моего приложения.LoggingSession.SaveToFileAsync иногда создает файлы, заканчивающиеся на .etl.tmp

Когда возникает необработанное исключение, я регистрирую это исключение, а затем жду вызова LoggingSession.SaveToFileAsync для вывода журналов в файл. При следующем запуске приложения я загружу файл журнала и получаю его в конце.

Проблема, которую я вижу, заключается в том, что иногда мои файлы журналов заканчиваются на .etl.tmp (обычно файлы имеют размер 50 - 100 КБ), и когда я пытаюсь их открыть (с помощью tracerpt или Windows Event Viewer), я Нет никаких журналов. В других случаях я открываю файлы .etl.tmp, размер которых обычно составляет около 200 КБ, и я вижу некоторые записи в журнале. И все же в других случаях файлы журнала (обычно до 20 Кб) корректно заканчиваются расширением .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); 
    } 

    . 
    . 
    . 
} 
+1

трудно дать вам точный ответ, основанный на вопросе. Ваши вопросы действительны, однако мы не можем видеть, как вы кодировали процесс асинхронного кода. Не могли бы вы показать свой код в отношении релевантности вашего вопроса. – MethodMan

+0

Добавлен образец кода! –

+0

У меня также есть эта проблема –

ответ

3

У меня есть довольно хорошее представление о том, что происходит здесь. Вы описываете общий метод, который использует Microsoft, он предотвращает повреждение файлов и потерю данных. Вместо создания файла foo.etl, который вы просили, он первый создает файл с другим именем. Как foo.etl.tmp. Только когда файл успешно записан или, другими словами, метод async действительно завершен, он переименовывает файл из foo.etl.tmp в foo.etl.

У вас теперь есть отличная гарантия того, что вы всегда получите полностью написанный «хороший» файл. Нет коррупции. И если у вас есть предыдущий файл с тем же именем, он не заменяется коррумпированным наполовину написанным файлом. Нет потери данных.

При возникновении необработанного исключения, я вхожу исключение и затем я жду вызова

«необработанное исключение» является проблемой. Ваш файл журнала может быть полностью записан только в том случае, если исключение не является достаточно фатальным, чтобы предотвратить продолжение работы async/wait plumbing. Или, другими словами, вы получаете только «мягкую» информацию об исключении прямо сейчас. Плохие производят наполовину написанный файл foo.etl.tmp, приложение закрыто до того, как оно будет завершено.

Здесь вы можете не использовать await, если хотите узнать о «плохих». Вызов SaveToFileAsync() должен выполняться синхронно.

+0

Да, я изменил вызов на синхронный, и это исправило мою проблему.Я просто не понимаю, почему Microsoft использует ожидаемый вызов для сохранения файла журнала в обработчике обработанных приложений без видимых действий, когда он явно не работает и должен быть синхронным вызовом. –

+0

Хмм, трудно поверить, что Microsoft использует или рекомендует это. Вы реализуете функцию, которая [уже доступна] (https://blogs.windows.com/buildingapps/2015/07/13/crash-analysis-in-the-unified-dev-center/). –

+0

Спасибо за ответ! Прежде чем вручить вам награду, я вызываю 'var logSaveTask = logSession.SaveToFileAsync (logUploadFolder, имя_файла) .AsTask();' затем в следующей строке я вызываю 'logSaveTask.Wait();' и я вижу эту проблему , Разве это недостаточно синхронно? Должен ли я открыть другой вопрос? –

Смежные вопросы