-
Notifications
You must be signed in to change notification settings - Fork 177
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,56 @@ namespace Exiled.API.Features | |
/// </summary> | ||
public static class Log | ||
{ | ||
/// <summary> | ||
/// Represents critical context, used for critical errors and issues. | ||
/// </summary> | ||
public const string CONTEXT_CRITICAL = "CRITICAL"; | ||
Check failure on line 23 in Exiled.API/Features/Log.cs
|
||
|
||
/// <summary> | ||
/// Represents database context, used for database-related operations and issues. | ||
/// </summary> | ||
public const string CONTEXT_DATABASE = "DATABASE"; | ||
Check failure on line 28 in Exiled.API/Features/Log.cs
|
||
|
||
/// <summary> | ||
/// Represents network context, used for network-related operations and issues. | ||
/// </summary> | ||
public const string CONTEXT_NETWORK = "NETWORK"; | ||
Check failure on line 33 in Exiled.API/Features/Log.cs
|
||
|
||
/// <summary> | ||
/// Represents authentication context, used for authentication and authorization-related operations. | ||
/// </summary> | ||
public const string CONTEXT_AUTHENTICATION = "AUTHENTICATION"; | ||
Check failure on line 38 in Exiled.API/Features/Log.cs
|
||
|
||
/// <summary> | ||
/// Represents configuration context, used for configuration-related operations and issues. | ||
/// </summary> | ||
public const string CONTEXT_CONFIGURATION = "CONFIGURATION"; | ||
Check failure on line 43 in Exiled.API/Features/Log.cs
|
||
|
||
/// <summary> | ||
/// Represents performance context, used for performance-related monitoring and issues. | ||
/// </summary> | ||
public const string CONTEXT_PERFORMANCE = "PERFORMANCE"; | ||
Check failure on line 48 in Exiled.API/Features/Log.cs
|
||
|
||
/// <summary> | ||
/// Represents security context, used for security-related operations and issues. | ||
/// </summary> | ||
public const string CONTEXT_SECURITY = "SECURITY"; | ||
Check failure on line 53 in Exiled.API/Features/Log.cs
|
||
|
||
/// <summary> | ||
/// Represents API context, used for API-related operations and issues. | ||
/// </summary> | ||
public const string CONTEXT_API = "API"; | ||
Check failure on line 58 in Exiled.API/Features/Log.cs
|
||
|
||
/// <summary> | ||
/// Represents logic context, used for core application logic operations and issues. | ||
/// </summary> | ||
public const string CONTEXT_LOGIC = "LOGIC"; | ||
Check failure on line 63 in Exiled.API/Features/Log.cs
|
||
|
||
/// <summary> | ||
/// Represents I/O context, used for input/output operations and issues. | ||
/// </summary> | ||
public const string CONTEXT_IO = "IO"; | ||
Check failure on line 68 in Exiled.API/Features/Log.cs
|
||
|
||
/// <summary> | ||
/// Gets a <see cref="HashSet{T}"/> of plugin assemblies that have debug logs enabled. | ||
/// </summary> | ||
|
@@ -177,5 +227,169 @@ public static void Assert(bool condition, object message) | |
|
||
throw new Exception(message.ToString()); | ||
} | ||
|
||
/// <summary> | ||
/// Sends a <see cref="Discord.LogLevel.Info"/> level message to the game console with context. | ||
/// </summary> | ||
/// <param name="message">The message to be sent.</param> | ||
/// <param name="context">Additional context to include in the log.</param> | ||
public static void InfoWithContext(object message, string context = null) | ||
{ | ||
context ??= GetContextInfo(); | ||
Send($"[{Assembly.GetCallingAssembly().GetName().Name}] [{context}] {message}", Discord.LogLevel.Info, ConsoleColor.Cyan); | ||
} | ||
|
||
/// <summary> | ||
/// Sends a <see cref="Discord.LogLevel.Info"/> level message to the game console with context. | ||
/// </summary> | ||
/// <param name="message">The message to be sent.</param> | ||
/// <param name="context">Additional context to include in the log.</param> | ||
public static void InfoWithContext(string message, string context = null) | ||
{ | ||
context ??= GetContextInfo(); | ||
Send($"[{Assembly.GetCallingAssembly().GetName().Name}] [{context}] {message}", Discord.LogLevel.Info, ConsoleColor.Cyan); | ||
} | ||
|
||
/// <summary> | ||
/// Sends a <see cref="Discord.LogLevel.Debug"/> level message to the game console with context. | ||
/// Server must have exiled_debug config enabled. | ||
/// </summary> | ||
/// <param name="message">The message to be sent.</param> | ||
/// <param name="context">Additional context to include in the log.</param> | ||
public static void DebugWithContext(object message, string context = null) | ||
{ | ||
Assembly callingAssembly = Assembly.GetCallingAssembly(); | ||
context ??= GetContextInfo(); | ||
#if DEBUG | ||
if (callingAssembly.GetName().Name is "Exiled.API") | ||
{ | ||
Send($"[{callingAssembly.GetName().Name}] [{context}] {message}", Discord.LogLevel.Debug, ConsoleColor.Green); | ||
return; | ||
} | ||
#endif | ||
|
||
if (DebugEnabled.Contains(callingAssembly)) | ||
Send($"[{callingAssembly.GetName().Name}] [{context}] {message})", Discord.LogLevel.Debug, ConsoleColor.Green); | ||
} | ||
|
||
/// <summary> | ||
/// Sends a <see cref="Discord.LogLevel.Debug"/> level message to the game console with context. | ||
/// Server must have exiled_debug config enabled. | ||
/// </summary> | ||
/// <typeparam name="T">The inputted object's type.</typeparam> | ||
/// <param name="object">The object to be logged and returned.</param> | ||
/// <param name="context">Additional context to include in the log.</param> | ||
/// <returns>Returns the <typeparamref name="T"/> object inputted in <paramref name="object"/>.</returns> | ||
public static T DebugObjectWithContext<T>(T @object, string context = null) | ||
{ | ||
DebugWithContext(@object, context); | ||
|
||
return @object; | ||
} | ||
|
||
/// <summary> | ||
/// Sends a <see cref="Discord.LogLevel.Debug"/> level message to the game console with context. | ||
/// Server must have exiled_debug config enabled. | ||
/// </summary> | ||
/// <param name="message">The message to be sent.</param> | ||
/// <param name="context">Additional context to include in the log.</param> | ||
public static void DebugWithContext(string message, string context = null) | ||
{ | ||
Assembly callingAssembly = Assembly.GetCallingAssembly(); | ||
context ??= GetContextInfo(); | ||
#if DEBUG | ||
if (callingAssembly.GetName().Name is "Exiled.API") | ||
{ | ||
Send($"[{callingAssembly.GetName().Name}] [{context}] {message})", Discord.LogLevel.Debug, ConsoleColor.Green); | ||
return; | ||
} | ||
#endif | ||
|
||
if (DebugEnabled.Contains(callingAssembly)) | ||
Send($"[{callingAssembly.GetName().Name}] [{context}] {message})", Discord.LogLevel.Debug, ConsoleColor.Green); | ||
} | ||
|
||
/// <summary> | ||
/// Sends a <see cref="Discord.LogLevel.Warn"/> level message to the game console with context. | ||
/// </summary> | ||
/// <param name="message">The message to be sent.</param> | ||
/// <param name="context">Additional context to include in the log.</param> | ||
public static void WarnWithContext(object message, string context = null) | ||
{ | ||
context ??= GetContextInfo(); | ||
Send($"[{Assembly.GetCallingAssembly().GetName().Name}] [{context}] {message}", Discord.LogLevel.Warn, ConsoleColor.Magenta); | ||
} | ||
|
||
/// <summary> | ||
/// Sends a <see cref="Discord.LogLevel.Warn"/> level message to the game console with context. | ||
/// </summary> | ||
/// <param name="message">The message to be sent.</param> | ||
/// <param name="context">Additional context to include in the log.</param> | ||
public static void WarnWithContext(string message, string context = null) | ||
{ | ||
context ??= GetContextInfo(); | ||
Send($"[{Assembly.GetCallingAssembly().GetName().Name}] [{context}] {message}", Discord.LogLevel.Warn, ConsoleColor.Magenta); | ||
} | ||
|
||
/// <summary> | ||
/// Sends a <see cref="Discord.LogLevel.Error"/> level message to the game console with context. | ||
/// This should be used to send errors only. | ||
/// It's recommended to send any messages in the catch block of a try/catch as errors with the exception string. | ||
/// </summary> | ||
/// <param name="message">The message to be sent.</param> | ||
/// <param name="context">Additional context to include in the log.</param> | ||
public static void ErrorWithContext(object message, string context = null) | ||
{ | ||
context ??= GetContextInfo(); | ||
Send($"[{Assembly.GetCallingAssembly().GetName().Name}] [{context}] {message}", Discord.LogLevel.Error, ConsoleColor.DarkRed); | ||
} | ||
|
||
/// <summary> | ||
/// Sends a <see cref="Discord.LogLevel.Error"/> level message to the game console with context. | ||
/// This should be used to send errors only. | ||
/// It's recommended to send any messages in the catch block of a try/catch as errors with the exception string. | ||
/// </summary> | ||
/// <param name="message">The message to be sent.</param> | ||
/// <param name="context">Additional context to include in the log.</param> | ||
public static void ErrorWithContext(string message, string context = null) | ||
{ | ||
context ??= GetContextInfo(); | ||
Send($"[{Assembly.GetCallingAssembly().GetName().Name}] [{context}] {message}", Discord.LogLevel.Error, ConsoleColor.DarkRed); | ||
} | ||
|
||
/// <summary> | ||
/// Sends an <see cref="Error(object)"/> with the provided message if the condition is false and stops the execution, including context information. | ||
/// <example> For example: | ||
/// <code> | ||
/// Player ply = Player.Get(2); | ||
/// Log.AssertWithContext(ply is not null, "The player with the id 2 is null", "GameLogic"); | ||
/// </code> | ||
/// results in it logging an error if the player is null and not continuing. | ||
/// </example> | ||
/// </summary> | ||
/// <param name="condition">The conditional expression to evaluate. If the condition is true it will continue.</param> | ||
/// <param name="message">The information message. The error and exception will show this message.</param> | ||
/// <param name="context">Additional context to include in the log.</param> | ||
/// <exception cref="Exception">If the condition is false. It throws an exception stopping the execution.</exception> | ||
public static void AssertWithContext(bool condition, object message, string context = null) | ||
{ | ||
if (condition) | ||
return; | ||
|
||
ErrorWithContext(message, context); | ||
|
||
throw new Exception(message.ToString()); | ||
} | ||
|
||
private static string GetContextInfo() | ||
{ | ||
StackFrame stackFrame = new(2, true); | ||
MethodBase method = stackFrame.GetMethod(); | ||
string methodName = method?.Name ?? "UnknownMethod"; | ||
string className = method?.DeclaringType?.Name ?? "UnknownClass"; | ||
int lineNumber = stackFrame.GetFileLineNumber(); | ||
|
||
return $"[{className}::{methodName} at line {lineNumber}]"; | ||
} | ||
} | ||
} |