forked from mirror/DotRecast
add log message broker sink
This commit is contained in:
parent
6300a24a81
commit
188b9e619e
|
@ -0,0 +1,26 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Serilog.Core;
|
||||||
|
using Serilog.Events;
|
||||||
|
using Serilog.Formatting;
|
||||||
|
|
||||||
|
namespace DotRecast.Recast.Demo.Logging.Sinks;
|
||||||
|
|
||||||
|
public class LogMessageBrokerSink : ILogEventSink
|
||||||
|
{
|
||||||
|
public static event Action<int, string> OnEmitted;
|
||||||
|
|
||||||
|
private readonly ITextFormatter _formatter;
|
||||||
|
|
||||||
|
public LogMessageBrokerSink(ITextFormatter formatter)
|
||||||
|
{
|
||||||
|
_formatter = formatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Emit(LogEvent logEvent)
|
||||||
|
{
|
||||||
|
using var writer = new StringWriter();
|
||||||
|
_formatter.Format(logEvent, writer);
|
||||||
|
OnEmitted?.Invoke((int)logEvent.Level, writer.ToString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using Serilog;
|
||||||
|
using Serilog.Configuration;
|
||||||
|
using Serilog.Events;
|
||||||
|
using Serilog.Formatting.Display;
|
||||||
|
|
||||||
|
namespace DotRecast.Recast.Demo.Logging.Sinks;
|
||||||
|
|
||||||
|
public static class SerilogSinkExtensions
|
||||||
|
{
|
||||||
|
public static LoggerConfiguration LogMessageBroker(
|
||||||
|
this LoggerSinkConfiguration sinkConfiguration,
|
||||||
|
LogEventLevel restrictedToMinimumLevel = LogEventLevel.Verbose,
|
||||||
|
string outputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}")
|
||||||
|
{
|
||||||
|
var formatter = new MessageTemplateTextFormatter(outputTemplate);
|
||||||
|
return sinkConfiguration.Sink(new LogMessageBrokerSink(formatter));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using DotRecast.Core;
|
using DotRecast.Core;
|
||||||
|
using DotRecast.Recast.Demo.Logging.Sinks;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Serilog.Enrichers;
|
using Serilog.Enrichers;
|
||||||
|
|
||||||
|
@ -9,7 +10,6 @@ public static class Program
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
|
||||||
var path = Loader.ToRPath("dungeon.obj");
|
var path = Loader.ToRPath("dungeon.obj");
|
||||||
path = Path.GetDirectoryName(path);
|
path = Path.GetDirectoryName(path);
|
||||||
if (!string.IsNullOrEmpty(path))
|
if (!string.IsNullOrEmpty(path))
|
||||||
|
@ -25,6 +25,7 @@ public static class Program
|
||||||
.Enrich.WithThreadId()
|
.Enrich.WithThreadId()
|
||||||
.Enrich.WithThreadName()
|
.Enrich.WithThreadName()
|
||||||
.Enrich.WithProperty(ThreadNameEnricher.ThreadNamePropertyName, "main")
|
.Enrich.WithProperty(ThreadNameEnricher.ThreadNamePropertyName, "main")
|
||||||
|
.WriteTo.LogMessageBroker(outputTemplate: format)
|
||||||
.WriteTo.Console(outputTemplate: format)
|
.WriteTo.Console(outputTemplate: format)
|
||||||
.WriteTo.File(
|
.WriteTo.File(
|
||||||
"logs/log.log",
|
"logs/log.log",
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using DotRecast.Recast.Demo.Logging.Sinks;
|
||||||
using DotRecast.Recast.Demo.Tools;
|
using DotRecast.Recast.Demo.Tools;
|
||||||
|
using DotRecast.Recast.Demo.UI.ViewModels;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Demo.UI;
|
namespace DotRecast.Recast.Demo.UI;
|
||||||
|
@ -13,29 +16,25 @@ public class RcLogView : IRcView
|
||||||
private RecastDemoCanvas _canvas;
|
private RecastDemoCanvas _canvas;
|
||||||
private bool _mouseInside;
|
private bool _mouseInside;
|
||||||
|
|
||||||
private List<string> _lines = new();
|
private readonly List<LogMessageItem> _lines;
|
||||||
private readonly ConcurrentQueue<string> _output = new();
|
private readonly ConcurrentQueue<LogMessageItem> _queues;
|
||||||
private readonly StringBuilder _outputStringBuilder = new();
|
|
||||||
|
|
||||||
private readonly ConcurrentQueue<string> _error = new();
|
|
||||||
private readonly StringBuilder _errorStringBuilder = new();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public RcLogView()
|
public RcLogView()
|
||||||
{
|
{
|
||||||
Console.SetOut(new ConsoleTextWriterHook(OnOut));
|
_lines = new();
|
||||||
Console.SetError(new ConsoleTextWriterHook(OnError));
|
_queues = new();
|
||||||
|
|
||||||
|
LogMessageBrokerSink.OnEmitted += OnOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnOut(string log)
|
private void OnOut(int level, string message)
|
||||||
{
|
{
|
||||||
_output.Enqueue(log);
|
var lines = message
|
||||||
}
|
.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries)
|
||||||
|
.Select(x => new LogMessageItem { Level = level, Message = x });
|
||||||
|
|
||||||
private void OnError(string log)
|
_lines.AddRange(lines);
|
||||||
{
|
|
||||||
_error.Enqueue(log);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
|
@ -43,23 +42,6 @@ public class RcLogView : IRcView
|
||||||
_lines.Clear();
|
_lines.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MergeLines(ConcurrentQueue<string> queue, StringBuilder builder)
|
|
||||||
{
|
|
||||||
while (queue.TryDequeue(out var s))
|
|
||||||
{
|
|
||||||
if (s != "\r\n")
|
|
||||||
{
|
|
||||||
builder.Append(s);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_lines.Add(builder.ToString());
|
|
||||||
builder.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void Bind(RecastDemoCanvas canvas)
|
public void Bind(RecastDemoCanvas canvas)
|
||||||
{
|
{
|
||||||
_canvas = canvas;
|
_canvas = canvas;
|
||||||
|
@ -67,8 +49,8 @@ public class RcLogView : IRcView
|
||||||
|
|
||||||
public void Update(double dt)
|
public void Update(double dt)
|
||||||
{
|
{
|
||||||
MergeLines(_output, _outputStringBuilder);
|
while (_queues.TryDequeue(out var item))
|
||||||
MergeLines(_error, _errorStringBuilder);
|
_lines.Add(item);
|
||||||
|
|
||||||
// buffer
|
// buffer
|
||||||
if (10240 < _lines.Count)
|
if (10240 < _lines.Count)
|
||||||
|
@ -108,7 +90,7 @@ public class RcLogView : IRcView
|
||||||
{
|
{
|
||||||
for (int lineNo = clipper.DisplayStart; lineNo < clipper.DisplayEnd; lineNo++)
|
for (int lineNo = clipper.DisplayStart; lineNo < clipper.DisplayEnd; lineNo++)
|
||||||
{
|
{
|
||||||
ImGui.TextUnformatted(_lines[lineNo]);
|
ImGui.TextUnformatted(_lines[lineNo].Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
namespace DotRecast.Recast.Demo.UI.ViewModels;
|
||||||
|
|
||||||
|
public class LogMessageItem
|
||||||
|
{
|
||||||
|
public required int Level { get; init; }
|
||||||
|
public required string Message { get; init; }
|
||||||
|
}
|
Loading…
Reference in New Issue