Files
Umbraco-CMS/src/Umbraco.Infrastructure/Logging/Viewer/SerilogJsonLogViewer.cs
Mole 9cb1d66b10 V14: Remove Newtonsoft from packed projects (#15811)
* Migrate ObjectJsonExtensions

* Use more generic exception to not use Newtonsoft

It should matter if it's a JsonReaderException, if we can't read we can't read

* Remove obsoleted constructors

* Use more generic exception in ContentValueSetBuilder

* Fix constructors

* Remove UdiRangeJsonConverter

* Remove more legacy newtonsoft stuff

* Migrate away from newtonsoft in CacheInstructionService

* Remove unused model binders

* Remove more newtonsoft

* Remove newtonsoft from DatabaseServerMessenger

* Remove now irrelevant benchmark

* Remove the usage of Newtonsoft from ImageCropperTemplateCoreExtensions

The value converter will never return JObject, JsonDocument, or JsonNode

* Remove usages of newtonsoft in ComplexPropertyEditorContentNotificationHandler

JTokens are no longer returned, so we don't need to check for it

* Remove newtonsoft references

* Re-add newtonsoft dependency to Umbraco.Tests.Common

* Fix package references

* move dependency

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2024-03-01 12:51:21 +01:00

134 lines
4.8 KiB
C#

using Microsoft.Extensions.Logging;
using Serilog.Events;
using Serilog.Formatting.Compact.Reader;
using ILogger = Serilog.ILogger;
namespace Umbraco.Cms.Core.Logging.Viewer;
internal class SerilogJsonLogViewer : SerilogLogViewerSourceBase
{
private const int FileSizeCap = 100;
private readonly ILogger<SerilogJsonLogViewer> _logger;
private readonly string _logsPath;
public SerilogJsonLogViewer(
ILogger<SerilogJsonLogViewer> logger,
ILogViewerConfig logViewerConfig,
ILoggingConfiguration loggingConfiguration,
ILogLevelLoader logLevelLoader,
ILogger serilogLog)
: base(logViewerConfig, logLevelLoader, serilogLog)
{
_logger = logger;
_logsPath = loggingConfiguration.LogDirectory;
}
public override bool CanHandleLargeLogs => false;
[Obsolete("Use ILogViewerService.CanViewLogsAsync instead. Scheduled for removal in Umbraco 15.")]
public override bool CheckCanOpenLogs(LogTimePeriod logTimePeriod)
{
// Log Directory
var logDirectory = _logsPath;
// Number of entries
long fileSizeCount = 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 (DateTime day = logTimePeriod.StartTime.Date; day.Date <= logTimePeriod.EndTime.Date; day = day.AddDays(1))
{
// Filename ending to search for (As could be multiple)
var filesToFind = GetSearchPattern(day);
var filesForCurrentDay = Directory.GetFiles(logDirectory, filesToFind);
fileSizeCount += filesForCurrentDay.Sum(x => new FileInfo(x).Length);
}
// The GetLogSize call on JsonLogViewer returns the total file size in bytes
// Check if the log size is not greater than 100Mb (FileSizeCap)
var logSizeAsMegabytes = fileSizeCount / 1024 / 1024;
return logSizeAsMegabytes <= FileSizeCap;
}
protected override IReadOnlyList<LogEvent> GetLogs(LogTimePeriod logTimePeriod, ILogFilter filter, int skip,
int take)
{
var logs = new List<LogEvent>();
var 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 (DateTime day = logTimePeriod.StartTime.Date; day.Date <= logTimePeriod.EndTime.Date; day = day.AddDays(1))
{
// Filename ending to search for (As could be multiple)
var filesToFind = GetSearchPattern(day);
var filesForCurrentDay = Directory.GetFiles(_logsPath, filesToFind);
// Foreach file we find - open it
foreach (var filePath in filesForCurrentDay)
{
// Open log file & add contents to the log collection
// Which we then use LINQ to page over
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var stream = new StreamReader(fs))
{
var reader = new LogEventReader(stream);
while (TryRead(reader, out LogEvent? evt))
{
// We may get a null if log line is malformed
if (evt == null)
{
continue;
}
if (count > skip + take)
{
break;
}
if (count < skip)
{
count++;
continue;
}
if (filter.TakeLogEvent(evt))
{
logs.Add(evt);
}
count++;
}
}
}
}
}
return logs;
}
private string GetSearchPattern(DateTime day) => $"*{day:yyyyMMdd}*.json";
private bool TryRead(LogEventReader reader, out LogEvent? evt)
{
try
{
return reader.TryRead(out evt);
}
catch (Exception ex)
{
// As we are reading/streaming one line at a time in the JSON file
// Thus we can not report the line number, as it will always be 1
_logger.LogError(ex, "Unable to parse a line in the JSON log file");
evt = null;
return true;
}
}
}