66 lines
1.7 KiB
C#
66 lines
1.7 KiB
C#
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace Sdt.Core;
|
|
|
|
public sealed class RunEventJsonlRecorder : IDisposable
|
|
{
|
|
private static readonly JsonSerializerOptions JsonOptions = new()
|
|
{
|
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
WriteIndented = false
|
|
};
|
|
|
|
static RunEventJsonlRecorder()
|
|
{
|
|
JsonOptions.Converters.Add(new JsonStringEnumConverter());
|
|
}
|
|
|
|
private readonly StreamWriter _writer;
|
|
private readonly object _gate = new();
|
|
private bool _disposed;
|
|
|
|
public string FilePath { get; }
|
|
|
|
private RunEventJsonlRecorder(string filePath, StreamWriter writer)
|
|
{
|
|
FilePath = filePath;
|
|
_writer = writer;
|
|
}
|
|
|
|
public static RunEventJsonlRecorder Create(string projectRoot, string category)
|
|
{
|
|
var root = Path.Combine(projectRoot, ".sdt", "events");
|
|
Directory.CreateDirectory(root);
|
|
var fileName = $"{category}-{DateTimeOffset.Now:yyyyMMdd-HHmmss}.jsonl";
|
|
var path = Path.Combine(root, fileName);
|
|
var writer = new StreamWriter(new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
|
|
{
|
|
AutoFlush = true
|
|
};
|
|
return new RunEventJsonlRecorder(path, writer);
|
|
}
|
|
|
|
public void Write(RunEvent evt)
|
|
{
|
|
lock (_gate)
|
|
{
|
|
if (_disposed)
|
|
return;
|
|
var line = JsonSerializer.Serialize(evt, JsonOptions);
|
|
_writer.WriteLine(line);
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
lock (_gate)
|
|
{
|
|
if (_disposed)
|
|
return;
|
|
_disposed = true;
|
|
_writer.Dispose();
|
|
}
|
|
}
|
|
}
|