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:
@@ -15,11 +15,13 @@ module HomeAssistant.Runtime.Metrics
|
||||
|
||||
import Control.Concurrent (threadDelay)
|
||||
import Control.Monad (forever, unless)
|
||||
import Data.Char (ord)
|
||||
import Data.Int (Int64)
|
||||
import Data.List (intercalate, sortBy)
|
||||
import Data.Ord (comparing)
|
||||
import Data.Text (Text)
|
||||
import Data.Void (Void)
|
||||
import Numeric (showHex)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import qualified System.Metrics as M (Value (..), Sample, Store, sampleAll)
|
||||
@@ -41,8 +43,16 @@ dsTypeOf (M.Counter _) = Just Derive
|
||||
dsTypeOf (M.Gauge _) = Just Gauge
|
||||
dsTypeOf _ = Nothing
|
||||
|
||||
-- | Maps an ekg metric label to a valid rrd DS name (≤19 chars, [A-Za-z0-9_]).
|
||||
-- Long names keep the first 15 chars plus a 3-hex hash suffix for uniqueness.
|
||||
sanitizeName :: Text -> String
|
||||
sanitizeName = T.unpack . T.replace "." "_"
|
||||
sanitizeName name
|
||||
| length sanitized <= 19 = sanitized
|
||||
| otherwise = take 15 sanitized ++ "_" ++ paddedHash
|
||||
where
|
||||
sanitized = T.unpack (T.replace "." "_" name)
|
||||
paddedHash = let h = showHex (sum (map ord sanitized) `mod` 4096) ""
|
||||
in replicate (3 - length h) '0' ++ h
|
||||
|
||||
buildSchema :: M.Sample -> [DsSpec]
|
||||
buildSchema sample =
|
||||
|
||||
Reference in New Issue
Block a user