using Fleet.Core; using Monitor.Protocol; namespace Monitor.Backend.Application; /// 原始块的索引信息(块本身在段文件里)。 public sealed record RawChunkMeta( ChunkId ChunkId, NodeId AgentId, string Series, string Kind, TaskId? TaskId, TestId? TestId, int? Phase, long StartTs, int DurationMs, bool Partial, string SegmentPath, long Offset, int Length); /// 写入一个原始块:块的完整字节加上用于索引的元数据。 public sealed record RawChunkAppend(RawChunkMeta Meta, ReadOnlyMemory Bytes, string Day); public sealed record RawQuery( NodeId? AgentId = null, string? Series = null, string? Kind = null, TestId? TestId = null, long? FromMs = null, long? ToMs = null, long? AfterStartTs = null, int Limit = 500); public sealed record MetricRow(NodeId AgentId, string Series, long WindowStart, bool Partial, byte[] Metrics); /// 每次入队递增:处理完成时只删除序号没变的项,处理期间又有迟到的块时不会丢更新。 public sealed record QueueItem(NodeId AgentId, string Series, long WindowStart, long NotBefore, string Reason, long Seq = 0); public sealed record MetricVersionRecord(string MetricId, string Fingerprint, long? RecomputeFrom, long? RecomputeCursor); /// 指标窗口的层级。数值是窗口宽度(秒)。 public enum MetricLevel { S10 = 10, M1 = 60, M5 = 300, H1 = 3600, } public static class MetricLevels { public static readonly IReadOnlyList All = [MetricLevel.S10, MetricLevel.M1, MetricLevel.M5, MetricLevel.H1]; public static long WidthMs(this MetricLevel level) => (long)level * 1000; public static string TableName(this MetricLevel level) => level switch { MetricLevel.S10 => "metric_10s", MetricLevel.M1 => "metric_1m", MetricLevel.M5 => "metric_5m", _ => "metric_1h", }; }