Skip to content
This repository has been archived by the owner on Jan 19, 2025. It is now read-only.

Commit

Permalink
Added LogWithContext
Browse files Browse the repository at this point in the history
  • Loading branch information
NaoUnderscore committed Jul 22, 2024
1 parent 8813d53 commit b7983db
Show file tree
Hide file tree
Showing 2 changed files with 215 additions and 1 deletion.
214 changes: 214 additions & 0 deletions Exiled.API/Features/Log.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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

View workflow job for this annotation

GitHub Actions / build

Field 'CONTEXT_CRITICAL' should not contain an underscore (https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1310.md)

/// <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

View workflow job for this annotation

GitHub Actions / build

Field 'CONTEXT_DATABASE' should not contain an underscore (https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1310.md)

/// <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

View workflow job for this annotation

GitHub Actions / build

Field 'CONTEXT_NETWORK' should not contain an underscore (https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1310.md)

/// <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

View workflow job for this annotation

GitHub Actions / build

Field 'CONTEXT_AUTHENTICATION' should not contain an underscore (https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1310.md)

/// <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

View workflow job for this annotation

GitHub Actions / build

Field 'CONTEXT_CONFIGURATION' should not contain an underscore (https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1310.md)

/// <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

View workflow job for this annotation

GitHub Actions / build

Field 'CONTEXT_PERFORMANCE' should not contain an underscore (https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1310.md)

/// <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

View workflow job for this annotation

GitHub Actions / build

Field 'CONTEXT_SECURITY' should not contain an underscore (https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1310.md)

/// <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

View workflow job for this annotation

GitHub Actions / build


/// <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

View workflow job for this annotation

GitHub Actions / build


/// <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

View workflow job for this annotation

GitHub Actions / build


/// <summary>
/// Gets a <see cref="HashSet{T}"/> of plugin assemblies that have debug logs enabled.
/// </summary>
Expand Down Expand Up @@ -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}]";
}
}
}
2 changes: 1 addition & 1 deletion Exiled.CustomModules/API/Features/CustomModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ public void DeserializeModule()
{
if (string.IsNullOrEmpty(Name))
{
Log.Error($"{GetType().Name}::Name property was not defined. A module must define a name, or it won't load.");
Log.ErrorWithContext($"{GetType().Name}::Name property was not defined. A module must define a name, or it won't load.", Log.CONTEXT_CRITICAL);
return;
}

Expand Down

0 comments on commit b7983db

Please sign in to comment.