From 0043dc27d30d65c1b1f09711b7c6eb7f78ceb69c Mon Sep 17 00:00:00 2001 From: Stan___Kudri <53861218+Stan-Kudri@users.noreply.github.com> Date: Thu, 12 Oct 2023 21:49:25 +0300 Subject: [PATCH] Solution - Add and used Logger. --- WatchList.Core/Logger/ConsoleLogger.cs | 35 ++++++++++++++ WatchList.Core/Logger/FileLogger.cs | 48 +++++++++++++++++++ .../Repository/WatchItemRepository.cs | 13 ++++- .../DataLoading/DownloadDataService.cs | 7 ++- WatchList.Core/WatchList.Core.csproj | 1 + WatchList.WinForms/BoxCinemaForm.Designer.cs | 1 + WatchList.WinForms/BoxCinemaForm.cs | 15 +++++- WatchList.WinForms/Program.cs | 29 ++++++++++- WatchList.WinForms/WatchList.WinForms.csproj | 1 + 9 files changed, 143 insertions(+), 7 deletions(-) create mode 100644 WatchList.Core/Logger/ConsoleLogger.cs create mode 100644 WatchList.Core/Logger/FileLogger.cs diff --git a/WatchList.Core/Logger/ConsoleLogger.cs b/WatchList.Core/Logger/ConsoleLogger.cs new file mode 100644 index 00000000..0dac9af5 --- /dev/null +++ b/WatchList.Core/Logger/ConsoleLogger.cs @@ -0,0 +1,35 @@ +using Microsoft.Extensions.Logging; + +namespace WatchList.Core.Logger +{ + public sealed class ConsoleLogger : ILogger + { + private LogLevel _logLevel; + + public ConsoleLogger(LogLevel logLevel) => _logLevel = logLevel; + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) + { + if (!IsEnabled(logLevel)) + { + return; + } + + var message = formatter(state, exception); + Console.WriteLine("[{0} {1:G}] {2}", logLevel, DateTime.Now, message); + } + + public bool IsEnabled(LogLevel logLevel) => _logLevel <= logLevel; + + public IDisposable? BeginScope(TState state) + where TState : notnull + => new Disposable(); + + private sealed class Disposable : IDisposable + { + public void Dispose() + { + } + } + } +} diff --git a/WatchList.Core/Logger/FileLogger.cs b/WatchList.Core/Logger/FileLogger.cs new file mode 100644 index 00000000..a2ebf702 --- /dev/null +++ b/WatchList.Core/Logger/FileLogger.cs @@ -0,0 +1,48 @@ +using System.Globalization; +using Microsoft.Extensions.Logging; + +namespace WatchList.Core.Logger +{ + public class FileLogger : ILogger + { + private LogLevel _logLevel; + private readonly string _pathFileLog; + + public FileLogger(LogLevel logLevel, string pathFileLog) + { + _logLevel = logLevel; + _pathFileLog = pathFileLog; + } + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) + { + if (!IsEnabled(logLevel)) + { + return; + } + + var message = formatter(state, exception); + var logText = string.Format("[{0} {1:G}] {2}", logLevel, DateTime.Now, message); + File.AppendAllText(BuildPath(), logText + Environment.NewLine); + } + + public bool IsEnabled(LogLevel logLevel) => _logLevel <= logLevel; + + public IDisposable? BeginScope(TState state) + where TState : notnull + => new Disposable(); + + private sealed class Disposable : IDisposable + { + public void Dispose() + { + } + } + + private string BuildPath() + { + var dateStr = DateTime.Now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture); + return Path.Combine(_pathFileLog, dateStr + ".txt"); + } + } +} diff --git a/WatchList.Core/Repository/WatchItemRepository.cs b/WatchList.Core/Repository/WatchItemRepository.cs index edb59e8e..5987dc01 100644 --- a/WatchList.Core/Repository/WatchItemRepository.cs +++ b/WatchList.Core/Repository/WatchItemRepository.cs @@ -1,4 +1,5 @@ using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; using WatchList.Core.Model.ItemCinema; using WatchList.Core.PageItem; using WatchList.Core.Repository.Db; @@ -9,8 +10,13 @@ namespace WatchList.Core.Repository public class WatchItemRepository : IWatchItemRepository { private readonly WatchCinemaDbContext _db; + private readonly ILogger _logger; - public WatchItemRepository(WatchCinemaDbContext db) => _db = db; + public WatchItemRepository(WatchCinemaDbContext db, ILogger logger) + { + _db = db; + _logger = logger; + } public PagedList GetPage(WatchItemSearchRequest searchRequest) { @@ -24,6 +30,7 @@ public void Add(WatchItem item) item.Id = _db.ReplaceIdIsNotFree(item); _db.Add(item); _db.SaveChanges(); + _logger.LogInformation("Add item with ID {0}", item.Id); } public void Remove(Guid id) @@ -33,6 +40,8 @@ public void Remove(Guid id) { throw new InvalidOperationException("Interaction element not found."); } + + _logger.LogInformation("Remove item with ID {0}", id); } public void Update(WatchItem editItem) @@ -52,6 +61,8 @@ public void Update(WatchItem editItem) item.Status = editItem.Status; _db.SaveChanges(); + + _logger.LogInformation("Edit item with ID {0}", item.Id); } public List SelectDuplicateItems(WatchItem item) => diff --git a/WatchList.Core/Service/DataLoading/DownloadDataService.cs b/WatchList.Core/Service/DataLoading/DownloadDataService.cs index efff5da2..ddac11a3 100644 --- a/WatchList.Core/Service/DataLoading/DownloadDataService.cs +++ b/WatchList.Core/Service/DataLoading/DownloadDataService.cs @@ -1,3 +1,4 @@ +using Microsoft.Extensions.Logging; using WatchList.Core.Model.Filter; using WatchList.Core.Model.QuestionResult; using WatchList.Core.Model.Sorting; @@ -11,13 +12,14 @@ namespace WatchList.Core.Service.DataLoading public class DownloadDataService { private readonly WatchItemRepository _repository; - private readonly IMessageBox _messageBox; + private readonly ILogger _logger; - public DownloadDataService(WatchItemRepository repository, IMessageBox messageBox, int numberOfItemPerPage = 500) + public DownloadDataService(WatchItemRepository repository, IMessageBox messageBox, ILogger logger, int numberOfItemPerPage = 500) { _repository = repository; _messageBox = messageBox; + _logger = logger; NumberOfItemPerPage = numberOfItemPerPage; } @@ -33,6 +35,7 @@ public void Download(WatchItemRepository repository, ILoadRule loadRule) var watchItemCollection = new WatchItemCollection(pagedList); watchItemCollection = loadRule.Apply(watchItemCollection); + _logger.LogInformation("Load items according to selected rules"); AddItems(watchItemCollection); UpdateItems(watchItemCollection); diff --git a/WatchList.Core/WatchList.Core.csproj b/WatchList.Core/WatchList.Core.csproj index 4274e1ba..ccd7629b 100644 --- a/WatchList.Core/WatchList.Core.csproj +++ b/WatchList.Core/WatchList.Core.csproj @@ -11,6 +11,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/WatchList.WinForms/BoxCinemaForm.Designer.cs b/WatchList.WinForms/BoxCinemaForm.Designer.cs index 81f4e334..3301656b 100644 --- a/WatchList.WinForms/BoxCinemaForm.Designer.cs +++ b/WatchList.WinForms/BoxCinemaForm.Designer.cs @@ -610,6 +610,7 @@ private void InitializeComponent() Name = "BoxCinemaForm"; StartPosition = FormStartPosition.CenterScreen; Text = "BoxCinema"; + FormClosed += BoxCinemaForm_FormClosed; ((System.ComponentModel.ISupportInitialize)cinemaBindingSource).EndInit(); ((System.ComponentModel.ISupportInitialize)dgvCinema).EndInit(); ((System.ComponentModel.ISupportInitialize)filterModelBindingSource).EndInit(); diff --git a/WatchList.WinForms/BoxCinemaForm.cs b/WatchList.WinForms/BoxCinemaForm.cs index d81dae61..f462f08d 100644 --- a/WatchList.WinForms/BoxCinemaForm.cs +++ b/WatchList.WinForms/BoxCinemaForm.cs @@ -1,5 +1,6 @@ using MaterialSkin.Controls; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using WatchList.Core.Model.Filter.Components; using WatchList.Core.Model.ItemCinema; using WatchList.Core.Model.ItemCinema.Components; @@ -36,6 +37,7 @@ public partial class BoxCinemaForm : MaterialForm private readonly WatchItemService _itemService; private readonly IMessageBox _messageBox; private readonly WatchItemRepository _itemRepository; + private readonly ILogger _logger; private WatchItemSearchRequest _searchRequest = new WatchItemSearchRequest(); @@ -48,8 +50,8 @@ public BoxCinemaForm(IServiceProvider serviceProvider) _itemRepository = serviceProvider.GetRequiredService(); _messageBox = serviceProvider.GetRequiredService(); _itemService = serviceProvider.GetRequiredService(); + _logger = serviceProvider.GetRequiredService(); _pagedList = _itemService.GetPage(_searchRequest); - Load += BoxCinemaForm_Load; } @@ -95,6 +97,7 @@ private void BtnAddCinema_Click(object sender, EventArgs e) return; } + _logger.LogInformation("Click save add item"); var itemCinema = addForm.GetCinema(); _itemService.Add(itemCinema.ToWatchItem()); @@ -114,6 +117,7 @@ private void BtnEditRow_Click(object sender, EventArgs e) return; } + _logger.LogInformation("Click save edit item"); var updateItem = updateForm.GetEditItemCinema(); _itemService.Update(oldItem.ToWatchItem(), updateItem.ToWatchItem()); UpdateGridData(); @@ -141,6 +145,7 @@ private void BtnDeleteMovie_Click(object sender, EventArgs e) return; } + _logger.LogInformation("Click delite item"); foreach (var id in selectedRowIds) { RemoveItemRowGrid(id); @@ -164,6 +169,7 @@ private void BtnDownloadDataFile_Click(object sender, EventArgs e) return; } + _logger.LogInformation("Add item from the selected file <{0}>", openReplaceDataFromFile.FileName); var dbContext = new FileDbContextFactory(openReplaceDataFromFile.FileName).Create(); var loadRuleConfig = dataLoadingForm.GetLoadRuleConfig(); var loadRuleHasGrade = new DeleteGradeRule(loadRuleConfig); @@ -172,13 +178,18 @@ private void BtnDownloadDataFile_Click(object sender, EventArgs e) var loadDuplicateItem = new DuplicateLoadRule(_itemRepository, loadRuleConfig); var aggregateRules = new AggregateLoadRule { loadRuleHasGrade, loadRuleType, loadRuleMoreGrade, loadDuplicateItem }; - var repositoryDataDownload = new WatchItemRepository(dbContext); + var repositoryDataDownload = new WatchItemRepository(dbContext, _logger); var downloadDataService = _serviceProvider.GetRequiredService(); downloadDataService.Download(repositoryDataDownload, aggregateRules); UpdateGridData(); } + private void BoxCinemaForm_FormClosed(object sender, FormClosedEventArgs e) + { + _logger.LogInformation("Close App."); + } + private void BtnBackPage_Click(object sender, EventArgs e) { if (_pagedList.HasPreviousPage) diff --git a/WatchList.WinForms/Program.cs b/WatchList.WinForms/Program.cs index b56d4022..9008c14c 100644 --- a/WatchList.WinForms/Program.cs +++ b/WatchList.WinForms/Program.cs @@ -1,5 +1,7 @@ using MaterialSkin; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using WatchList.Core.Logger; using WatchList.Core.Repository; using WatchList.Core.Service; using WatchList.Core.Service.Component; @@ -23,6 +25,9 @@ public static void Main() // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); + var path = "logs"; + CreatDirectoryIfNotExists(path); + var serviceCollection = new ServiceCollection() .AddSingleton(new FileDbContextFactory("app.db")) .AddScoped(e => e.GetRequiredService().Create()) @@ -32,7 +37,9 @@ public static void Main() .AddScoped() .AddScoped() .AddTransient() - .AddTransient(); + .AddTransient() + //.AddTransient(e => new ConsoleLogger(LogLevel.Information)) + .AddTransient(e => new FileLogger(LogLevel.Trace, path)); using var contain = serviceCollection.BuildServiceProvider(new ServiceProviderOptions { @@ -50,7 +57,25 @@ public static void Main() materialSkinManager.Theme = MaterialSkinManager.Themes.LIGHT; materialSkinManager.ColorScheme = new ColorScheme(Primary.Purple900, Primary.DeepPurple700, Primary.Purple50, Accent.LightBlue200, TextShade.WHITE); - Application.Run(form); + var loger = scope.ServiceProvider.GetRequiredService(); + + try + { + loger.LogTrace("Launch the application"); + Application.Run(form); + } + catch (Exception ex) + { + loger.LogError(ex, "Unhandled exception"); + } + } + + static void CreatDirectoryIfNotExists(string path) + { + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } } } } diff --git a/WatchList.WinForms/WatchList.WinForms.csproj b/WatchList.WinForms/WatchList.WinForms.csproj index d0e8ad5a..35994f9f 100644 --- a/WatchList.WinForms/WatchList.WinForms.csproj +++ b/WatchList.WinForms/WatchList.WinForms.csproj @@ -15,6 +15,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive