Remove 'report' option in logging
The feature was previously meant for monitoring errors in a large public bot instance, but is massively redundant and even annoying when using as a self-hosted instance. Besides, the information it did report was excessive and of little use.
This commit is contained in:
parent
c77e4bd579
commit
ebdaa6482c
9 changed files with 21 additions and 55 deletions
|
@ -19,7 +19,6 @@ class InstanceConfig {
|
||||||
/// List of assemblies to load, by file. Paths are always relative to the bot directory.
|
/// List of assemblies to load, by file. Paths are always relative to the bot directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal IReadOnlyList<string> Assemblies { get; }
|
internal IReadOnlyList<string> Assemblies { get; }
|
||||||
internal string InstanceLogTarget { get; }
|
|
||||||
|
|
||||||
public string? SqlHost { get; }
|
public string? SqlHost { get; }
|
||||||
public string? SqlDatabase { get; }
|
public string? SqlDatabase { get; }
|
||||||
|
@ -47,7 +46,6 @@ class InstanceConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
BotToken = ReadConfKey<string>(conf, nameof(BotToken), true);
|
BotToken = ReadConfKey<string>(conf, nameof(BotToken), true);
|
||||||
InstanceLogTarget = ReadConfKey<string>(conf, nameof(InstanceLogTarget), true);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Assemblies = Common.Utilities.LoadStringOrStringArray(conf[nameof(Assemblies)]).AsReadOnly();
|
Assemblies = Common.Utilities.LoadStringOrStringArray(conf[nameof(Assemblies)]).AsReadOnly();
|
||||||
|
|
|
@ -51,7 +51,7 @@ static class ModuleLoader {
|
||||||
newreport.Append($" {t.Name}");
|
newreport.Append($" {t.Name}");
|
||||||
newmods.Add((RegexbotModule)mod);
|
newmods.Add((RegexbotModule)mod);
|
||||||
}
|
}
|
||||||
rb._svcLogging.DoLog(false, nameof(ModuleLoader), newreport.ToString());
|
rb._svcLogging.DoLog(nameof(ModuleLoader), newreport.ToString());
|
||||||
return newmods;
|
return newmods;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
Program.cs
10
Program.cs
|
@ -34,15 +34,13 @@ class Program {
|
||||||
AlwaysDownloadUsers = true
|
AlwaysDownloadUsers = true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Initialize services, load modules
|
||||||
_main = new RegexbotClient(cfg, client);
|
_main = new RegexbotClient(cfg, client);
|
||||||
|
|
||||||
// Set up application close handler
|
// Set up application close handler
|
||||||
Console.CancelKeyPress += Console_CancelKeyPress;
|
Console.CancelKeyPress += Console_CancelKeyPress;
|
||||||
|
|
||||||
// TODO Set up unhandled exception handler
|
// Proceed to connect
|
||||||
// send error notification to instance log channel, if possible
|
|
||||||
|
|
||||||
// And off we go.
|
|
||||||
await _main.DiscordClient.LoginAsync(TokenType.Bot, cfg.BotToken);
|
await _main.DiscordClient.LoginAsync(TokenType.Bot, cfg.BotToken);
|
||||||
await _main.DiscordClient.StartAsync();
|
await _main.DiscordClient.StartAsync();
|
||||||
await Task.Delay(-1);
|
await Task.Delay(-1);
|
||||||
|
@ -51,7 +49,7 @@ class Program {
|
||||||
private static void Console_CancelKeyPress(object? sender, ConsoleCancelEventArgs e) {
|
private static void Console_CancelKeyPress(object? sender, ConsoleCancelEventArgs e) {
|
||||||
e.Cancel = true;
|
e.Cancel = true;
|
||||||
|
|
||||||
_main._svcLogging.DoLog(true, nameof(RegexBot), "Shutting down. Reason: Interrupt signal.");
|
_main._svcLogging.DoLog(nameof(RegexBot), "Shutting down.");
|
||||||
|
|
||||||
var finishingTasks = Task.Run(async () => {
|
var finishingTasks = Task.Run(async () => {
|
||||||
// TODO periodic task service: stop processing, wait for all tasks to finish
|
// TODO periodic task service: stop processing, wait for all tasks to finish
|
||||||
|
@ -60,7 +58,7 @@ class Program {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!finishingTasks.Wait(5000))
|
if (!finishingTasks.Wait(5000))
|
||||||
_main._svcLogging.DoLog(false, nameof(RegexBot), "Could not disconnect properly. Exiting...");
|
_main._svcLogging.DoLog(nameof(RegexBot), "Warning: Normal shutdown is taking too long. Exiting now.");
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,8 @@ public partial class RegexbotClient {
|
||||||
_svcCommonFunctions = new Services.CommonFunctions.CommonFunctionsService(this);
|
_svcCommonFunctions = new Services.CommonFunctions.CommonFunctionsService(this);
|
||||||
_svcEntityCache = new Services.EntityCache.EntityCacheService(this);
|
_svcEntityCache = new Services.EntityCache.EntityCacheService(this);
|
||||||
|
|
||||||
var ver = Assembly.GetExecutingAssembly().GetName().Version!;
|
var ver = Assembly.GetExecutingAssembly().GetName().Version!.ToString(3);
|
||||||
_svcLogging.DoLog(true, nameof(RegexBot), $"{nameof(RegexBot)} v{ver:3} - https://github.com/NoiTheCat/RegexBot");
|
_svcLogging.DoLog(nameof(RegexBot), $"{nameof(RegexBot)} v{ver} - https://github.com/NoiTheCat/RegexBot");
|
||||||
|
|
||||||
// Load externally defined functionality
|
// Load externally defined functionality
|
||||||
Modules = ModuleLoader.Load(Config, this);
|
Modules = ModuleLoader.Load(Config, this);
|
||||||
|
|
|
@ -73,16 +73,12 @@ public abstract class RegexbotModule {
|
||||||
/// <param name="message">The log message to send. Multi-line messages are acceptable.</param>
|
/// <param name="message">The log message to send. Multi-line messages are acceptable.</param>
|
||||||
protected void Log(SocketGuild guild, string? message) {
|
protected void Log(SocketGuild guild, string? message) {
|
||||||
var gname = guild.Name ?? $"Guild ID {guild.Id}";
|
var gname = guild.Name ?? $"Guild ID {guild.Id}";
|
||||||
Bot._svcLogging.DoLog(false, $"{gname}] [{Name}", message);
|
Bot._svcLogging.DoLog($"{gname}] [{Name}", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Emits a log message to the bot console and, optionally, the logging webhook.
|
/// Emits a log message to the bot console and, optionally, the logging webhook.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The log message to send. Multi-line messages are acceptable.</param>
|
/// <param name="message">The log message to send. Multi-line messages are acceptable.</param>
|
||||||
/// <param name="report">
|
protected void Log(string message) => Bot._svcLogging.DoLog(Name, message);
|
||||||
/// Specifies if the log message should be sent to the reporting channel.
|
|
||||||
/// Only messages of very high importance should use this option.
|
|
||||||
/// </param>
|
|
||||||
protected void Log(string message, bool report = false) => Bot._svcLogging.DoLog(report, Name, message);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,9 @@ class MessageCachingSubservice {
|
||||||
// Hooked
|
// Hooked
|
||||||
public event EcMessageUpdateHandler? OnCachePreUpdate;
|
public event EcMessageUpdateHandler? OnCachePreUpdate;
|
||||||
|
|
||||||
private readonly Action<string, bool> _log;
|
private readonly Action<string> _log;
|
||||||
|
|
||||||
internal MessageCachingSubservice(RegexbotClient bot, Action<string, bool> logMethod) {
|
internal MessageCachingSubservice(RegexbotClient bot, Action<string> logMethod) {
|
||||||
_log = logMethod;
|
_log = logMethod;
|
||||||
bot.DiscordClient.MessageReceived += DiscordClient_MessageReceived;
|
bot.DiscordClient.MessageReceived += DiscordClient_MessageReceived;
|
||||||
bot.DiscordClient.MessageUpdated += DiscordClient_MessageUpdated;
|
bot.DiscordClient.MessageUpdated += DiscordClient_MessageUpdated;
|
||||||
|
@ -63,8 +63,8 @@ class MessageCachingSubservice {
|
||||||
try {
|
try {
|
||||||
await (Task)handler.DynamicInvoke(oldMsg, newMsg)!;
|
await (Task)handler.DynamicInvoke(oldMsg, newMsg)!;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
_log($"Unhandled exception in {nameof(RegexbotClient.EcOnMessageUpdate)} handler '{handler.Method.Name}':", false);
|
_log($"Unhandled exception in {nameof(RegexbotClient.EcOnMessageUpdate)} handler '{handler.Method.Name}':\n"
|
||||||
_log(ex.ToString(), false);
|
+ ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Discord;
|
using Discord;
|
||||||
using Discord.Webhook;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
@ -9,11 +8,9 @@ namespace RegexBot.Services.Logging;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class LoggingService : Service {
|
class LoggingService : Service {
|
||||||
// NOTE: Service.Log's functionality is implemented here. DO NOT use within this class.
|
// NOTE: Service.Log's functionality is implemented here. DO NOT use within this class.
|
||||||
private readonly DiscordWebhookClient _instLogWebhook;
|
|
||||||
private readonly string? _logBasePath;
|
private readonly string? _logBasePath;
|
||||||
|
|
||||||
internal LoggingService(RegexbotClient bot) : base(bot) {
|
internal LoggingService(RegexbotClient bot) : base(bot) {
|
||||||
_instLogWebhook = new DiscordWebhookClient(bot.Config.InstanceLogTarget);
|
|
||||||
_logBasePath = Path.GetDirectoryName(Assembly.GetEntryAssembly()!.Location)
|
_logBasePath = Path.GetDirectoryName(Assembly.GetEntryAssembly()!.Location)
|
||||||
+ Path.DirectorySeparatorChar + "logs";
|
+ Path.DirectorySeparatorChar + "logs";
|
||||||
try {
|
try {
|
||||||
|
@ -21,7 +18,7 @@ class LoggingService : Service {
|
||||||
Directory.GetFiles(_logBasePath);
|
Directory.GetFiles(_logBasePath);
|
||||||
} catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) {
|
} catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) {
|
||||||
_logBasePath = null;
|
_logBasePath = null;
|
||||||
Output(Name, "Cannot create or access logging directory. File logging will be disabled.");
|
DoLog(Name, "Cannot create or access logging directory. File logging will be disabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bot.DiscordClient.Log += DiscordClient_Log;
|
bot.DiscordClient.Log += DiscordClient_Log;
|
||||||
|
@ -33,9 +30,8 @@ class LoggingService : Service {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Task DiscordClient_Log(LogMessage arg) {
|
private Task DiscordClient_Log(LogMessage arg) {
|
||||||
var msg = $"[{Enum.GetName(typeof(LogSeverity), arg.Severity)}] {arg.Message}";
|
var msg = $"[{Enum.GetName(typeof(LogSeverity), arg.Severity)}] {arg.Message}";
|
||||||
if (arg.Exception != null) msg += "\n```\n" + arg.Exception.ToString() + "\n```";
|
if (arg.Exception != null) msg += arg.Exception.ToString();
|
||||||
|
|
||||||
var important = arg.Severity != LogSeverity.Info;
|
|
||||||
switch (arg.Message) { // Prevent webhook logs for these 'important' Discord.Net messages
|
switch (arg.Message) { // Prevent webhook logs for these 'important' Discord.Net messages
|
||||||
case "Connecting":
|
case "Connecting":
|
||||||
case "Connected":
|
case "Connected":
|
||||||
|
@ -44,15 +40,16 @@ class LoggingService : Service {
|
||||||
case "Disconnected":
|
case "Disconnected":
|
||||||
case "Resumed previous session":
|
case "Resumed previous session":
|
||||||
case "Failed to resume previous session":
|
case "Failed to resume previous session":
|
||||||
important = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DoLog(important, "Discord.Net", msg);
|
DoLog("Discord.Net", msg);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Output(string source, string message) {
|
// Hooked
|
||||||
|
internal void DoLog(string source, string? message) {
|
||||||
|
message ??= "(null)";
|
||||||
var now = DateTimeOffset.UtcNow;
|
var now = DateTimeOffset.UtcNow;
|
||||||
var output = new StringBuilder();
|
var output = new StringBuilder();
|
||||||
var prefix = $"[{now:u}] [{source}] ";
|
var prefix = $"[{now:u}] [{source}] ";
|
||||||
|
@ -66,24 +63,4 @@ class LoggingService : Service {
|
||||||
File.AppendAllText(filename, outstr, Encoding.UTF8);
|
File.AppendAllText(filename, outstr, Encoding.UTF8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hooked
|
|
||||||
internal void DoLog(bool report, string source, string? message) {
|
|
||||||
message ??= "(null)";
|
|
||||||
Output(source, message);
|
|
||||||
if (report) Task.Run(() => ReportInstanceWebhook(source, message));
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ReportInstanceWebhook(string source, string message) {
|
|
||||||
try {
|
|
||||||
EmbedBuilder e = new() {
|
|
||||||
Footer = new EmbedFooterBuilder() { Text = source },
|
|
||||||
Timestamp = DateTimeOffset.UtcNow,
|
|
||||||
Description = message
|
|
||||||
};
|
|
||||||
await _instLogWebhook.SendMessageAsync(embeds: new[] { e.Build() });
|
|
||||||
} catch (Exception ex) {
|
|
||||||
DoLog(false, Name, "Failed to send message to reporting channel: " + ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,8 +75,6 @@ class ModuleStateService : Service {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Guild-specific service options? If implemented, this is where to load them.
|
|
||||||
|
|
||||||
// Load moderator list
|
// Load moderator list
|
||||||
var mods = new EntityList(guildConf["Moderators"]!, true);
|
var mods = new EntityList(guildConf["Moderators"]!, true);
|
||||||
|
|
||||||
|
@ -94,7 +92,7 @@ class ModuleStateService : Service {
|
||||||
Log("Unhandled exception while initializing guild state for module:\n" +
|
Log("Unhandled exception while initializing guild state for module:\n" +
|
||||||
$"Module: {module.Name} | " +
|
$"Module: {module.Name} | " +
|
||||||
$"Guild: {guildId} ({BotClient.DiscordClient.GetGuild(guildId)?.Name ?? "unknown name"})\n" +
|
$"Guild: {guildId} ({BotClient.DiscordClient.GetGuild(guildId)?.Name ?? "unknown name"})\n" +
|
||||||
$"```\n{ex}\n```", true);
|
$"```\n{ex}\n```");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,5 @@ internal abstract class Service {
|
||||||
/// Emits a log message.
|
/// Emits a log message.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The log message to send. Multi-line messages are acceptable.</param>
|
/// <param name="message">The log message to send. Multi-line messages are acceptable.</param>
|
||||||
/// <param name="report">Specify if the log message should be sent to a reporting channel.</param>
|
protected void Log(string message) => BotClient._svcLogging.DoLog(Name, message);
|
||||||
protected void Log(string message, bool report = false) => BotClient._svcLogging.DoLog(report, Name, message);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue