Files
zszq-trs/Tools/YLTestTool/Forms/FormTraceLog.cs
2024-05-09 14:06:26 +08:00

169 lines
4.8 KiB
C#

using System.Diagnostics;
using YLErp.Commons;
using YLErp.Events;
namespace YLErp.Forms
{
public partial class FormTraceLog : Form
{
readonly InnerTraceListener _traceListener;
public FormTraceLog()
{
InitializeComponent();
_traceListener = new InnerTraceListener(richTextBox1);
EventBus.Subscribe<TraceEvent>(_traceListener.HandleTraceEvent);
Trace.Listeners.Clear();
Trace.Listeners.Add(_traceListener);
}
private void FormTraceLog_Load(object sender, EventArgs e)
{
}
private void FormLog_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
Hide();
}
}
private void menuClearLog_Click(object sender, EventArgs e)
{
_traceListener.Reset();
}
}
class InnerTraceListener : TraceListener
{
const int MaxDataCount = 3000;
const int MaxDataDiscardCount = 2000;
const string UrlPrefix = "http://trace/";
readonly List<object> _datalist;
readonly RichTextBox _richTextBox;
int _loopSeq;
readonly Action<string> _appendTextAction;
public InnerTraceListener(RichTextBox richTextBox)
{
_richTextBox = richTextBox;
_richTextBox.DetectUrls = true;
_richTextBox.LinkClicked += richTextBox_LinkClicked;
_datalist = new List<object>(MaxDataCount + 100);
_appendTextAction = text => _richTextBox.Text += text;
}
private void AppendTextInvoke(string text)
{
_richTextBox.BeginInvoke(_appendTextAction, text);
}
public void Reset()
{
lock (_datalist)
{
_loopSeq = 0;
_datalist.Clear();
_richTextBox.Clear();
}
}
private void richTextBox_LinkClicked(object sender, LinkClickedEventArgs e)
{
if (!e.LinkText.StartsWith(UrlPrefix)) return;
var text = e.LinkText.Substring(13);
var index = text.IndexOf('/');
if (index < 0) return;
var index2 = text.IndexOf('#', index + 1);
var left = text.Substring(0, index);
var right = text.Substring(index + 1, index2 - index - 1);
lock (_datalist)
{
index = (int.Parse(left) - _loopSeq) * 2000 + int.Parse(right);
if (index >= 0)
{
var json = JsonHelper.Serialize(_datalist[index]);
var form = new FormJsonView();
form.SetJson(json);
form.ShowDialog();
}
}
}
public override void Write(string message)
{
AppendTextInvoke(message);
}
public override void WriteLine(string message)
{
AppendTextInvoke($"{DateTime.Now:G} [--]{message}{Environment.NewLine}");
}
public override void WriteLine(string message, string category)
{
AppendTextInvoke($"{DateTime.Now:G} [{category}] {message}{Environment.NewLine}");
}
public override void WriteLine(object obj, string category)
{
var wrap = obj as TraceDataWrap;
if (wrap != null)
{
obj = wrap.Data;
}
if (obj is null)
{
AppendTextInvoke($"{DateTime.Now:G} [{category}] {UrlPrefix}null#{wrap?.DataDesc}{Environment.NewLine}");
return;
}
int curSeq = AddData(wrap?.Data ?? obj);
AppendTextInvoke($"{DateTime.Now:G} [{category}] {UrlPrefix}{_loopSeq}/{curSeq}#{wrap?.DataDesc}{Environment.NewLine}");
}
public void HandleTraceEvent(TraceEvent trace)
{
if (trace == null) return;
if (trace.Data != null)
{
int curSeq = AddData(trace.Data);
AppendTextInvoke($"{DateTime.Now:G} [{trace.Category}] {trace.Message} {UrlPrefix}{_loopSeq}/{curSeq}#{trace.DataDesc}{Environment.NewLine}");
}
else
{
AppendTextInvoke($"{DateTime.Now:G} [{trace.Category}] {trace.Message}{Environment.NewLine}");
}
}
private int AddData(object data)
{
if (_datalist.Count > MaxDataCount)
{
_loopSeq++;
_datalist.RemoveRange(0, MaxDataDiscardCount);
}
var count = _datalist.Count;
_datalist.Add(data);
return count;
}
}
}