Skip to content

Commit 230160b

Browse files
author
LoneWandererProductions
committed
add Debug Ocne
1 parent a130186 commit 230160b

1 file changed

Lines changed: 122 additions & 0 deletions

File tree

‎Core.MemoryLog/DebugLogger.cs‎

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
// ReSharper disable UnusedType.Global
1313

14+
using System.Collections.Concurrent;
1415
using System.Diagnostics;
1516
using System.Runtime.CompilerServices;
1617

@@ -28,10 +29,23 @@ namespace Core.MemoryLog
2829
/// All logging work and parameter evaluation is skipped at compile time.
2930
/// In Debug builds, calls are routed to <see cref="Backend"/>,
3031
/// which can be swapped at runtime.
32+
/// Some Exceptions though WarningOnce and ErrorOnce are not compiled out, but they will only log once per call site.
3133
/// </para>
3234
/// </summary>
3335
public static class DebugLogger
3436
{
37+
38+
/// <summary>
39+
/// The logged keys
40+
/// </summary>
41+
private static readonly ConcurrentDictionary<string, byte> LoggedKeys = new();
42+
43+
/// <summary>
44+
/// Resets the LoggedKeys dictionary, allowing all "Once" log methods to log again.
45+
/// Escape Hatches: This is useful for unit tests that need to verify logging behavior across multiple test cases.
46+
/// </summary>
47+
public static void ResetOnce() => LoggedKeys.Clear();
48+
3549
/// <summary>
3650
/// Gets or sets the backend logger instance used for debug logging.
3751
/// <para>
@@ -126,5 +140,113 @@ public static void Debug(
126140
var prefix = $"{Path.GetFileName(file)}:{line} {caller} → ";
127141
Backend.LogDebug(prefix + message, args);
128142
}
143+
144+
/// <summary>
145+
/// Writes a debug-level message **only once** per call site during runtime.
146+
/// </summary>
147+
/// <param name="message">The message.</param>
148+
/// <param name="caller">The caller.</param>
149+
/// <param name="file">The file.</param>
150+
/// <param name="line">The line.</param>
151+
/// <param name="args">The arguments.</param>
152+
[Conditional("DEBUG")]
153+
public static void DebugOnce(
154+
string message,
155+
[CallerMemberName] string caller = "",
156+
[CallerFilePath] string file = "",
157+
[CallerLineNumber] int line = 0,
158+
params object[] args)
159+
{
160+
if (LoggedKeys.TryAdd($"{file}:{line}", 0))
161+
{
162+
Backend.LogDebug(message, args);
163+
}
164+
}
165+
166+
/// <summary>
167+
/// Writes a trace-level message **only once** per call site during runtime.
168+
/// </summary>
169+
/// <param name="message">The message.</param>
170+
/// <param name="caller">The caller.</param>
171+
/// <param name="file">The file.</param>
172+
/// <param name="line">The line.</param>
173+
/// <param name="args">The arguments.</param>
174+
[Conditional("DEBUG")]
175+
public static void TraceOnce(
176+
string message,
177+
[CallerMemberName] string caller = "",
178+
[CallerFilePath] string file = "",
179+
[CallerLineNumber] int line = 0,
180+
params object[] args)
181+
{
182+
if (LoggedKeys.TryAdd($"{file}:{line}", 0))
183+
{
184+
Backend.LogTrace(message, args);
185+
}
186+
}
187+
188+
/// <summary>
189+
/// Writes an information-level message **only once** per call site during runtime.
190+
/// </summary>
191+
/// <param name="message">The message.</param>
192+
/// <param name="caller">The caller.</param>
193+
/// <param name="file">The file.</param>
194+
/// <param name="line">The line.</param>
195+
/// <param name="args">The arguments.</param>
196+
[Conditional("DEBUG")]
197+
public static void InfoOnce(
198+
string message,
199+
[CallerMemberName] string caller = "",
200+
[CallerFilePath] string file = "",
201+
[CallerLineNumber] int line = 0,
202+
params object[] args)
203+
{
204+
if (LoggedKeys.TryAdd($"{file}:{line}", 0))
205+
{
206+
Backend.LogInformation(message, args);
207+
}
208+
}
209+
210+
/// <summary>
211+
/// Writes a warning-level message **only once** per call site during runtime.
212+
/// </summary>
213+
/// <param name="message">The message.</param>
214+
/// <param name="caller">The caller.</param>
215+
/// <param name="file">The file.</param>
216+
/// <param name="line">The line.</param>
217+
/// <param name="args">The arguments.</param>
218+
public static void WarnOnce(
219+
string message,
220+
[CallerMemberName] string caller = "",
221+
[CallerFilePath] string file = "",
222+
[CallerLineNumber] int line = 0,
223+
params object[] args)
224+
{
225+
if (LoggedKeys.TryAdd($"{file}:{line}", 0))
226+
{
227+
Backend.LogWarning(message, args);
228+
}
229+
}
230+
231+
/// <summary>
232+
/// Writes an error-level message **only once** per call site during runtime.
233+
/// </summary>
234+
/// <param name="message">The message.</param>
235+
/// <param name="caller">The caller.</param>
236+
/// <param name="file">The file.</param>
237+
/// <param name="line">The line.</param>
238+
/// <param name="args">The arguments.</param>
239+
public static void ErrorOnce(
240+
string message,
241+
[CallerMemberName] string caller = "",
242+
[CallerFilePath] string file = "",
243+
[CallerLineNumber] int line = 0,
244+
params object[] args)
245+
{
246+
if (LoggedKeys.TryAdd($"{file}:{line}", 0))
247+
{
248+
Backend.LogError(message, args);
249+
}
250+
}
129251
}
130252
}

0 commit comments

Comments
 (0)