From 24a6aecd735b5b694411d90bf80b100b73f8327f Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 1 Nov 2018 16:14:03 +0000 Subject: [PATCH] Adds in a new API endpoint to get the size of logs - which will determine to display a warning message if the filesize is too big to read (to help prevent the CPU & memory being eaten up & killing the site) --- src/Umbraco.Core/Logging/Viewer/ILogViewer.cs | 2 + .../Logging/Viewer/JsonLogViewer.cs | 41 ++++++++++++++++++- .../Logging/Viewer/LogViewerSourceBase.cs | 5 ++- .../Editors/LogViewerController.cs | 29 +++++++++++++ 4 files changed, 74 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/Logging/Viewer/ILogViewer.cs b/src/Umbraco.Core/Logging/Viewer/ILogViewer.cs index c3e17931a3..1f23353608 100644 --- a/src/Umbraco.Core/Logging/Viewer/ILogViewer.cs +++ b/src/Umbraco.Core/Logging/Viewer/ILogViewer.cs @@ -44,6 +44,8 @@ namespace Umbraco.Core.Logging.Viewer /// IEnumerable GetMessageTemplates(DateTimeOffset startDate, DateTimeOffset endDate); + long GetLogSize(DateTimeOffset startDate, DateTimeOffset endDate); + /// /// Returns the collection of logs /// diff --git a/src/Umbraco.Core/Logging/Viewer/JsonLogViewer.cs b/src/Umbraco.Core/Logging/Viewer/JsonLogViewer.cs index 22e02ea991..4e887352d4 100644 --- a/src/Umbraco.Core/Logging/Viewer/JsonLogViewer.cs +++ b/src/Umbraco.Core/Logging/Viewer/JsonLogViewer.cs @@ -67,6 +67,45 @@ namespace Umbraco.Core.Logging.Viewer } return logs; - } + } + + /// + /// This default JSON disk implementation here - returns the total filesize & NOT the count of entries + /// Other implementations we would expect to return the count of entries + /// We use this number to help prevent the logviewer killing the site with CPU/Memory if the number of items too big to handle + /// + public override long GetLogSize(DateTimeOffset startDate, DateTimeOffset endDate) + { + //Open the JSON log file for the range of dates (and exclude machinename) Could be several for LB + var dateRange = endDate - startDate; + + //Log Directory + var logDirectory = $@"{AppDomain.CurrentDomain.BaseDirectory}\App_Data\Logs\"; + + //Number of entries + long count = 0; + + //foreach full day in the range - see if we can find one or more filenames that end with + //yyyyMMdd.json - Ends with due to MachineName in filenames - could be 1 or more due to load balancing + for (var day = startDate.Date; day.Date <= endDate.Date; day = day.AddDays(1)) + { + //Filename ending to search for (As could be multiple) + var filesToFind = $"*{day.ToString("yyyyMMdd")}.json"; + + var filesForCurrentDay = Directory.GetFiles(logDirectory, filesToFind); + + //Foreach file we find - open it + foreach (var filePath in filesForCurrentDay) + { + //Get the current filesize in bytes ! + var byteFileSize = new FileInfo(filePath).Length; + + count += byteFileSize; + } + } + + //Count contains a combination of file sizes in bytes + return count; + } } } diff --git a/src/Umbraco.Core/Logging/Viewer/LogViewerSourceBase.cs b/src/Umbraco.Core/Logging/Viewer/LogViewerSourceBase.cs index 7f0531a570..eed5fcc9ab 100644 --- a/src/Umbraco.Core/Logging/Viewer/LogViewerSourceBase.cs +++ b/src/Umbraco.Core/Logging/Viewer/LogViewerSourceBase.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using Serilog.Events; -using Serilog.Filters.Expressions; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Persistence.DatabaseModelDefinitions; @@ -17,6 +16,8 @@ namespace Umbraco.Core.Logging.Viewer public abstract IEnumerable GetLogs(DateTimeOffset startDate, DateTimeOffset endDate, ILogFilter filter, int skip, int take); + public abstract long GetLogSize(DateTimeOffset startDate, DateTimeOffset endDate); + public virtual IEnumerable GetSavedSearches() { //Our default implementation @@ -137,6 +138,6 @@ namespace Umbraco.Core.Logging.Viewer { Items = logMessages }; - } + } } } diff --git a/src/Umbraco.Web/Editors/LogViewerController.cs b/src/Umbraco.Web/Editors/LogViewerController.cs index 61ba3d0a9b..e7e20cda05 100644 --- a/src/Umbraco.Web/Editors/LogViewerController.cs +++ b/src/Umbraco.Web/Editors/LogViewerController.cs @@ -21,6 +21,35 @@ namespace Umbraco.Web.Editors _logViewer = logViewer; } + [HttpGet] + public IHttpActionResult GetLogSize() + { + //Returns 200 OK if the logs can be viewed + + //Check if the ILogViewer is our JSON file + var isJsonLogViewer = _logViewer is JsonLogViewer; + + //Don't WARN or check if it's not our JSON disk file approach + if (isJsonLogViewer == false) + { + return Ok(); + } + + //Go & fetch the number of log entries OR + var logSize = _logViewer.GetLogSize(startDate: DateTime.Now.AddDays(-1), endDate: DateTime.Now); + + //If the number of items is less than + if (logSize >= 10) + { + return Ok(logSize); + } + + //TODO: It may need to be an Umbraco request with errow/warning notification?! + //Depends how best to bubble up to UI - with some custom JS promise error that is caught + return BadRequest(); + + } + [HttpGet] public int GetNumberOfErrors() {