add searching log category (#2251)

This commit is contained in:
Jason Dove
2025-08-04 14:51:13 +00:00
committed by GitHub
parent 3b955255ce
commit ab2b926de0
9 changed files with 37 additions and 8 deletions
+1
View File
@@ -59,6 +59,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed ### Changed
- Always tell ffmpeg to stop encoding with a specific duration - Always tell ffmpeg to stop encoding with a specific duration
- This was removed to try to improve transitions with ffmpeg 7.x, but has been causing issues with other content - This was removed to try to improve transitions with ffmpeg 7.x, but has been causing issues with other content
- Move search debug logging to its own log category; add `Searching Minimum Log Level` to `Settings` > `Logging`
## [25.3.1] - 2025-07-24 ## [25.3.1] - 2025-07-24
### Fixed ### Fixed
@@ -36,6 +36,11 @@ public class UpdateLoggingSettingsHandler : IRequestHandler<UpdateLoggingSetting
loggingSettings.SchedulingMinimumLogLevel); loggingSettings.SchedulingMinimumLogLevel);
_loggingLevelSwitches.SchedulingLevelSwitch.MinimumLevel = loggingSettings.SchedulingMinimumLogLevel; _loggingLevelSwitches.SchedulingLevelSwitch.MinimumLevel = loggingSettings.SchedulingMinimumLogLevel;
await _configElementRepository.Upsert(
ConfigElementKey.MinimumLogLevelSearching,
loggingSettings.SearchingMinimumLogLevel);
_loggingLevelSwitches.SearchingLevelSwitch.MinimumLevel = loggingSettings.SearchingMinimumLogLevel;
await _configElementRepository.Upsert( await _configElementRepository.Upsert(
ConfigElementKey.MinimumLogLevelStreaming, ConfigElementKey.MinimumLogLevelStreaming,
loggingSettings.StreamingMinimumLogLevel); loggingSettings.StreamingMinimumLogLevel);
@@ -7,6 +7,7 @@ public class LoggingSettingsViewModel
public LogEventLevel DefaultMinimumLogLevel { get; set; } public LogEventLevel DefaultMinimumLogLevel { get; set; }
public LogEventLevel ScanningMinimumLogLevel { get; set; } public LogEventLevel ScanningMinimumLogLevel { get; set; }
public LogEventLevel SchedulingMinimumLogLevel { get; set; } public LogEventLevel SchedulingMinimumLogLevel { get; set; }
public LogEventLevel SearchingMinimumLogLevel { get; set; }
public LogEventLevel StreamingMinimumLogLevel { get; set; } public LogEventLevel StreamingMinimumLogLevel { get; set; }
public LogEventLevel HttpMinimumLogLevel { get; set; } public LogEventLevel HttpMinimumLogLevel { get; set; }
} }
@@ -22,6 +22,9 @@ public class GetLoggingSettingsHandler : IRequestHandler<GetLoggingSettings, Log
Option<LogEventLevel> maybeSchedulingLevel = Option<LogEventLevel> maybeSchedulingLevel =
await _configElementRepository.GetValue<LogEventLevel>(ConfigElementKey.MinimumLogLevelScheduling); await _configElementRepository.GetValue<LogEventLevel>(ConfigElementKey.MinimumLogLevelScheduling);
Option<LogEventLevel> maybeSearchingLevel =
await _configElementRepository.GetValue<LogEventLevel>(ConfigElementKey.MinimumLogLevelSearching);
Option<LogEventLevel> maybeStreamingLevel = Option<LogEventLevel> maybeStreamingLevel =
await _configElementRepository.GetValue<LogEventLevel>(ConfigElementKey.MinimumLogLevelStreaming); await _configElementRepository.GetValue<LogEventLevel>(ConfigElementKey.MinimumLogLevelStreaming);
@@ -33,6 +36,7 @@ public class GetLoggingSettingsHandler : IRequestHandler<GetLoggingSettings, Log
DefaultMinimumLogLevel = await maybeDefaultLevel.IfNoneAsync(LogEventLevel.Information), DefaultMinimumLogLevel = await maybeDefaultLevel.IfNoneAsync(LogEventLevel.Information),
ScanningMinimumLogLevel = await maybeScanningLevel.IfNoneAsync(LogEventLevel.Information), ScanningMinimumLogLevel = await maybeScanningLevel.IfNoneAsync(LogEventLevel.Information),
SchedulingMinimumLogLevel = await maybeSchedulingLevel.IfNoneAsync(LogEventLevel.Information), SchedulingMinimumLogLevel = await maybeSchedulingLevel.IfNoneAsync(LogEventLevel.Information),
SearchingMinimumLogLevel = await maybeSearchingLevel.IfNoneAsync(LogEventLevel.Information),
StreamingMinimumLogLevel = await maybeStreamingLevel.IfNoneAsync(LogEventLevel.Information), StreamingMinimumLogLevel = await maybeStreamingLevel.IfNoneAsync(LogEventLevel.Information),
HttpMinimumLogLevel = await maybeHttpLevel.IfNoneAsync(LogEventLevel.Information) HttpMinimumLogLevel = await maybeHttpLevel.IfNoneAsync(LogEventLevel.Information)
}; };
+1
View File
@@ -9,6 +9,7 @@ public class ConfigElementKey
public static ConfigElementKey MinimumLogLevel => new("log.minimum_level"); public static ConfigElementKey MinimumLogLevel => new("log.minimum_level");
public static ConfigElementKey MinimumLogLevelScanning => new("log.minimum_level.scanning"); public static ConfigElementKey MinimumLogLevelScanning => new("log.minimum_level.scanning");
public static ConfigElementKey MinimumLogLevelScheduling => new("log.minimum_level.scheduling"); public static ConfigElementKey MinimumLogLevelScheduling => new("log.minimum_level.scheduling");
public static ConfigElementKey MinimumLogLevelSearching => new("log.minimum_level.searching");
public static ConfigElementKey MinimumLogLevelStreaming => new("log.minimum_level.streaming"); public static ConfigElementKey MinimumLogLevelStreaming => new("log.minimum_level.streaming");
public static ConfigElementKey MinimumLogLevelHttp => new("log.minimum_level.http"); public static ConfigElementKey MinimumLogLevelHttp => new("log.minimum_level.http");
public static ConfigElementKey FFmpegPath => new("ffmpeg.ffmpeg_path"); public static ConfigElementKey FFmpegPath => new("ffmpeg.ffmpeg_path");
+2
View File
@@ -10,6 +10,8 @@ public class LoggingLevelSwitches
public LoggingLevelSwitch SchedulingLevelSwitch { get; } = new(); public LoggingLevelSwitch SchedulingLevelSwitch { get; } = new();
public LoggingLevelSwitch SearchingLevelSwitch { get; } = new();
public LoggingLevelSwitch StreamingLevelSwitch { get; } = new(); public LoggingLevelSwitch StreamingLevelSwitch { get; } = new();
public LoggingLevelSwitch HttpLevelSwitch { get; } = new(); public LoggingLevelSwitch HttpLevelSwitch { get; } = new();
@@ -6,12 +6,12 @@ using Lucene.Net.Analysis.Miscellaneous;
using Lucene.Net.Analysis.Standard; using Lucene.Net.Analysis.Standard;
using Lucene.Net.QueryParsers.Classic; using Lucene.Net.QueryParsers.Classic;
using Lucene.Net.Search; using Lucene.Net.Search;
using Serilog; using Microsoft.Extensions.Logging;
using Query = Lucene.Net.Search.Query; using Query = Lucene.Net.Search.Query;
namespace ErsatzTV.Infrastructure.Search; namespace ErsatzTV.Infrastructure.Search;
public partial class SearchQueryParser(ISmartCollectionCache smartCollectionCache) public partial class SearchQueryParser(ISmartCollectionCache smartCollectionCache, ILogger<SearchQueryParser> logger)
{ {
static SearchQueryParser() => BooleanQuery.MaxClauseCount = 1024 * 4; static SearchQueryParser() => BooleanQuery.MaxClauseCount = 1024 * 4;
@@ -54,7 +54,7 @@ public partial class SearchQueryParser(ISmartCollectionCache smartCollectionCach
if (!string.IsNullOrWhiteSpace(smartCollectionName) && await smartCollectionCache.HasCycle(smartCollectionName)) if (!string.IsNullOrWhiteSpace(smartCollectionName) && await smartCollectionCache.HasCycle(smartCollectionName))
{ {
Log.Logger.Error("Smart collection {Name} contains a cycle; will not evaluate", smartCollectionName); logger.LogError("Smart collection {Name} contains a cycle; will not evaluate", smartCollectionName);
} }
else else
{ {
@@ -63,7 +63,7 @@ public partial class SearchQueryParser(ISmartCollectionCache smartCollectionCach
{ {
if (replaceCount > 100) if (replaceCount > 100)
{ {
Log.Logger.Warning("smart_collection query is nested too deep; giving up"); logger.LogWarning("smart_collection query is nested too deep; giving up");
break; break;
} }
@@ -75,7 +75,7 @@ public partial class SearchQueryParser(ISmartCollectionCache smartCollectionCach
if (parsedQuery == replaceResult.Query) if (parsedQuery == replaceResult.Query)
{ {
Log.Logger.Warning( logger.LogWarning(
"Failed to replace smart_collection in query; is the syntax correct? Quotes are required. Giving up..."); "Failed to replace smart_collection in query; is the syntax correct? Quotes are required. Giving up...");
break; break;
} }
@@ -97,7 +97,7 @@ public partial class SearchQueryParser(ISmartCollectionCache smartCollectionCach
}; };
Query result = ParseQuery(parsedQuery, parser); Query result = ParseQuery(parsedQuery, parser);
Log.Logger.Debug("Search query parsed from [{Query}] to [{ParsedQuery}]", query, result.ToString()); logger.LogDebug("Search query parsed from [{Query}] to [{ParsedQuery}]", query, result.ToString());
return result; return result;
} }
@@ -113,7 +113,7 @@ public partial class SearchQueryParser(ISmartCollectionCache smartCollectionCach
string smartCollectionName = match.Groups[1].Value; string smartCollectionName = match.Groups[1].Value;
if (await smartCollectionCache.HasCycle(smartCollectionName)) if (await smartCollectionCache.HasCycle(smartCollectionName))
{ {
Log.Logger.Error( logger.LogError(
"Smart collection {Name} contains a cycle; will not evaluate", "Smart collection {Name} contains a cycle; will not evaluate",
smartCollectionName); smartCollectionName);
return new ReplaceResult(query, true); return new ReplaceResult(query, true);
@@ -130,7 +130,7 @@ public partial class SearchQueryParser(ISmartCollectionCache smartCollectionCach
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Logger.Warning(ex, "Unexpected exception replacing smart collections in search query"); logger.LogWarning(ex, "Unexpected exception replacing smart collections in search query");
return new ReplaceResult(query, true); return new ReplaceResult(query, true);
} }
} }
@@ -47,6 +47,17 @@
<MudSelectItem Value="@LogEventLevel.Error">Error</MudSelectItem> <MudSelectItem Value="@LogEventLevel.Error">Error</MudSelectItem>
</MudSelect> </MudSelect>
</MudStack> </MudStack>
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5">
<div class="d-flex">
<MudText>Searching Minimum Log Level</MudText>
</div>
<MudSelect @bind-Value="_loggingSettings.SearchingMinimumLogLevel">
<MudSelectItem Value="@LogEventLevel.Debug">Debug</MudSelectItem>
<MudSelectItem Value="@LogEventLevel.Information">Information</MudSelectItem>
<MudSelectItem Value="@LogEventLevel.Warning">Warning</MudSelectItem>
<MudSelectItem Value="@LogEventLevel.Error">Error</MudSelectItem>
</MudSelect>
</MudStack>
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5"> <MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5">
<div class="d-flex"> <div class="d-flex">
<MudText>Streaming Minimum Log Level</MudText> <MudText>Streaming Minimum Log Level</MudText>
+4
View File
@@ -74,6 +74,9 @@ public class Program
"ErsatzTV.Application.Subtitles.ExtractEmbeddedSubtitlesHandler", "ErsatzTV.Application.Subtitles.ExtractEmbeddedSubtitlesHandler",
LoggingLevelSwitches.SchedulingLevelSwitch) LoggingLevelSwitches.SchedulingLevelSwitch)
// searching
.MinimumLevel.Override("ErsatzTV.Infrastructure.Search.SearchQueryParser", LoggingLevelSwitches.SearchingLevelSwitch)
// streaming // streaming
.MinimumLevel.Override("ErsatzTV.Application.Streaming", LoggingLevelSwitches.StreamingLevelSwitch) .MinimumLevel.Override("ErsatzTV.Application.Streaming", LoggingLevelSwitches.StreamingLevelSwitch)
.MinimumLevel.Override("ErsatzTV.FFmpeg", LoggingLevelSwitches.StreamingLevelSwitch) .MinimumLevel.Override("ErsatzTV.FFmpeg", LoggingLevelSwitches.StreamingLevelSwitch)
@@ -85,6 +88,7 @@ public class Program
LoggingLevelSwitches.StreamingLevelSwitch) LoggingLevelSwitches.StreamingLevelSwitch)
.MinimumLevel.Override("ErsatzTV.Controllers.IptvController", LoggingLevelSwitches.StreamingLevelSwitch) .MinimumLevel.Override("ErsatzTV.Controllers.IptvController", LoggingLevelSwitches.StreamingLevelSwitch)
.MinimumLevel.Override("ErsatzTV.Controllers.InternalController", LoggingLevelSwitches.StreamingLevelSwitch) .MinimumLevel.Override("ErsatzTV.Controllers.InternalController", LoggingLevelSwitches.StreamingLevelSwitch)
.MinimumLevel.Override("ErsatzTV.Controllers.TroubleshootController", LoggingLevelSwitches.StreamingLevelSwitch)
// http // http
.MinimumLevel.Override("Serilog.AspNetCore.RequestLoggingMiddleware", LoggingLevelSwitches.HttpLevelSwitch) .MinimumLevel.Override("Serilog.AspNetCore.RequestLoggingMiddleware", LoggingLevelSwitches.HttpLevelSwitch)