Skip to content

Commit 9d98507

Browse files
author
LoneWandererProductions
committed
add a Release neutral Logger Implementation and Interface
1 parent f5542ea commit 9d98507

3 files changed

Lines changed: 190 additions & 1 deletion

File tree

CoreMemoryLog/DebugLogger.cs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* COPYRIGHT: See COPYING in the top level directory
3+
* PROJECT: <Your Project Name>
4+
* FILE: DebugLogger.cs
5+
* PURPOSE: A lightweight wrapper for debug-only logging.
6+
* Provides zero-cost removal in Release builds.
7+
* Uses IEngineLogger as its backend, allowing any logging
8+
* implementation to be plugged in.
9+
* PROGRAMMER: Peter Geinitz (Wayfarer)
10+
*/
11+
12+
using System.Diagnostics;
13+
using System.IO;
14+
using System.Runtime.CompilerServices;
15+
using CoreMemoryLog;
16+
17+
/// <summary>
18+
/// Provides a static, debug-only logging wrapper that is **entirely removed**
19+
/// from Release builds using <see cref="ConditionalAttribute"/>.
20+
/// <para>
21+
/// This allows all engine subsystems (renderer, memory manager, physics,
22+
/// scene graph, tilemap, etc.) to call logging code without incurring
23+
/// **any runtime overhead** in Release builds.
24+
/// </para>
25+
/// <para>
26+
/// All logging work and parameter evaluation is skipped at compile time.
27+
/// In Debug builds, calls are routed to <see cref="Backend"/>,
28+
/// which can be swapped at runtime.
29+
/// </para>
30+
/// </summary>
31+
public static class DebugLogger
32+
{
33+
/// <summary>
34+
/// Gets or sets the backend logger instance used for debug logging.
35+
/// <para>
36+
/// Must implement <see cref="IEngineLogger"/>.
37+
/// Defaults to <see cref="InMemoryLogger.Instance"/>.
38+
/// </para>
39+
/// <para>
40+
/// You can replace this with any logger (console, file, network, UI)
41+
/// during engine initialization, as long as <c>DEBUG</c> is defined.
42+
/// </para>
43+
/// <para>
44+
/// In Release builds, this property has **no effect**, since all debug
45+
/// logging calls are removed at compile time.
46+
/// </para>
47+
/// </summary>
48+
public static IEngineLogger Backend { get; set; } = InMemoryLogger.Instance;
49+
50+
/// <summary>
51+
/// Writes a debug-level message to the configured backend.
52+
/// <para>This method is **compiled out in Release builds**.</para>
53+
/// </summary>
54+
/// <param name="message">The log message format string.</param>
55+
/// <param name="args">Optional format arguments.</param>
56+
[Conditional("DEBUG")]
57+
public static void Debug(string message, params object[] args)
58+
=> Backend.LogDebug(message, args);
59+
60+
/// <summary>
61+
/// Writes a trace-level message to the configured backend.
62+
/// <para>This method is **compiled out in Release builds**.</para>
63+
/// </summary>
64+
/// <param name="message">The log message format string.</param>
65+
/// <param name="args">Optional format arguments.</param>
66+
[Conditional("DEBUG")]
67+
public static void Trace(string message, params object[] args)
68+
=> Backend.LogTrace(message, args);
69+
70+
/// <summary>
71+
/// Writes an information-level message to the configured backend.
72+
/// <para>This method is **compiled out in Release builds**.</para>
73+
/// </summary>
74+
/// <param name="message">The log message format string.</param>
75+
/// <param name="args">Optional format arguments.</param>
76+
[Conditional("DEBUG")]
77+
public static void Info(string message, params object[] args)
78+
=> Backend.LogInformation(message, args);
79+
80+
/// <summary>
81+
/// Writes a warning-level message to the configured backend.
82+
/// <para>This method is **compiled out in Release builds**.</para>
83+
/// </summary>
84+
/// <param name="message">The log message format string.</param>
85+
/// <param name="args">Optional format arguments.</param>
86+
[Conditional("DEBUG")]
87+
public static void Warn(string message, params object[] args)
88+
=> Backend.LogWarning(message, args);
89+
90+
/// <summary>
91+
/// Writes an error-level message to the configured backend.
92+
/// <para>This method is **compiled out in Release builds**.</para>
93+
/// </summary>
94+
/// <param name="message">The log message format string.</param>
95+
/// <param name="args">Optional format arguments.</param>
96+
[Conditional("DEBUG")]
97+
public static void Error(string message, params object[] args)
98+
=> Backend.LogError(message, args);
99+
100+
/// <summary>
101+
/// Writes a debug-level message including caller metadata
102+
/// (file name, line number and calling method).
103+
/// <para>
104+
/// Useful for debugging the engine’s execution flow,
105+
/// especially in hot paths where stack traces are too slow.
106+
/// </para>
107+
/// <para>
108+
/// This method is **compiled out in Release**.
109+
/// </para>
110+
/// </summary>
111+
/// <param name="message">The main log message format string.</param>
112+
/// <param name="caller">Automatically filled with the calling member name.</param>
113+
/// <param name="file">Automatically filled with the calling source file path.</param>
114+
/// <param name="line">Automatically filled with the source line number.</param>
115+
/// <param name="args">Optional format arguments.</param>
116+
[Conditional("DEBUG")]
117+
public static void Debug(
118+
string message,
119+
[CallerMemberName] string caller = "",
120+
[CallerFilePath] string file = "",
121+
[CallerLineNumber] int line = 0,
122+
params object[] args)
123+
{
124+
string prefix = $"{Path.GetFileName(file)}:{line} {caller} → ";
125+
Backend.LogDebug(prefix + message, args);
126+
}
127+
}

