From bb7de7f9d197b9a83f2a0954d6ec3486e3830ceb Mon Sep 17 00:00:00 2001 From: cocoa-dev004 <66989461+cocoa-dev004@users.noreply.github.com> Date: Mon, 11 Jul 2022 16:17:12 +0900 Subject: [PATCH 1/2] Rotate event logs --- .../Covid19Radar.Android.csproj | 1 + .../Covid19Radar.Android/MainApplication.cs | 14 ++ .../DataMaintainanceBackgroundService.cs | 107 ++++++++++ .../Migration/MigrationProcessService.cs | 5 + .../Services/Migration/WorkManagerMigrator.cs | 5 + Covid19Radar/Covid19Radar.iOS/AppDelegate.cs | 14 ++ .../Covid19Radar.iOS/Covid19Radar.iOS.csproj | 1 + Covid19Radar/Covid19Radar.iOS/Info.plist | 1 + .../DataMaintainanceBackgroundService.cs | 112 ++++++++++ .../EventLogSubmissionBackgroundService.cs | 7 + Covid19Radar/Covid19Radar/App.xaml.cs | 14 +- .../Covid19Radar/Common/AppConstants.cs | 5 + .../Repository/EventLogRepository.cs | 90 ++++++-- .../AbsDataMaintainanceBackgroundService.cs | 44 ++++ .../ViewModels/Settings/DebugPageViewModel.cs | 5 + .../Views/Settings/DebugPage.xaml | 4 + .../Repository/EventLogRepositoryTests.cs | 198 ++++++++++++++++++ 17 files changed, 612 insertions(+), 15 deletions(-) create mode 100644 Covid19Radar/Covid19Radar.Android/Services/DataMaintainanceBackgroundService.cs create mode 100644 Covid19Radar/Covid19Radar.iOS/Services/DataMaintainanceBackgroundService.cs create mode 100644 Covid19Radar/Covid19Radar/Services/AbsDataMaintainanceBackgroundService.cs create mode 100644 Covid19Radar/Tests/Covid19Radar.UnitTests/Repository/EventLogRepositoryTests.cs diff --git a/Covid19Radar/Covid19Radar.Android/Covid19Radar.Android.csproj b/Covid19Radar/Covid19Radar.Android/Covid19Radar.Android.csproj index ad99d5244..70ff8a800 100644 --- a/Covid19Radar/Covid19Radar.Android/Covid19Radar.Android.csproj +++ b/Covid19Radar/Covid19Radar.Android/Covid19Radar.Android.csproj @@ -193,6 +193,7 @@ + diff --git a/Covid19Radar/Covid19Radar.Android/MainApplication.cs b/Covid19Radar/Covid19Radar.Android/MainApplication.cs index b2d213f2b..4a26647bb 100644 --- a/Covid19Radar/Covid19Radar.Android/MainApplication.cs +++ b/Covid19Radar/Covid19Radar.Android/MainApplication.cs @@ -49,6 +49,9 @@ private Lazy _exposureDetectionBackground private readonly Lazy _eventLogSubmissionBackgroundService = new Lazy(() => ContainerLocator.Current.Resolve()); + private Lazy _dataMaintainanceService + = new Lazy(() => ContainerLocator.Current.Resolve()); + private Lazy _loggerService = new Lazy(() => ContainerLocator.Current.Resolve()); @@ -98,6 +101,7 @@ private void ScheduleBackgroundTasks() { _loggerService.Value.Exception("Failed to schedule ExposureDetectionBackgroundService", exception); } + try { _eventLogSubmissionBackgroundService.Value.Schedule(); @@ -106,6 +110,15 @@ private void ScheduleBackgroundTasks() { _loggerService.Value.Exception("Failed to schedule EventLogSubmissionBackgroundService", exception); } + + try + { + _dataMaintainanceService.Value.Schedule(); + } + catch (Exception exception) + { + _loggerService.Value.Exception("Failed to schedule DataMaintainanceBackgroundService", exception); + } } private void SetupENClient(ExposureNotificationClient client) @@ -141,6 +154,7 @@ private void RegisterPlatformTypes(IContainer container) container.Register(Reuse.Singleton); container.Register(Reuse.Singleton); container.Register(Reuse.Singleton); + container.Register(Reuse.Singleton); } public Task GetExposureConfigurationAsync() diff --git a/Covid19Radar/Covid19Radar.Android/Services/DataMaintainanceBackgroundService.cs b/Covid19Radar/Covid19Radar.Android/Services/DataMaintainanceBackgroundService.cs new file mode 100644 index 000000000..33788b0f1 --- /dev/null +++ b/Covid19Radar/Covid19Radar.Android/Services/DataMaintainanceBackgroundService.cs @@ -0,0 +1,107 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +using System; +using Android.Content; +using Android.Runtime; +using AndroidX.Work; +using Covid19Radar.Repository; +using Covid19Radar.Services; +using Covid19Radar.Services.Logs; +using Java.Util.Concurrent; +using Prism.Ioc; +using Xamarin.Essentials; + +namespace Covid19Radar.Droid.Services +{ + public class DataMaintainanceBackgroundService : AbsDataMaintainanceBackgroundService + { + private const string CURRENT_WORK_NAME = "data_maintainance_worker_20220628"; + + private const long INTERVAL_IN_HOURS = 24; + private const long BACKOFF_DELAY_IN_MINUTES = 60; + + public DataMaintainanceBackgroundService( + ILoggerService loggerService, + IEventLogRepository eventLogRepository + ) : base(loggerService, eventLogRepository) + { + // do nothing + } + + public override void Schedule() + { + LoggerService.StartMethod(); + + WorkManager workManager = WorkManager.GetInstance(Platform.AppContext); + + PeriodicWorkRequest periodicWorkRequest = CreatePeriodicWorkRequest(); + workManager.EnqueueUniquePeriodicWork( + CURRENT_WORK_NAME, + ExistingPeriodicWorkPolicy.Keep, + periodicWorkRequest + ); + + LoggerService.EndMethod(); + } + + private PeriodicWorkRequest CreatePeriodicWorkRequest() + { + var workRequestBuilder = new PeriodicWorkRequest.Builder( + typeof(DataMaintainanceBackgroundWorker), + INTERVAL_IN_HOURS, TimeUnit.Hours + ) + .SetConstraints(new Constraints.Builder() + .SetRequiresBatteryNotLow(true) + .Build()) + .SetBackoffCriteria(BackoffPolicy.Linear, BACKOFF_DELAY_IN_MINUTES, TimeUnit.Minutes); + return workRequestBuilder.Build(); + } + } + + [Preserve] + public class DataMaintainanceBackgroundWorker : Worker + { + private Lazy _dataMaintainanceBackgroundService + => new Lazy(() => ContainerLocator.Current.Resolve()); + private Lazy _loggerService => new Lazy(() => ContainerLocator.Current.Resolve()); + + public DataMaintainanceBackgroundWorker(Context context, WorkerParameters workerParameters) + : base(context, workerParameters) + { + // do nothing + } + + public override Result DoWork() + { + var dataMaintainanceBackgroundService = _dataMaintainanceBackgroundService.Value; + var loggerService = _loggerService.Value; + + loggerService.StartMethod(); + + try + { + dataMaintainanceBackgroundService.ExecuteAsync().GetAwaiter().GetResult(); + return Result.InvokeSuccess(); + } + catch (Exception exception) + { + loggerService.Exception("Exception", exception); + return Result.InvokeFailure(); + } + finally + { + loggerService.EndMethod(); + } + } + + public override void OnStopped() + { + base.OnStopped(); + + _loggerService.Value.Warning("OnStopped"); + } + } +} + diff --git a/Covid19Radar/Covid19Radar.Android/Services/Migration/MigrationProcessService.cs b/Covid19Radar/Covid19Radar.Android/Services/Migration/MigrationProcessService.cs index 9ee3dbbbb..a9209cafe 100644 --- a/Covid19Radar/Covid19Radar.Android/Services/Migration/MigrationProcessService.cs +++ b/Covid19Radar/Covid19Radar.Android/Services/Migration/MigrationProcessService.cs @@ -69,14 +69,18 @@ public override Result DoWork() public class MigrationProccessService : IMigrationProcessService { private readonly AbsExposureDetectionBackgroundService _exposureDetectionBackgroundService; + private readonly AbsDataMaintainanceBackgroundService _dataMaintainanceBackgroundService; + private readonly ILoggerService _loggerService; public MigrationProccessService( AbsExposureDetectionBackgroundService exposureDetectionBackgroundService, + AbsDataMaintainanceBackgroundService dataMaintainanceBackgroundService, ILoggerService loggerService ) { _exposureDetectionBackgroundService = exposureDetectionBackgroundService; + _dataMaintainanceBackgroundService = dataMaintainanceBackgroundService; _loggerService = loggerService; } @@ -86,6 +90,7 @@ public async Task SetupAsync() await new WorkManagerMigrator( _exposureDetectionBackgroundService, + _dataMaintainanceBackgroundService, _loggerService ).ExecuteAsync(); diff --git a/Covid19Radar/Covid19Radar.Android/Services/Migration/WorkManagerMigrator.cs b/Covid19Radar/Covid19Radar.Android/Services/Migration/WorkManagerMigrator.cs index c0e02ee8a..5fc117812 100644 --- a/Covid19Radar/Covid19Radar.Android/Services/Migration/WorkManagerMigrator.cs +++ b/Covid19Radar/Covid19Radar.Android/Services/Migration/WorkManagerMigrator.cs @@ -19,14 +19,18 @@ internal class WorkManagerMigrator }; private readonly AbsExposureDetectionBackgroundService _exposureDetectionBackgroundService; + private readonly AbsDataMaintainanceBackgroundService _dataMaintainanceBackgroundService; + private readonly ILoggerService _loggerService; public WorkManagerMigrator( AbsExposureDetectionBackgroundService exposureDetectionBackgroundService, + AbsDataMaintainanceBackgroundService dataMaintainanceBackgroundService, ILoggerService loggerService ) { _exposureDetectionBackgroundService = exposureDetectionBackgroundService; + _dataMaintainanceBackgroundService = dataMaintainanceBackgroundService; _loggerService = loggerService; } @@ -38,6 +42,7 @@ internal Task ExecuteAsync() CancelOldWorks(workManager, OldWorkNames, _loggerService); _exposureDetectionBackgroundService.Schedule(); + _dataMaintainanceBackgroundService.Schedule(); _loggerService.EndMethod(); diff --git a/Covid19Radar/Covid19Radar.iOS/AppDelegate.cs b/Covid19Radar/Covid19Radar.iOS/AppDelegate.cs index 6c491c375..3ebfa7aff 100644 --- a/Covid19Radar/Covid19Radar.iOS/AppDelegate.cs +++ b/Covid19Radar/Covid19Radar.iOS/AppDelegate.cs @@ -44,6 +44,9 @@ private Lazy _exposureDetectionBackground private readonly Lazy _eventLogSubmissionBackgroundService = new Lazy(() => ContainerLocator.Current.Resolve()); + private Lazy _dataMaintainanceBackgroundService + = new Lazy(() => ContainerLocator.Current.Resolve()); + private Lazy _exposureDetectionService = new Lazy(() => ContainerLocator.Current.Resolve()); @@ -127,6 +130,7 @@ private void ScheduleBackgroundTask() { _loggerService.Value.Exception("Failed to schedule ExposureDetectionBackgroundService", exception); } + try { _eventLogSubmissionBackgroundService.Value.Schedule(); @@ -135,6 +139,15 @@ private void ScheduleBackgroundTask() { _loggerService.Value.Exception("Failed to schedule EventLogSubmissionBackgroundService", exception); } + + try + { + _dataMaintainanceBackgroundService.Value.Schedule(); + } + catch (Exception exception) + { + _loggerService.Value.Exception("Failed to schedule DataMaintainanceBackgroundService", exception); + } } private bool IsUniversalLinks(NSDictionary launchOptions) @@ -274,6 +287,7 @@ private void RegisterPlatformTypes(IContainer container) #endif container.Register(Reuse.Singleton); container.Register(Reuse.Singleton); + container.Register(Reuse.Singleton); } public Task GetExposureConfigurationAsync() diff --git a/Covid19Radar/Covid19Radar.iOS/Covid19Radar.iOS.csproj b/Covid19Radar/Covid19Radar.iOS/Covid19Radar.iOS.csproj index e423d9e96..b4e913796 100644 --- a/Covid19Radar/Covid19Radar.iOS/Covid19Radar.iOS.csproj +++ b/Covid19Radar/Covid19Radar.iOS/Covid19Radar.iOS.csproj @@ -272,6 +272,7 @@ + diff --git a/Covid19Radar/Covid19Radar.iOS/Info.plist b/Covid19Radar/Covid19Radar.iOS/Info.plist index 751350d06..ebe15152b 100644 --- a/Covid19Radar/Covid19Radar.iOS/Info.plist +++ b/Covid19Radar/Covid19Radar.iOS/Info.plist @@ -56,6 +56,7 @@ APP_PACKAGE_NAME.exposure-notification APP_PACKAGE_NAME.delete-old-logs APP_PACKAGE_NAME.eventlog-submission + APP_PACKAGE_NAME.data-maintainance UIAppFonts diff --git a/Covid19Radar/Covid19Radar.iOS/Services/DataMaintainanceBackgroundService.cs b/Covid19Radar/Covid19Radar.iOS/Services/DataMaintainanceBackgroundService.cs new file mode 100644 index 000000000..3df569f1a --- /dev/null +++ b/Covid19Radar/Covid19Radar.iOS/Services/DataMaintainanceBackgroundService.cs @@ -0,0 +1,112 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +using System; +using System.Threading; +using System.Threading.Tasks; +using BackgroundTasks; +using Covid19Radar.Common; +using Covid19Radar.Repository; +using Covid19Radar.Services; +using Covid19Radar.Services.Logs; +using Foundation; +using Xamarin.Essentials; + +namespace Covid19Radar.iOS.Services +{ + public class DataMaintainanceBackgroundService : AbsDataMaintainanceBackgroundService + { + private const int TASK_INTERVAL_IN_DAYS = 1; + private static readonly string BGTASK_IDENTIFIER = AppInfo.PackageName + ".data-maintainance"; + + private readonly IDateTimeUtility _dateTimeUtility; + + public DataMaintainanceBackgroundService( + ILoggerService loggerService, + IEventLogRepository eventLogRepository, + IDateTimeUtility dateTimeUtility + ) : base(loggerService, eventLogRepository) + { + _dateTimeUtility = dateTimeUtility; + } + + public override void Schedule() + { + LoggerService.StartMethod(); + + var result = BGTaskScheduler.Shared.Register(BGTASK_IDENTIFIER, null, task => + { + LoggerService.Info("Background task has been started."); + + DateTime nextDateTime = _dateTimeUtility.UtcNow.Date.AddDays(TASK_INTERVAL_IN_DAYS); + ScheduleBgTask(nextDateTime); + + var cancellationTokenSource = new CancellationTokenSource(); + task.ExpirationHandler = cancellationTokenSource.Cancel; + + _ = Task.Run(async () => + { + try + { + await ExecuteAsync(); + task.SetTaskCompleted(true); + } + catch (OperationCanceledException exception) + { + LoggerService.Exception($"Background task canceled.", exception); + task.SetTaskCompleted(false); + } + catch (Exception exception) + { + LoggerService.Exception($"Exception", exception); + task.SetTaskCompleted(false); + } + finally + { + cancellationTokenSource.Dispose(); + } + }, cancellationTokenSource.Token); + }); + + if (result) + { + LoggerService.Debug("BGTaskScheduler.Shared.Register succeeded."); + } + else + { + LoggerService.Info("BGTaskScheduler.Shared.Register failed."); + } + + ScheduleBgTask(_dateTimeUtility.UtcNow); + + LoggerService.EndMethod(); + } + + private void ScheduleBgTask(DateTime nextDateTime) + { + LoggerService.StartMethod(); + + try + { + BGProcessingTaskRequest bgTaskRequest = new BGProcessingTaskRequest(BGTASK_IDENTIFIER) + { + EarliestBeginDate = NSDate.FromTimeIntervalSince1970(nextDateTime.ToUnixEpoch()) + }; + + BGTaskScheduler.Shared.Submit(bgTaskRequest, out var error); + if (error != null) + { + NSErrorException exception = new NSErrorException(error); + LoggerService.Exception("BGTaskScheduler submit failed.", exception); + throw exception; + } + } + finally + { + LoggerService.EndMethod(); + } + } + } +} + diff --git a/Covid19Radar/Covid19Radar.iOS/Services/EventLogSubmissionBackgroundService.cs b/Covid19Radar/Covid19Radar.iOS/Services/EventLogSubmissionBackgroundService.cs index eb6b65720..34736ba7b 100644 --- a/Covid19Radar/Covid19Radar.iOS/Services/EventLogSubmissionBackgroundService.cs +++ b/Covid19Radar/Covid19Radar.iOS/Services/EventLogSubmissionBackgroundService.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using BackgroundTasks; using Covid19Radar.Common; +using Covid19Radar.Repository; using Covid19Radar.Services; using Covid19Radar.Services.Logs; using Foundation; @@ -21,14 +22,17 @@ public class EventLogSubmissionBackgroundService : AbsEventLogSubmissionBackgrou private const double ONE_DAY_IN_SECONDS = 1 * 24 * 60 * 60; private readonly IEventLogService _eventLogService; + private readonly IEventLogRepository _eventLogRepository; private readonly ILoggerService _loggerService; public EventLogSubmissionBackgroundService( IEventLogService eventLogService, + IEventLogRepository eventLogRepository, ILoggerService loggerService ) : base() { _eventLogService = eventLogService; + _eventLogRepository = eventLogRepository; _loggerService = loggerService; } @@ -60,6 +64,9 @@ private void HandleSendLogAsync(BGAppRefreshTask task) _loggerService.Info("HandleSendLogAsync() Task.Run() start"); try { + await _eventLogRepository.RotateAsync( + AppConstants.EventLogFileExpiredSeconds); + await _eventLogService.SendAllAsync( AppConstants.EventLogMaxRequestSizeInBytes, AppConstants.EventLogMaxRetry); diff --git a/Covid19Radar/Covid19Radar/App.xaml.cs b/Covid19Radar/Covid19Radar/App.xaml.cs index cbcb98b91..af62e702d 100644 --- a/Covid19Radar/Covid19Radar/App.xaml.cs +++ b/Covid19Radar/Covid19Radar/App.xaml.cs @@ -37,6 +37,8 @@ public partial class App : PrismApplication private ILoggerService LoggerService; private ILogFileService LogFileService; + private IEventLogRepository EventLogRepository { get; set; } + /* * The Xamarin Forms XAML Previewer in Visual Studio uses System.Activator.CreateInstance. * This imposes a limitation in which the App class must have a default constructor. @@ -55,6 +57,8 @@ protected override void OnInitialized() LogFileService = Container.Resolve(); LogFileService.SetSkipBackupAttributeToLogDir(); + EventLogRepository = Container.Resolve(); + LogUnobservedTaskExceptions(); FirstLoad = false; @@ -234,19 +238,25 @@ private static void RegisterCommonTypes(IContainer container) container.Register(Reuse.Singleton); } - protected override void OnStart() + protected override async void OnStart() { // Initialize periodic log delete service var logPeriodicDeleteService = Container.Resolve(); logPeriodicDeleteService.Init(); LogFileService.Rotate(); + + await EventLogRepository.RotateAsync( + AppConstants.EventLogFileExpiredSeconds); } - protected override void OnResume() + protected override async void OnResume() { base.OnResume(); LogFileService.Rotate(); + + await EventLogRepository.RotateAsync( + AppConstants.EventLogFileExpiredSeconds); } protected override void OnSleep() diff --git a/Covid19Radar/Covid19Radar/Common/AppConstants.cs b/Covid19Radar/Covid19Radar/Common/AppConstants.cs index c240e0e66..c3736c348 100644 --- a/Covid19Radar/Covid19Radar/Common/AppConstants.cs +++ b/Covid19Radar/Covid19Radar/Common/AppConstants.cs @@ -91,6 +91,11 @@ public static readonly DateTime COCOA_FIRST_RELEASE_DATE /// public const int EventLogMaxRetry = 3; + /// + /// Event log file expiration date. (seconds) + /// + public const int EventLogFileExpiredSeconds = 14 * 24 * 60 * 60; // 14 days + #region Other Private Methods private static TimeZoneInfo JstTimeZoneInfo() diff --git a/Covid19Radar/Covid19Radar/Repository/EventLogRepository.cs b/Covid19Radar/Covid19Radar/Repository/EventLogRepository.cs index ec133b539..4b424c87e 100644 --- a/Covid19Radar/Covid19Radar/Repository/EventLogRepository.cs +++ b/Covid19Radar/Covid19Radar/Repository/EventLogRepository.cs @@ -20,19 +20,12 @@ namespace Covid19Radar.Repository { public interface IEventLogRepository { - public Task> GetLogsAsync( - long maxSize = AppConstants.EventLogMaxRequestSizeInBytes - ); - - public Task RemoveAsync(EventLog eventLog); - - public Task RemoveAllAsync(); - - public Task AddEventNotifiedAsync( - long maxSize = AppConstants.EventLogMaxRequestSizeInBytes - ); - - public Task IsExist(); + Task> GetLogsAsync(long maxSize = AppConstants.EventLogMaxRequestSizeInBytes); + Task RemoveAsync(EventLog eventLog); + Task RemoveAllAsync(); + Task AddEventNotifiedAsync(long maxSize = AppConstants.EventLogMaxRequestSizeInBytes); + Task IsExist(); + Task RotateAsync(long seconds); } public class EventLogRepository : IEventLogRepository @@ -350,6 +343,77 @@ private bool IsExistInternal() _loggerService.EndMethod(); } } + + public async Task RotateAsync(long seconds) + { + _loggerService.StartMethod(); + + await _semaphore.WaitAsync(); + + try + { + await RotateAsyncInternal(seconds); + } + finally + { + _semaphore.Release(); + + _loggerService.EndMethod(); + } + } + + private async Task RotateAsyncInternal(long seconds) + { + _loggerService.StartMethod(); + _loggerService.Info($"seconds: {seconds}"); + + try + { + if (!Directory.Exists(_basePath)) + { + return; + } + + long utcNowEpoch = DateTime.UtcNow.ToUnixEpoch(); + _loggerService.Info($"utcNowEpoch: {utcNowEpoch}"); + + string[] filesInDirectory = Directory.GetFiles(_basePath); + foreach (var file in filesInDirectory) + { + _loggerService.Info($"file: {file}"); + + long eventLogEpoch; + try + { + string content = await File.ReadAllTextAsync(file); + EventLog eventLog = JsonConvert.DeserializeObject(content); + eventLogEpoch = eventLog.Epoch; + } + catch (Exception ex) + { + _loggerService.Exception("Failed read of event log content.", ex); + File.Delete(file); + continue; + } + + _loggerService.Info($"eventLogEpoch: {eventLogEpoch}"); + + if (eventLogEpoch < utcNowEpoch - seconds) + { + _loggerService.Info("Delete"); + File.Delete(file); + } + else + { + _loggerService.Info("Keep"); + } + } + } + finally + { + _loggerService.EndMethod(); + } + } } public class EventContentExposureNotified diff --git a/Covid19Radar/Covid19Radar/Services/AbsDataMaintainanceBackgroundService.cs b/Covid19Radar/Covid19Radar/Services/AbsDataMaintainanceBackgroundService.cs new file mode 100644 index 000000000..0a034e26e --- /dev/null +++ b/Covid19Radar/Covid19Radar/Services/AbsDataMaintainanceBackgroundService.cs @@ -0,0 +1,44 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +using System.Threading.Tasks; +using Covid19Radar.Common; +using Covid19Radar.Repository; +using Covid19Radar.Services.Logs; + +namespace Covid19Radar.Services +{ + public abstract class AbsDataMaintainanceBackgroundService : IBackgroundService + { + protected ILoggerService LoggerService { get; private set; } + + private readonly IEventLogRepository _eventLogRepository; + + public AbsDataMaintainanceBackgroundService( + ILoggerService loggerService, + IEventLogRepository eventLogRepository) + { + LoggerService = loggerService; + _eventLogRepository = eventLogRepository; + } + + public abstract void Schedule(); + + public async Task ExecuteAsync() + { + LoggerService.StartMethod(); + + try + { + await _eventLogRepository.RotateAsync( + AppConstants.EventLogFileExpiredSeconds); + } + finally + { + LoggerService.EndMethod(); + } + } + } +} + diff --git a/Covid19Radar/Covid19Radar/ViewModels/Settings/DebugPageViewModel.cs b/Covid19Radar/Covid19Radar/ViewModels/Settings/DebugPageViewModel.cs index 1c0b85529..b955f90b3 100644 --- a/Covid19Radar/Covid19Radar/ViewModels/Settings/DebugPageViewModel.cs +++ b/Covid19Radar/Covid19Radar/ViewModels/Settings/DebugPageViewModel.cs @@ -329,6 +329,11 @@ private string ConvertSha256(string text) await _eventLogRepository.AddEventNotifiedAsync(); }); + public IAsyncCommand OnClickRotateEventLogs => new AsyncCommand(async () => + { + await _eventLogRepository.RotateAsync(AppConstants.EventLogFileExpiredSeconds); + }); + public Command OnClickQuit => new Command(() => { Application.Current.Quit(); diff --git a/Covid19Radar/Covid19Radar/Views/Settings/DebugPage.xaml b/Covid19Radar/Covid19Radar/Views/Settings/DebugPage.xaml index a85b7bfd5..fc10e7dc0 100644 --- a/Covid19Radar/Covid19Radar/Views/Settings/DebugPage.xaml +++ b/Covid19Radar/Covid19Radar/Views/Settings/DebugPage.xaml @@ -116,6 +116,10 @@ Command="{Binding Path=OnClickAddEventNotifiedForce}" Style="{StaticResource DefaultButton}" Text="AddEventNotified(Force)" /> +