ingotctl, HTTP layer, and self-instrumentation
Add cmd/ingotctl with four subcommands: blocks (list with stats), inspect (series/postings dump), chunks (decode raw samples by ref), and fsck (CRC and index integrity validation across all blocks). Add cmd/ingothttp with JSON query endpoints: /api/v1/query_range (Prometheus-style matrix response), /api/v1/read (matcher-based read requests), and /epi/v1/status (DB stats snapshot). Uses JSON instead of protobuf to maintain zero dependencies. Add self-instrumentation via the normal Appender path so metrics are queryable with the same API: ingot_head_series, ingot_head_chunks_active, ingot_blocks_total, ingot_compactions_total, ingot_wal_fsync_duration_seconds. Supporting changes: block.Validate() and block.ReadMeta() exports, Head.Stats() for series/chunk counts, WAL.LastSyncDuration() with timed fsync tracking, DB.Stats() for the HTTP status endpoint.
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"git.dvdt.dev/david/ingot/internal/block"
|
||||
@@ -37,6 +38,9 @@ type DB struct {
|
||||
compactCtx context.Context
|
||||
compactCancel context.CancelFunc
|
||||
compactWg sync.WaitGroup
|
||||
|
||||
compactionCount atomic.Int64 // incremented on each successful compaction
|
||||
metricsR metricsRefs // cached series refs for self-instrumentation
|
||||
}
|
||||
|
||||
// Options configures a DB.
|
||||
@@ -237,6 +241,7 @@ func (db *DB) RunCompaction() error {
|
||||
}
|
||||
}
|
||||
|
||||
db.compactionCount.Add(1)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -292,6 +297,7 @@ func (db *DB) compactLoop() {
|
||||
case <-db.compactCtx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
db.collectMetrics()
|
||||
db.autoFlush()
|
||||
db.RunCompaction()
|
||||
db.ApplyRetention()
|
||||
@@ -306,6 +312,28 @@ func (db *DB) autoFlush() {
|
||||
db.FlushOlderThan(cutoff)
|
||||
}
|
||||
|
||||
// DBStats holds summary statistics for the database.
|
||||
type DBStats struct {
|
||||
HeadSeries int
|
||||
HeadChunks int
|
||||
Blocks int
|
||||
Compactions int
|
||||
}
|
||||
|
||||
// Stats returns a snapshot of database statistics.
|
||||
func (db *DB) Stats() DBStats {
|
||||
hs := db.head.Stats()
|
||||
db.mu.RLock()
|
||||
numBlocks := len(db.blocks)
|
||||
db.mu.RUnlock()
|
||||
return DBStats{
|
||||
HeadSeries: hs.NumSeries,
|
||||
HeadChunks: hs.NumActiveChunks,
|
||||
Blocks: numBlocks,
|
||||
Compactions: int(db.compactionCount.Load()),
|
||||
}
|
||||
}
|
||||
|
||||
// Close closes the DB, releasing all resources.
|
||||
func (db *DB) Close() error {
|
||||
db.compactCancel()
|
||||
|
||||
Reference in New Issue
Block a user