CoreMemoryLog/IEngineLogger.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* COPYRIGHT: See COPYING in the top level directory
3+
* PROJECT: CoreMemoryLog
4+
* FILE: IEngineLogger.cs
5+
* PURPOSE: Defines a lightweight, engine-facing logging interface.
6+
* Used by DebugLogger and other components to allow flexible
7+
* backend implementations without imposing dependencies.
8+
* PROGRAMMER: Peter Geinitz (Wayfarer)
9+
*/
10+
11+
namespace CoreMemoryLog
12+
{
13+
/// <summary>
14+
/// Defines a minimal, engine-facing logging interface used by debug-only
15+
/// wrappers such as <c>DebugLogger</c>.
16+
/// <para>
17+
/// Implementations may route messages to any logging backend, such as
18+
/// in-memory buffers, consoles, files, or external monitoring systems.
19+
/// The interface is intentionally lightweight to minimize overhead when
20+
/// used together with conditional logging in debug builds.
21+
/// </para>
22+
/// </summary>
23+
public interface IEngineLogger
24+
{
25+
/// <summary>
26+
/// Writes a debug-level log message.
27+
/// </summary>
28+
/// <param name="message">The format string representing the log message.</param>
29+
/// <param name="args">Optional format arguments.</param>
30+
void LogDebug(string message, params object[] args);
31+
32+
/// <summary>
33+
/// Writes an information-level log message.
34+
/// </summary>
35+
/// <param name="message">The format string representing the log message.</param>
36+
/// <param name="args">Optional format arguments.</param>
37+
void LogInformation(string message, params object[] args);
38+
39+
/// <summary>
40+
/// Writes a warning-level log message.
41+
/// </summary>
42+
/// <param name="message">The format string representing the log message.</param>
43+
/// <param name="args">Optional format arguments.</param>
44+
void LogWarning(string message, params object[] args);
45+
46+
/// <summary>
47+
/// Writes an error-level log message.
48+
/// </summary>
49+
/// <param name="message">The format string representing the log message.</param>
50+
/// <param name="args">Optional format arguments.</param>
51+
void LogError(string message, params object[] args);
52+
53+
/// <summary>
54+
/// Writes a trace-level log message.
55+
/// Trace logs are typically used for very fine-grained debugging
56+
/// such as rendering loops, memory allocators, or ECS pipelines.
57+
/// </summary>
58+
/// <param name="message">The format string representing the log message.</param>
59+
/// <param name="args">Optional format arguments.</param>
60+
void LogTrace(string message, params object[] args);
61+
}
62+
}

CoreMemoryLog/InMemoryLogger.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace CoreMemoryLog
2222
/// In-memory logger that supports structured logging similar to Microsoft.Extensions.Logging
2323
/// and acts as a fallback logger for any library.
2424
/// </summary>
25-
public sealed class InMemoryLogger : ILogger, IInMemoryLogger, Microsoft.Extensions.Logging.ILogger
25+
public sealed class InMemoryLogger : ILogger, IInMemoryLogger, IEngineLogger, Microsoft.Extensions.Logging.ILogger
2626
{
2727
/// <summary>
2828
/// The memory instance

0 commit comments

Comments
 (0)