mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
logging: cleanse messages in log files (#14433)
Co-authored-by: ilike2burnthing <59480337+ilike2burnthing@users.noreply.github.com>
This commit is contained in:
@@ -35,5 +35,13 @@ namespace Jackett.Common.Extensions
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string Replace(this string text, int index, int length, string replacement)
|
||||||
|
{
|
||||||
|
text = text.Remove(index, length);
|
||||||
|
text = text.Insert(index, replacement);
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,43 +2,43 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Jackett.Common.Models;
|
using Jackett.Common.Models;
|
||||||
using Jackett.Common.Services.Interfaces;
|
using Jackett.Common.Services.Interfaces;
|
||||||
|
using Jackett.Common.Utils.Logging;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NLog.Targets;
|
using NLog.Targets;
|
||||||
|
|
||||||
namespace Jackett.Common.Services
|
namespace Jackett.Common.Services
|
||||||
{
|
{
|
||||||
|
|
||||||
[Target("LogService")]
|
[Target("LogService")]
|
||||||
public class LogCacheService : TargetWithLayout, ILogCacheService
|
public class LogCacheService : TargetWithLayout, ILogCacheService
|
||||||
{
|
{
|
||||||
private static List<CachedLog> logs = new List<CachedLog>();
|
private static List<CachedLog> _Logs = new List<CachedLog>();
|
||||||
|
|
||||||
public void AddLog(LogEventInfo l)
|
|
||||||
{
|
|
||||||
lock (logs)
|
|
||||||
{
|
|
||||||
logs.Insert(0, new CachedLog()
|
|
||||||
{
|
|
||||||
Level = l.Level.Name,
|
|
||||||
Message = l.FormattedMessage,
|
|
||||||
When = l.TimeStamp
|
|
||||||
});
|
|
||||||
logs = logs.Take(200).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<CachedLog> Logs
|
public List<CachedLog> Logs
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
lock (logs)
|
lock (_Logs)
|
||||||
{
|
{
|
||||||
return logs.ToList();
|
return _Logs.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Write(LogEventInfo logEvent) => AddLog(logEvent);
|
protected override void Write(LogEventInfo logEvent) => AddLog(logEvent);
|
||||||
|
|
||||||
|
private static void AddLog(LogEventInfo logEvent)
|
||||||
|
{
|
||||||
|
lock (_Logs)
|
||||||
|
{
|
||||||
|
_Logs.Insert(0, new CachedLog
|
||||||
|
{
|
||||||
|
Level = logEvent.Level.Name,
|
||||||
|
Message = CleanseLogMessage.Cleanse(logEvent.FormattedMessage),
|
||||||
|
When = logEvent.TimeStamp
|
||||||
|
});
|
||||||
|
|
||||||
|
_Logs = _Logs.Take(200).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
src/Jackett.Common/Utils/Logging/CleanseFileTarget.cs
Normal file
15
src/Jackett.Common/Utils/Logging/CleanseFileTarget.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System.Text;
|
||||||
|
using NLog;
|
||||||
|
using NLog.Targets;
|
||||||
|
|
||||||
|
namespace Jackett.Common.Utils.Logging
|
||||||
|
{
|
||||||
|
public class CleanseFileTarget : FileTarget
|
||||||
|
{
|
||||||
|
protected override void RenderFormattedMessage(LogEventInfo logEvent, StringBuilder target)
|
||||||
|
{
|
||||||
|
var result = CleanseLogMessage.Cleanse(Layout.Render(logEvent));
|
||||||
|
target.Append(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
74
src/Jackett.Common/Utils/Logging/CleanseLogMessage.cs
Normal file
74
src/Jackett.Common/Utils/Logging/CleanseLogMessage.cs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Jackett.Common.Extensions;
|
||||||
|
|
||||||
|
namespace Jackett.Common.Utils.Logging
|
||||||
|
{
|
||||||
|
// See https://github.com/Prowlarr/Prowlarr/blob/develop/src/NzbDrone.Common/Instrumentation/CleanseLogMessage.cs
|
||||||
|
public class CleanseLogMessage
|
||||||
|
{
|
||||||
|
private static readonly Regex[] _CleansingRules =
|
||||||
|
{
|
||||||
|
// Url
|
||||||
|
new Regex(@"(?<=[?&: ;])(apikey|api_key|(?:(?:access|api)[-_]?)?token|pass(?:key|wd)?|auth|authkey|user|u?id|api|[a-z_]*apikey|account|pid|pwd)=(?<secret>[^&=""]+?)(?=[ ""&=]|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"(?<=[?& ;])[^=]*?(_?(?<!use|get_)token|username|passwo?rd)=(?<secret>[^&=]+?)(?= |&|$|;)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"rss\.torrentleech\.org/(?!rss)(?<secret>[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"rss\.torrentleech\.org/rss/download/[0-9]+/(?<secret>[0-9a-z]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"iptorrents\.com/[/a-z0-9?&;]*?(?:[?&;](u|tp)=(?<secret>[^&=;]+?))+(?= |;|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"/fetch/[a-z0-9]{32}/(?<secret>[a-z0-9]{32})", RegexOptions.Compiled),
|
||||||
|
new Regex(@"\b(\w*)?(_?(?<!use|get_)token|username|passwo?rd)=(?<secret>[^&=]+?)(?= |&|$|;)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"(?<=authkey = "")(?<secret>[^&=]+?)(?="")", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"(?<=beyond-hd\.[a-z]+/api/torrents/)(?<secret>[^&=][a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"(?<=beyond-hd\.[a-z]+/torrent/download/[\w\d-]+[.]\d+[.])(?<secret>[a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
|
||||||
|
// UNIT3D
|
||||||
|
new Regex(@"(?<=[a-z0-9-]+\.[a-z]+/torrent/download/\d+\.)(?<secret>[^&=][a-z0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
|
||||||
|
// Path
|
||||||
|
new Regex(@"""C:\\Users\\(?<secret>[^\""]+?)(\\|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"""/(home|Users)/(?<secret>[^/""]+?)(/|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
|
||||||
|
// uTorrent
|
||||||
|
new Regex(@"\[""[a-z._]*(username|password)"",\d,""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"\[""(boss_key|boss_key_salt|proxy\.proxy)"",\d,""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
|
||||||
|
// BroadcastheNet (;torrent_pass|torrents_notify_ is for MTV)
|
||||||
|
new Regex(@"""?method""?\s*:\s*""(getTorrents)"",\s*""?params""?\s*:\s*\[\s*""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"getTorrents\(""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"(?<=\?|&|;|=)(authkey|torrent_pass|torrents_notify)[_=](?<secret>[^&=]+?)(?=""|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
|
||||||
|
// Indexer Responses
|
||||||
|
new Regex(@"(?:avistaz|exoticaz|cinemaz|privatehd)\.[a-z]{2,3}/rss/download/(?<secret>[^&=]+?)/(?<secret>[^&=]+?)\.torrent", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"(?:animebytes)\.[a-z]{2,3}/torrent/[0-9]+/download/(?<secret>[^&=]+?)[""]", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@",""info_hash"":""(?<secret>[^&=]+?)"",", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@"""token"":""(?<secret>[^&=]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@",""pass[- _]?key"":""(?<secret>[^&=]+?)"",", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
new Regex(@",""rss[- _]?key"":""(?<secret>[^&=]+?)"",", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||||
|
};
|
||||||
|
|
||||||
|
public static string Cleanse(string message)
|
||||||
|
{
|
||||||
|
if (message.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var regex in _CleansingRules)
|
||||||
|
{
|
||||||
|
message = regex.Replace(message, m =>
|
||||||
|
{
|
||||||
|
var value = m.Value;
|
||||||
|
|
||||||
|
foreach (var capture in m.Groups["secret"].Captures.OfType<Capture>().Reverse())
|
||||||
|
{
|
||||||
|
value = value.Replace(capture.Index - m.Index, capture.Length, "(removed)");
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -3,6 +3,7 @@ using System.IO;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Jackett.Common.Models.Config;
|
using Jackett.Common.Models.Config;
|
||||||
using Jackett.Common.Services;
|
using Jackett.Common.Services;
|
||||||
|
using Jackett.Common.Utils.Logging;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NLog.Config;
|
using NLog.Config;
|
||||||
using NLog.LayoutRenderers;
|
using NLog.LayoutRenderers;
|
||||||
@@ -21,7 +22,7 @@ namespace Jackett.Common.Utils
|
|||||||
|
|
||||||
var logConfig = new LoggingConfiguration();
|
var logConfig = new LoggingConfiguration();
|
||||||
|
|
||||||
var logFile = new FileTarget
|
var logFile = new CleanseFileTarget
|
||||||
{
|
{
|
||||||
Layout = "${longdate} ${level} ${message} ${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}",
|
Layout = "${longdate} ${level} ${message} ${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}",
|
||||||
FileName = Path.Combine(settings.DataFolder, logFileName),
|
FileName = Path.Combine(settings.DataFolder, logFileName),
|
||||||
|
Reference in New Issue
Block a user