use FileLogger as fallback in LogManager when site cannot be determined

This commit is contained in:
sbwalker 2024-09-18 07:37:52 -04:00
parent 40abb2720e
commit 355ce00968
2 changed files with 48 additions and 17 deletions

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Text.Json; using System.Text.Json;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Oqtane.Enums; using Oqtane.Enums;
using Oqtane.Models; using Oqtane.Models;
using Oqtane.Repository; using Oqtane.Repository;
@ -20,8 +21,9 @@ namespace Oqtane.Infrastructure
private readonly IHttpContextAccessor _accessor; private readonly IHttpContextAccessor _accessor;
private readonly IUserRoleRepository _userRoles; private readonly IUserRoleRepository _userRoles;
private readonly INotificationRepository _notifications; private readonly INotificationRepository _notifications;
private readonly ILogger<LogManager> _filelogger;
public LogManager(ILogRepository logs, ITenantManager tenantManager, IConfigManager config, IUserPermissions userPermissions, IHttpContextAccessor accessor, IUserRoleRepository userRoles, INotificationRepository notifications) public LogManager(ILogRepository logs, ITenantManager tenantManager, IConfigManager config, IUserPermissions userPermissions, IHttpContextAccessor accessor, IUserRoleRepository userRoles, INotificationRepository notifications, ILogger<LogManager> filelogger)
{ {
_logs = logs; _logs = logs;
_tenantManager = tenantManager; _tenantManager = tenantManager;
@ -30,24 +32,25 @@ namespace Oqtane.Infrastructure
_accessor = accessor; _accessor = accessor;
_userRoles = userRoles; _userRoles = userRoles;
_notifications = notifications; _notifications = notifications;
_filelogger = filelogger;
} }
public void Log(LogLevel level, object @class, LogFunction function, string message, params object[] args) public void Log(Shared.LogLevel level, object @class, LogFunction function, string message, params object[] args)
{ {
Log(-1, level, @class, function, null, message, args); Log(-1, level, @class, function, null, message, args);
} }
public void Log(LogLevel level, object @class, LogFunction function, Exception exception, string message, params object[] args) public void Log(Shared.LogLevel level, object @class, LogFunction function, Exception exception, string message, params object[] args)
{ {
Log(-1, level, @class, function, exception, message, args); Log(-1, level, @class, function, exception, message, args);
} }
public void Log(int siteId, LogLevel level, object @class, LogFunction function, string message, params object[] args) public void Log(int siteId, Shared.LogLevel level, object @class, LogFunction function, string message, params object[] args)
{ {
Log(siteId, level, @class, function, null, message, args); Log(siteId, level, @class, function, null, message, args);
} }
public void Log(int siteId, LogLevel level, object @class, LogFunction function, Exception exception, string message, params object[] args) public void Log(int siteId, Shared.LogLevel level, object @class, LogFunction function, Exception exception, string message, params object[] args)
{ {
Log log = new Log(); Log log = new Log();
@ -60,7 +63,6 @@ namespace Oqtane.Infrastructure
log.SiteId = alias.SiteId; log.SiteId = alias.SiteId;
} }
} }
if (log.SiteId == -1) return; // logs must be site specific
log.PageId = null; log.PageId = null;
log.ModuleId = null; log.ModuleId = null;
@ -92,7 +94,7 @@ namespace Oqtane.Infrastructure
log.Feature = log.Category; log.Feature = log.Category;
} }
log.Function = Enum.GetName(typeof(LogFunction), function); log.Function = Enum.GetName(typeof(LogFunction), function);
log.Level = Enum.GetName(typeof(LogLevel), level); log.Level = Enum.GetName(typeof(Shared.LogLevel), level);
if (exception != null) if (exception != null)
{ {
log.Exception = exception.ToString(); log.Exception = exception.ToString();
@ -112,27 +114,34 @@ namespace Oqtane.Infrastructure
public void Log(Log log) public void Log(Log log)
{ {
LogLevel minlevel = LogLevel.Information; var minlevel = Shared.LogLevel.Information;
var section = _config.GetSection("Logging:LogLevel:Default"); var section = _config.GetSection("Logging:LogLevel:Default");
if (section.Exists()) if (section.Exists())
{ {
minlevel = Enum.Parse<LogLevel>(section.Value); minlevel = Enum.Parse<Shared.LogLevel>(section.Value);
} }
if (Enum.Parse<LogLevel>(log.Level) >= minlevel) if (Enum.Parse<Shared.LogLevel>(log.Level) >= minlevel)
{ {
log.LogDate = DateTime.UtcNow; log.LogDate = DateTime.UtcNow;
log.Server = Environment.MachineName; log.Server = Environment.MachineName;
log.MessageTemplate = log.Message; log.MessageTemplate = log.Message;
log = ProcessStructuredLog(log); log = ProcessStructuredLog(log);
try try
{
if (log.SiteId != -1)
{ {
_logs.AddLog(log); _logs.AddLog(log);
SendNotification(log); SendNotification(log);
} }
else // use file logger as fallback when site cannot be determined
{
_filelogger.Log(GetLogLevel(log.Level), "[" + log.Category + "] " + log.Message);
}
}
catch catch
{ {
// an error occurred writing to the database // an error occurred writing the log
} }
} }
} }
@ -195,13 +204,13 @@ namespace Oqtane.Infrastructure
private void SendNotification(Log log) private void SendNotification(Log log)
{ {
LogLevel notifylevel = LogLevel.Error; Shared.LogLevel notifylevel = Shared.LogLevel.Error;
var section = _config.GetSection("Logging:LogLevel:Notify"); var section = _config.GetSection("Logging:LogLevel:Notify");
if (section.Exists()) if (section.Exists())
{ {
notifylevel = Enum.Parse<LogLevel>(section.Value); notifylevel = Enum.Parse<Shared.LogLevel>(section.Value);
} }
if (Enum.Parse<LogLevel>(log.Level) >= notifylevel) if (Enum.Parse<Shared.LogLevel>(log.Level) >= notifylevel)
{ {
var subject = $"Site {log.Level} Notification"; var subject = $"Site {log.Level} Notification";
string body = $"Log Message: {log.Message}"; string body = $"Log Message: {log.Message}";
@ -220,5 +229,26 @@ namespace Oqtane.Infrastructure
} }
} }
} }
private Microsoft.Extensions.Logging.LogLevel GetLogLevel(string level)
{
switch (Enum.Parse<Shared.LogLevel>(level))
{
case Shared.LogLevel.Trace:
return Microsoft.Extensions.Logging.LogLevel.Trace;
case Shared.LogLevel.Debug:
return Microsoft.Extensions.Logging.LogLevel.Debug;
case Shared.LogLevel.Information:
return Microsoft.Extensions.Logging.LogLevel.Information;
case Shared.LogLevel.Warning:
return Microsoft.Extensions.Logging.LogLevel.Warning;
case Shared.LogLevel.Error:
return Microsoft.Extensions.Logging.LogLevel.Error;
case Shared.LogLevel.Critical:
return Microsoft.Extensions.Logging.LogLevel.Critical;
default:
return Microsoft.Extensions.Logging.LogLevel.None;
}
}
} }
} }

View File

@ -65,7 +65,8 @@ namespace Oqtane.Security
{ {
if (!path.StartsWith("/api/")) // reduce log verbosity if (!path.StartsWith("/api/")) // reduce log verbosity
{ {
logger.Log(alias.SiteId, LogLevel.Information, "LoginValidation", Enums.LogFunction.Security, message, username, path); var siteId = (alias != null) ? alias.SiteId : -1;
logger.Log(siteId, LogLevel.Information, "UserValidation", Enums.LogFunction.Security, message, username, path);
} }
} }
} }