Added CommandService logging
This commit is contained in:
15
src/Discord.Net.Commands/CommandException.cs
Normal file
15
src/Discord.Net.Commands/CommandException.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
public class CommandException : Exception
|
||||
{
|
||||
public CommandInfo Command { get; }
|
||||
public ICommandContext Content { get; }
|
||||
|
||||
public CommandException(CommandInfo command, ICommandContext context, Exception ex)
|
||||
: base($"Error occurred executing {command.GetLogText(context)}.", ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using Discord.Commands.Builders;
|
||||
using Discord.Logging;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
@@ -7,12 +9,13 @@ using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Discord.Commands.Builders;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
public class CommandService
|
||||
{
|
||||
public event Func<LogMessage, Task> Log { add { _logEvent.Add(value); } remove { _logEvent.Remove(value); } }
|
||||
internal readonly AsyncEvent<Func<LogMessage, Task>> _logEvent = new AsyncEvent<Func<LogMessage, Task>>();
|
||||
|
||||
private readonly SemaphoreSlim _moduleLock;
|
||||
private readonly ConcurrentDictionary<Type, ModuleInfo> _typedModuleDefs;
|
||||
private readonly ConcurrentDictionary<Type, ConcurrentDictionary<Type, TypeReader>> _typeReaders;
|
||||
@@ -24,6 +27,8 @@ namespace Discord.Commands
|
||||
internal readonly bool _caseSensitive;
|
||||
internal readonly char _separatorChar;
|
||||
internal readonly RunMode _defaultRunMode;
|
||||
internal readonly Logger _cmdLogger;
|
||||
internal readonly LogManager _logManager;
|
||||
|
||||
public IEnumerable<ModuleInfo> Modules => _moduleDefs.Select(x => x);
|
||||
public IEnumerable<CommandInfo> Commands => _moduleDefs.SelectMany(x => x.Commands);
|
||||
@@ -36,7 +41,11 @@ namespace Discord.Commands
|
||||
_separatorChar = config.SeparatorChar;
|
||||
_defaultRunMode = config.DefaultRunMode;
|
||||
if (_defaultRunMode == RunMode.Default)
|
||||
throw new InvalidOperationException("The default run mode cannot be set to Default, it must be one of Sync, Mixed, or Async");
|
||||
throw new InvalidOperationException("The default run mode cannot be set to Default.");
|
||||
|
||||
_logManager = new LogManager(config.LogLevel);
|
||||
_logManager.Message += async msg => await _logEvent.InvokeAsync(msg).ConfigureAwait(false);
|
||||
_cmdLogger = _logManager.CreateLogger("Command");
|
||||
|
||||
_moduleLock = new SemaphoreSlim(1, 1);
|
||||
_typedModuleDefs = new ConcurrentDictionary<Type, ModuleInfo>();
|
||||
|
||||
@@ -8,5 +8,8 @@
|
||||
public char SeparatorChar { get; set; } = ' ';
|
||||
/// <summary> Should commands be case-sensitive? </summary>
|
||||
public bool CaseSensitiveCommands { get; set; } = false;
|
||||
|
||||
/// <summary> Gets or sets the minimum log level severity that will be sent to the Log event. </summary>
|
||||
public LogSeverity LogLevel { get; set; } = LogSeverity.Info;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,16 +137,48 @@ namespace Discord.Commands
|
||||
return ExecuteResult.FromError(result);
|
||||
}
|
||||
|
||||
await Module.Service._cmdLogger.DebugAsync($"Executing {GetLogText(context)}").ConfigureAwait(false);
|
||||
switch (RunMode)
|
||||
{
|
||||
case RunMode.Sync: //Always sync
|
||||
await _action(context, args, map).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await _action(context, args, map).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex = new CommandException(this, context, ex);
|
||||
await Module.Service._cmdLogger.ErrorAsync(ex).ConfigureAwait(false);
|
||||
throw;
|
||||
}
|
||||
await Module.Service._cmdLogger.VerboseAsync($"Executed {GetLogText(context)}").ConfigureAwait(false);
|
||||
break;
|
||||
case RunMode.Mixed: //Sync until first await statement
|
||||
var t1 = _action(context, args, map);
|
||||
var t1 = _action(context, args, map).ContinueWith(async t =>
|
||||
{
|
||||
if (t.IsFaulted)
|
||||
{
|
||||
var ex = new CommandException(this, context, t.Exception);
|
||||
await Module.Service._cmdLogger.ErrorAsync(ex).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
await Module.Service._cmdLogger.VerboseAsync($"Executed {GetLogText(context)}").ConfigureAwait(false);
|
||||
});
|
||||
break;
|
||||
case RunMode.Async: //Always async
|
||||
var t2 = Task.Run(() => _action(context, args, map));
|
||||
var t2 = Task.Run(() =>
|
||||
{
|
||||
var _ = _action(context, args, map).ContinueWith(async t =>
|
||||
{
|
||||
if (t.IsFaulted)
|
||||
{
|
||||
var ex = new CommandException(this, context, t.Exception);
|
||||
await Module.Service._cmdLogger.ErrorAsync(ex).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
await Module.Service._cmdLogger.VerboseAsync($"Executed {GetLogText(context)}").ConfigureAwait(false);
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
return ExecuteResult.FromSuccess();
|
||||
@@ -189,5 +221,13 @@ namespace Discord.Commands
|
||||
|
||||
private static T[] ConvertParamsList<T>(IEnumerable<object> paramsList)
|
||||
=> paramsList.Cast<T>().ToArray();
|
||||
|
||||
internal string GetLogText(ICommandContext context)
|
||||
{
|
||||
if (context.Guild != null)
|
||||
return $"\"{Name}\" for {context.User} in {context.Guild}/{context.Channel}";
|
||||
else
|
||||
return $"\"{Name}\" for {context.User} in {context.Channel}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
using Discord.Commands.Builders;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Discord.Commands.Builders;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
public class ParameterInfo
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Discord
|
||||
/// <summary> Gets or sets how a request should act in the case of an error, by default. </summary>
|
||||
public RetryMode DefaultRetryMode { get; set; } = RetryMode.AlwaysRetry;
|
||||
|
||||
/// <summary> Gets or sets the minimum log level severity that will be sent to the LogMessage event. </summary>
|
||||
/// <summary> Gets or sets the minimum log level severity that will be sent to the Log event. </summary>
|
||||
public LogSeverity LogLevel { get; set; } = LogSeverity.Info;
|
||||
|
||||
/// <summary> Gets or sets whether the initial log entry should be printed. </summary>
|
||||
|
||||
Reference in New Issue
Block a user