Fix: rrdtool DS names must be <= 19 chars

sanitizeName now keeps the first 15 chars plus a 3-hex hash suffix
for names longer than 19 chars (rrdtool's hard limit on DS name
length). The previous replace-dots-only version produced names up to
31 chars, which rrdtool rejected with 'invalid DS format'.
This commit is contained in:
2026-09-07 23:09:42 +03:00
parent e30a28c9ef
commit d3518e8ff2
2 changed files with 37 additions and 8 deletions
+26 -7
View File
@@ -41,22 +41,41 @@ spec = do
dsTypeOf (M.Label "hello") `shouldBe` Nothing
describe "sanitizeName" $ do
it "replaces dots with underscores" $
sanitizeName ("rts.gc.bytes_allocated" :: Text) `shouldBe` "rts_gc_bytes_allocated"
it "replaces dots with underscores for short names" $
sanitizeName ("rts.gc.cpu_ms" :: Text) `shouldBe` "rts_gc_cpu_ms"
it "shortens names longer than 19 chars to 15 chars + _ + 3 hex" $ do
let result = sanitizeName ("rts.gc.par_balanced_bytes_copied" :: Text)
length result `shouldBe` 19
take 15 result `shouldBe` "rts_gc_par_bala"
drop 15 result `shouldBe` "_" ++ drop 16 result
it "is deterministic (same input -> same output)" $
sanitizeName ("rts.gc.peak_megabytes_allocated" :: Text)
`shouldBe` sanitizeName ("rts.gc.peak_megabytes_allocated" :: Text)
describe "buildSchema" $ do
it "builds sorted DsSpecs from counters and gauges, skipping labels" $
let sample :: HashMap Text M.Value
sample = HM.fromList
[ ("rts.gc.bytes_allocated", M.Counter 1000)
, ("rts.gc.max_bytes_used", M.Gauge 500)
, ("rts.gc.label_thing", M.Label "irrelevant")
[ ("x.allocated", M.Counter 1000)
, ("a.bytes_used", M.Gauge 500)
, ("c.label_thing", M.Label "irrelevant")
]
in buildSchema sample `shouldBe`
[ DsSpec "rts.gc.bytes_allocated" "rts_gc_bytes_allocated" Derive
, DsSpec "rts.gc.max_bytes_used" "rts_gc_max_bytes_used" Gauge
[ DsSpec "a.bytes_used" "a_bytes_used" Gauge
, DsSpec "x.allocated" "x_allocated" Derive
]
it "produces dsName <= 19 chars for long ekg GC metric names" $
let sample :: HashMap Text M.Value
sample = HM.fromList
[ ("rts.gc.par_balanced_bytes_copied", M.Gauge 1)
, ("rts.gc.peak_megabytes_allocated", M.Gauge 2)
, ("rts.gc.cumulative_bytes_used", M.Counter 3)
]
in map (length . dsName) (buildSchema sample) `shouldSatisfy` all (<= 19)
describe "buildCreateArgs" $ do
it "builds create argv with mixed DERIVE and GAUGE DSes and RRAs" $
buildCreateArgs "test.rrd" 10