journal-bot/tools/JournalBot.Shared/RuntimeReader.cs

51 lines
1.7 KiB
C#

using System.Text.Json;
namespace JournalBot.Shared;
public sealed record QueueStatus(int Pending, int Failed);
public sealed class RuntimeReader
{
private readonly string _root;
public RuntimeReader(string runtimeRoot) => _root = runtimeRoot;
private string Queue(string sub) => Path.Combine(_root, "queue", sub);
public IReadOnlyList<QueueItem> ReadHistory()
{
var dir = Queue("done");
if (!Directory.Exists(dir)) return Array.Empty<QueueItem>();
var items = new List<QueueItem>();
foreach (var f in Directory.EnumerateFiles(dir, "*.json"))
{
try
{
var item = JsonSerializer.Deserialize<QueueItem>(
File.ReadAllText(f, System.Text.Encoding.UTF8));
if (item is not null) items.Add(item);
}
catch (JsonException) { /* skip malformed */ }
}
// Newest first by processed_at (fallback received_at).
return items
.OrderByDescending(i => i.ProcessedAt ?? i.ReceivedAt, StringComparer.Ordinal)
.ToList();
}
public QueueStatus ReadStatus()
{
int Count(string sub) => Directory.Exists(Queue(sub))
? Directory.EnumerateFiles(Queue(sub), "*.json").Count()
: 0;
return new QueueStatus(Count("pending"), Count("failed"));
}
public IReadOnlyList<string> TailLog(string fileName, int lines)
{
var path = Path.Combine(_root, "logs", fileName);
if (!File.Exists(path)) return Array.Empty<string>();
var all = File.ReadAllLines(path, System.Text.Encoding.UTF8);
return all.Length <= lines ? all : all[^lines..];
}
}