Initial version

This commit is contained in:
Yaakov 2020-05-21 10:35:58 +10:00
commit aecb3421c7
9 changed files with 257 additions and 0 deletions

View file

@ -0,0 +1,11 @@
namespace Microsoft.Extensions.Logging
{
public static class LoggingBuilderExtensions
{
public static ILoggingBuilder AddNotepad(this ILoggingBuilder builder)
{
builder.AddProvider(NotepadLoggerProvider.Instance);
return builder;
}
}
}

View file

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="3.1.4" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,107 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Extensions.ObjectPool;
namespace Microsoft.Extensions.Logging
{
class NotepadLogger : ILogger
{
public NotepadLogger(ObjectPool<StringBuilder> stringBuilderPool, string categoryName)
{
this.stringBuilderPool = stringBuilderPool;
this.categoryName = categoryName;
}
readonly ObjectPool<StringBuilder> stringBuilderPool;
readonly string categoryName;
public IDisposable BeginScope<TState>(TState state) => NullDisposable.Instance;
public bool IsEnabled(LogLevel logLevel) => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
if (formatter is null)
{
throw new ArgumentNullException(nameof(formatter));
}
var message = formatter(state, exception);
if (string.IsNullOrEmpty(message) && exception is null)
{
return;
}
WriteMessage(logLevel, eventId.Id, message, exception);
}
void WriteMessage(LogLevel logLevel, int eventId, string message, Exception ex)
{
var builder = stringBuilderPool.Get();
try
{
builder
.Append('[')
.Append(GetLogLevelString(logLevel))
.Append("] ")
.Append(categoryName)
.Append(" (")
.Append(eventId)
.Append(") ")
.AppendLine(message);
if (ex is { })
{
builder.Append(" ");
builder.AppendLine(ex.ToString());
}
WriteToNotepad(builder.ToString());
}
finally
{
stringBuilderPool.Return(builder);
}
}
static string GetLogLevelString(LogLevel logLevel) => logLevel switch
{
LogLevel.Trace => "trce",
LogLevel.Debug => "dbug",
LogLevel.Information => "info",
LogLevel.Warning => "warn",
LogLevel.Error => "fail",
LogLevel.Critical => "crit",
_ => throw new ArgumentOutOfRangeException(nameof(logLevel)),
};
static void WriteToNotepad(string message)
{
IntPtr hwnd = NativeMethods.FindWindow(null, "Untitled - Notepad");
IntPtr edit = NativeMethods.FindWindowEx(hwnd, IntPtr.Zero, "EDIT", null);
NativeMethods.SendMessage(edit, NativeMethods.EM_REPLACESEL, (IntPtr)1, message);
}
}
static class NativeMethods
{
[DllImport("User32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr hWndParent, IntPtr hWndChildAfter, string lpszClass, string lpszWindow);
public const int EM_REPLACESEL = 0x00C2;
[DllImport("User32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
}
}

View file

@ -0,0 +1,24 @@
using System.Text;
using Microsoft.Extensions.ObjectPool;
namespace Microsoft.Extensions.Logging
{
class NotepadLoggerProvider : ILoggerProvider
{
NotepadLoggerProvider()
{
var poolProvider = new DefaultObjectPoolProvider();
stringBuilderPool = poolProvider.CreateStringBuilderPool();
}
public static ILoggerProvider Instance { get; } = new NotepadLoggerProvider();
readonly ObjectPool<StringBuilder> stringBuilderPool;
public ILogger CreateLogger(string categoryName) => new NotepadLogger(stringBuilderPool, categoryName);
public void Dispose()
{
}
}
}

View file

@ -0,0 +1,13 @@
using System;
namespace Microsoft.Extensions.Logging
{
class NullDisposable : IDisposable
{
public static IDisposable Instance { get; } = new NullDisposable();
public void Dispose()
{
}
}
}