Skip to content

Commit

Permalink
Add a better way to register a log source
Browse files Browse the repository at this point in the history
  • Loading branch information
TolikPylypchuk committed Sep 18, 2023
1 parent 815d8bd commit 26a0ebc
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 10 deletions.
2 changes: 1 addition & 1 deletion SharpHook.Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Console.WriteLine("---------- SharpHook Sample ----------\n");

using var logSource = LogSource.Register(minLevel: LogLevel.Debug);
using var logSource = LogSource.RegisterOrGet(minLevel: LogLevel.Debug);
using var reactiveLogSource = new ReactiveLogSourceAdapter(logSource, TaskPoolScheduler.Default);

reactiveLogSource.MessageLogged.Subscribe(OnMessageLogged);
Expand Down
75 changes: 70 additions & 5 deletions SharpHook/Logging/LogSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ namespace SharpHook.Logging;
[ExcludeFromCodeCoverage]
public sealed class LogSource : ILogSource
{
private static readonly object syncRoot = new();

private static LogSource? registeredLogSource = null;

private readonly LogEntryParser parser;
private readonly LoggerProc loggerProc;
private readonly ILoggingProvider loggingProvider;
Expand Down Expand Up @@ -52,15 +56,66 @@ private LogSource(ILoggingProvider loggingProvider, LogEntryParser parser, LogLe
/// </remarks>
public bool IsDisposed { get; private set; } = false;

/// <summary>
/// Creates and registers a source of libuiohook logs or returns the registered instance.
/// </summary>
/// <param name="minLevel">The minimum log level.</param>
/// <returns>A source of libuiohook logs.</returns>
/// <remarks>
/// This method should be preferred to <see cref="Register(LogLevel)" /> as it's safer - it won't invalidate an

Check warning on line 65 in SharpHook/Logging/LogSource.cs

View workflow job for this annotation

GitHub Actions / sharphook

Invalid type for parameter LogLevel in XML comment cref attribute: 'Register(LogLevel)'

Check warning on line 65 in SharpHook/Logging/LogSource.cs

View workflow job for this annotation

GitHub Actions / sharphook

XML comment has cref attribute 'Register(LogLevel)' that could not be resolved

Check warning on line 65 in SharpHook/Logging/LogSource.cs

View workflow job for this annotation

GitHub Actions / sharphook

Invalid type for parameter LogLevel in XML comment cref attribute: 'Register(LogLevel)'

Check warning on line 65 in SharpHook/Logging/LogSource.cs

View workflow job for this annotation

GitHub Actions / sharphook

XML comment has cref attribute 'Register(LogLevel)' that could not be resolved
/// already registered instance.
/// </remarks>
public static LogSource RegisterOrGet(LogLevel minLevel = LogLevel.Info) =>
RegisterOrGet(UioHookProvider.Instance, minLevel);

/// <summary>
/// Creates and registers a source of libuiohook logs or returns the registered instance.
/// </summary>
/// <param name="loggingProvider">The logging provider used to register the log source.</param>
/// <param name="minLevel">The minimum log level.</param>
/// <returns>A source of libuiohook logs.</returns>
/// <remarks>
/// <para>
/// This method should be preferred to <see cref="Register(LogLevel)" /> as it's safer - it won't invalidate an

Check warning on line 79 in SharpHook/Logging/LogSource.cs

View workflow job for this annotation

GitHub Actions / sharphook

Invalid type for parameter LogLevel in XML comment cref attribute: 'Register(LogLevel)'

Check warning on line 79 in SharpHook/Logging/LogSource.cs

View workflow job for this annotation

GitHub Actions / sharphook

XML comment has cref attribute 'Register(LogLevel)' that could not be resolved
/// already registered instance.
/// </para>
/// <para>
/// A single instance of <see cref="LogSource" /> can be registered using this method, irrespective of the logging
/// provider used.
/// </para>
/// </remarks>
/// <exception cref="ArgumentNullException">
/// <paramref name="loggingProvider" /> is <see langword="null" />.
/// </exception>
public static LogSource RegisterOrGet(ILoggingProvider loggingProvider, LogLevel minLevel = LogLevel.Info)
{
if (loggingProvider is null)
{
throw new ArgumentNullException(nameof(loggingProvider));
}

lock (syncRoot)
{
if (registeredLogSource is null)
{
registeredLogSource = new LogSource(loggingProvider, LogEntryParser.Instance, minLevel);
loggingProvider.SetLoggerProc(registeredLogSource.loggerProc, IntPtr.Zero);
}

return registeredLogSource;
}
}

/// <summary>
/// Creates and registers a source of libuiohook logs.
/// </summary>
/// <param name="minLevel">The minimum log level.</param>
/// <returns>A source of libuiohook logs.</returns>
/// <remarks>
/// This method must not be called when another <see cref="LogSource" /> instance has already been registerd and
/// hasn't been disposed.
/// This method is obsolete as it must not be called when another <see cref="LogSource" /> instance has already been
/// registerd and hasn't been disposed. <see cref="RegisterOrGet(LogLevel)" /> should be used instead.

Check warning on line 116 in SharpHook/Logging/LogSource.cs

View workflow job for this annotation

GitHub Actions / sharphook

Invalid type for parameter LogLevel in XML comment cref attribute: 'RegisterOrGet(LogLevel)'

Check warning on line 116 in SharpHook/Logging/LogSource.cs

View workflow job for this annotation

GitHub Actions / sharphook

XML comment has cref attribute 'RegisterOrGet(LogLevel)' that could not be resolved
/// </remarks>
[Obsolete("LogSource.RegisterOrGet should be used instead")]
public static LogSource Register(LogLevel minLevel = LogLevel.Info) =>
Register(UioHookProvider.Instance, minLevel);

Expand All @@ -71,12 +126,14 @@ public static LogSource Register(LogLevel minLevel = LogLevel.Info) =>
/// <param name="minLevel">The minimum log level.</param>
/// <returns>A source of libuiohook logs.</returns>
/// <remarks>
/// This method must not be called when another <see cref="LogSource" /> instance has already been registerd and
/// hasn't been disposed.
/// This method is obsolete as it must not be called when another <see cref="LogSource" /> instance has already been
/// registerd and hasn't been disposed. <see cref="RegisterOrGet(ILoggingProvider, LogLevel)" /> should be used

Check warning on line 130 in SharpHook/Logging/LogSource.cs

View workflow job for this annotation

GitHub Actions / sharphook

Invalid type for parameter LogLevel in XML comment cref attribute: 'RegisterOrGet(ILoggingProvider, LogLevel)'

Check warning on line 130 in SharpHook/Logging/LogSource.cs

View workflow job for this annotation

GitHub Actions / sharphook

XML comment has cref attribute 'RegisterOrGet(ILoggingProvider, LogLevel)' that could not be resolved
/// instead.
/// </remarks>
/// <exception cref="ArgumentNullException">
/// <paramref name="loggingProvider" /> is <see langword="null" />.
/// </exception>
[Obsolete("LogSource.RegisterOrGet should be used instead")]
public static LogSource Register(ILoggingProvider loggingProvider, LogLevel minLevel = LogLevel.Info)
{
if (loggingProvider is null)
Expand Down Expand Up @@ -105,7 +162,15 @@ private void Dispose(bool disposing)
return;
}

this.loggingProvider.SetLoggerProc(null, IntPtr.Zero);
lock (syncRoot)
{
if (registeredLogSource == this)
{
registeredLogSource = null;
}

this.loggingProvider.SetLoggerProc(null, IntPtr.Zero);
}

if (disposing)
{
Expand Down
41 changes: 37 additions & 4 deletions SharpHook/SharpHook.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 26a0ebc

Please sign in to comment.