Merge remote-tracking branch 'upstream/master' into client-logger

This commit is contained in:
Cody Robibero
2021-10-26 17:43:36 -06:00
1165 changed files with 24439 additions and 15715 deletions

View File

@@ -5,18 +5,20 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CommandLine;
using Emby.Server.Implementations;
using Emby.Server.Implementations.IO;
using Jellyfin.Server.Implementations;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.ClientEvent;
using MediaBrowser.Controller.Extensions;
using MediaBrowser.Model.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -121,11 +123,11 @@ namespace Jellyfin.Server
// Log uncaught exceptions to the logging instead of std error
AppDomain.CurrentDomain.UnhandledException -= UnhandledExceptionToConsole;
AppDomain.CurrentDomain.UnhandledException += (sender, e)
AppDomain.CurrentDomain.UnhandledException += (_, e)
=> _logger.LogCritical((Exception)e.ExceptionObject, "Unhandled Exception");
// Intercept Ctrl+C and Ctrl+Break
Console.CancelKeyPress += (sender, e) =>
Console.CancelKeyPress += (_, e) =>
{
if (_tokenSource.IsCancellationRequested)
{
@@ -139,7 +141,7 @@ namespace Jellyfin.Server
};
// Register a SIGTERM handler
AppDomain.CurrentDomain.ProcessExit += (sender, e) =>
AppDomain.CurrentDomain.ProcessExit += (_, _) =>
{
if (_tokenSource.IsCancellationRequested)
{
@@ -180,7 +182,7 @@ namespace Jellyfin.Server
"The server is expected to host the web client, but the provided content directory is either " +
$"invalid or empty: {webContentPath}. If you do not want to host the web client with the " +
"server, you may set the '--nowebclient' command line flag, or set" +
$"'{MediaBrowser.Controller.Extensions.ConfigurationExtensions.HostWebClientKey}=false' in your config settings.");
$"'{ConfigurationExtensions.HostWebClientKey}=false' in your config settings.");
}
}
@@ -195,9 +197,9 @@ namespace Jellyfin.Server
try
{
await webHost.StartAsync().ConfigureAwait(false);
await webHost.StartAsync(_tokenSource.Token).ConfigureAwait(false);
}
catch
catch (Exception ex) when (ex is not TaskCanceledException)
{
_logger.LogError("Kestrel failed to start! This is most likely due to an invalid address or port bind - correct your bind configuration in network.xml and try again.");
throw;
@@ -222,6 +224,14 @@ namespace Jellyfin.Server
}
finally
{
_logger.LogInformation("Running query planner optimizations in the database... This might take a while");
// Run before disposing the application
using var context = appHost.Resolve<JellyfinDbProvider>().CreateContext();
if (context.Database.IsSqlite())
{
context.Database.ExecuteSqlRaw("PRAGMA optimize");
}
appHost.Dispose();
}
@@ -310,8 +320,8 @@ namespace Jellyfin.Server
}
}
// Bind to unix socket (only on macOS and Linux)
if (startupConfig.UseUnixSocket() && !RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
// Bind to unix socket (only on unix systems)
if (startupConfig.UseUnixSocket() && Environment.OSVersion.Platform == PlatformID.Unix)
{
var socketPath = startupConfig.GetUnixSocketPath();
if (string.IsNullOrEmpty(socketPath))
@@ -396,7 +406,7 @@ namespace Jellyfin.Server
{
if (options.DataDir != null
|| Directory.Exists(Path.Combine(dataDir, "config"))
|| RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|| OperatingSystem.IsWindows())
{
// Hang config folder off already set dataDir
configDir = Path.Combine(dataDir, "config");
@@ -434,7 +444,7 @@ namespace Jellyfin.Server
if (string.IsNullOrEmpty(cacheDir))
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
if (OperatingSystem.IsWindows())
{
// Hang cache folder off already set dataDir
cacheDir = Path.Combine(dataDir, "cache");
@@ -535,11 +545,11 @@ namespace Jellyfin.Server
// Get a stream of the resource contents
// NOTE: The .csproj name is used instead of the assembly name in the resource path
const string ResourcePath = "Jellyfin.Server.Resources.Configuration.logging.json";
await using Stream? resource = typeof(Program).Assembly.GetManifestResourceStream(ResourcePath)
await using Stream resource = typeof(Program).Assembly.GetManifestResourceStream(ResourcePath)
?? throw new InvalidOperationException($"Invalid resource path: '{ResourcePath}'");
// Copy the resource contents to the expected file path for the config file
await using Stream dst = File.Open(configPath, FileMode.CreateNew);
await using Stream dst = new FileStream(configPath, FileMode.CreateNew, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
await resource.CopyToAsync(dst).ConfigureAwait(false);
}
@@ -586,15 +596,14 @@ namespace Jellyfin.Server
try
{
// Serilog.Log is used by SerilogLoggerFactory when no logger is specified
Serilog.Log.Logger = new LoggerConfiguration()
Log.Logger = new LoggerConfiguration()
.WriteTo.Logger(lc =>
lc.ReadFrom.Configuration(configuration)
.Enrich.FromLogContext()
.Enrich.WithThreadId()
.Filter.ByExcluding(Matching.FromSource<ClientEventLogger>()))
.WriteTo.Logger(lc =>
lc
.WriteTo.Map(
lc.WriteTo.Map(
"ClientName",
(clientName, wt)
=> wt.File(
@@ -607,7 +616,7 @@ namespace Jellyfin.Server
}
catch (Exception ex)
{
Serilog.Log.Logger = new LoggerConfiguration()
Log.Logger = new LoggerConfiguration()
.WriteTo.Logger(lc =>
lc.WriteTo.Async(x => x.File(
Path.Combine(appPaths.LogDirectoryPath, "log_.log"),
@@ -630,7 +639,7 @@ namespace Jellyfin.Server
.Filter.ByIncludingOnly(Matching.FromSource<ClientEventLogger>()))
.CreateLogger();
Serilog.Log.Logger.Fatal(ex, "Failed to create/read logger configuration");
Log.Logger.Fatal(ex, "Failed to create/read logger configuration");
}
}