statsd-rupp 0.1.0.0 → 0.2.0.0
raw patch · 5 files changed
+72/−39 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- System.Metrics.StatsD.Internal: [$sel:sampling:StatGauge] :: StatGauge -> !Sampling
- System.Metrics.StatsD.Internal: type TimingData = [Int]
+ System.Metrics.StatsD: decrementGauge :: MonadIO m => StatGauge -> Int -> m ()
+ System.Metrics.StatsD: incrementGauge :: MonadIO m => StatGauge -> Int -> m ()
+ System.Metrics.StatsD.Internal: type Timings = [Int]
- System.Metrics.StatsD: newStatGauge :: MonadIO m => Stats -> Key -> Int -> Int -> m (Maybe StatGauge)
+ System.Metrics.StatsD: newStatGauge :: MonadIO m => Stats -> Key -> Int -> m (Maybe StatGauge)
- System.Metrics.StatsD.Internal: Gauge :: !Gauge -> Value
+ System.Metrics.StatsD.Internal: Gauge :: !Gauge -> !Bool -> Value
- System.Metrics.StatsD.Internal: StatGauge :: !Stats -> !Key -> !Sampling -> StatGauge
+ System.Metrics.StatsD.Internal: StatGauge :: !Stats -> !Key -> StatGauge
- System.Metrics.StatsD.Internal: TimingData :: !TimingData -> MetricData
+ System.Metrics.StatsD.Internal: TimingData :: !Timings -> MetricData
- System.Metrics.StatsD.Internal: makeTimingStats :: TimingData -> TimingStats
+ System.Metrics.StatsD.Internal: makeTimingStats :: Timings -> TimingStats
- System.Metrics.StatsD.Internal: timingReports :: StatConfig -> Key -> TimingData -> [Report]
+ System.Metrics.StatsD.Internal: timingReports :: StatConfig -> Key -> Timings -> [Report]
Files
- CHANGELOG.md +4/−0
- src/System/Metrics/StatsD.hs +19/−6
- src/System/Metrics/StatsD/Internal.hs +13/−11
- statsd-rupp.cabal +1/−1
- test/Spec.hs +35/−21
CHANGELOG.md view
@@ -8,6 +8,10 @@ ## Unreleased +## 0.2.0.0 - 2023-09-02++- Fix gauges.+ ## 0.1.0.0 - 2023-09-02 - Initial release.
src/System/Metrics/StatsD.hs view
@@ -19,6 +19,8 @@ newStatSet, incrementCounter, setGauge,+ incrementGauge,+ decrementGauge, addTiming, newSetElement, withStats,@@ -80,11 +82,11 @@ else return Nothing newStatGauge ::- (MonadIO m) => Stats -> Key -> Int -> Int -> m (Maybe StatGauge)-newStatGauge stats key sampling ini = do+ (MonadIO m) => Stats -> Key -> Int -> m (Maybe StatGauge)+newStatGauge stats key ini = do success <- newMetric stats key (GaugeData ini) if success- then return $ Just $ StatGauge stats key sampling+ then return $ Just $ StatGauge stats key else return Nothing newStatTiming :: (MonadIO m) => Stats -> Key -> Int -> m (Maybe StatTiming)@@ -106,9 +108,16 @@ processSample stats sampling key . Counter setGauge :: (MonadIO m) => StatGauge -> Int -> m ()-setGauge StatGauge {..} =- processSample stats sampling key . Gauge+setGauge StatGauge {..} i =+ processSample stats 1 key (Gauge i False) +incrementGauge :: (MonadIO m) => StatGauge -> Int -> m ()+incrementGauge StatGauge {..} i =+ processSample stats 1 key (Gauge i True)++decrementGauge :: (MonadIO m) => StatGauge -> Int -> m ()+decrementGauge x i = incrementGauge x (negate i)+ addTiming :: (MonadIO m) => StatTiming -> Int -> m () addTiming StatTiming {..} = processSample stats sampling key . Timing@@ -154,7 +163,11 @@ let s = C.unpack v in case t of "c" -> Counter <$> parseRead s- "g" -> Gauge <$> parseRead s+ "g" ->+ case s of+ '+' : n -> Gauge <$> parseRead n <*> pure True+ '-' : _ -> Gauge <$> parseRead s <*> pure True+ _ -> Gauge <$> parseRead s <*> pure False "s" -> return $ Set s "ms" -> Timing <$> parseRead s _ -> mzero
src/System/Metrics/StatsD/Internal.hs view
@@ -15,7 +15,7 @@ Gauge, Timing, SetElement,- TimingData,+ Timings, SetData, MetricData (..), Store (..),@@ -120,14 +120,14 @@ type SetElement = String -type TimingData = [Int]+type Timings = [Int] type SetData = HashSet String data MetricData = CounterData !Counter | GaugeData !Gauge- | TimingData !TimingData+ | TimingData !Timings | SetData !(HashSet String) data Store = Store@@ -139,7 +139,7 @@ data Value = Counter !Counter- | Gauge !Gauge+ | Gauge !Gauge !Bool | Timing !Timing | Set !SetElement | Metric !Int@@ -169,8 +169,7 @@ data StatGauge = StatGauge { stats :: !Stats,- key :: !Key,- sampling :: !Sampling+ key :: !Key } data StatTiming = StatTiming@@ -215,7 +214,8 @@ adjust m = m {index = m.index + 1, dat = change <$> m.dat} change store = case (reading, store) of (Counter c, CounterData s) -> CounterData (s + c)- (Gauge i, GaugeData _) -> GaugeData i+ (Gauge i False, GaugeData _) -> GaugeData i+ (Gauge i True, GaugeData g) -> GaugeData (max 0 (g + i)) (Timing t, TimingData s) -> TimingData (t : s) (Set e, SetData s) -> SetData (HashSet.insert e s) _ -> error "Stats reading mismatch"@@ -279,7 +279,7 @@ GaugeData s -> [ Report { key = catKey [cfg.statsPrefix, cfg.prefixGauge, key],- value = Gauge s,+ value = Gauge s False, rate = 1.0 } ]@@ -299,7 +299,7 @@ } deriving (Eq, Ord, Show, Read) -makeTimingStats :: TimingData -> TimingStats+makeTimingStats :: Timings -> TimingStats makeTimingStats timings = TimingStats { timings = sorted,@@ -316,7 +316,7 @@ . filter (\x -> x > 0 && x < 100) . (.timingPercentiles) -timingReports :: StatConfig -> Key -> TimingData -> [Report]+timingReports :: StatConfig -> Key -> Timings -> [Report] timingReports cfg key timings = concatMap (timingStats cfg key tstats) percentiles where@@ -432,8 +432,10 @@ case report.value of Counter i -> printf "%d|c%s" i rate- Gauge g ->+ Gauge g False -> printf "%d|g" g+ Gauge g True ->+ printf "%+d|g" g Timing t -> printf "%d|ms%s" t rate Set e ->
statsd-rupp.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: statsd-rupp-version: 0.1.0.0+version: 0.2.0.0 synopsis: Simple StatsD Client description: Please see the README on GitHub at <https://github.com/jprupp/statsd-rupp#readme> category: System
test/Spec.hs view
@@ -26,7 +26,7 @@ Just _ <- newStatCounter stats "planets" 1 Just _ <- newStatCounter stats "moons" 1 return () :: Expectation- it "reports two counters" $ \(stats, report) -> do+ it "reports on two counters" $ \(stats, report) -> do Just planets <- newStatCounter stats "planets" 1 Just moons <- newStatCounter stats "moons" 1 incrementCounter planets 10@@ -50,7 +50,7 @@ rs `shouldMatchList` rs' r <- report r.key `shouldNotBe` "moons"- it "reports counter stats" $ \(stats, report) -> do+ it "reports stats" $ \(stats, report) -> do Just c <- newStatCounter stats "planets" 4 replicateM_ 20 (incrementCounter c 10) replicateM_ 5 report@@ -69,14 +69,14 @@ ] rs `shouldMatchList` rs' describe "timing" $ do- it "reports timing events" $ \(stats, report) -> do+ it "reports events" $ \(stats, report) -> do let timings = [51 .. 55] Just t <- newStatTiming stats "trips" 1 forM_ timings (addTiming t) rs <- replicateM (length timings) report let rs' = map (\n -> Report "trips" (Timing n) 1.0) timings rs `shouldMatchList` rs'- it "reports empty timing stats" $ \(stats, report) -> do+ it "reports empty stats" $ \(stats, report) -> do Just _ <- newStatTiming stats "holes" 1 rs <- replicateM 8 report let rs' =@@ -99,7 +99,7 @@ i `mod` 100 == 0 ] rs `shouldMatchList` rs'- it "computes timing stats correctly" $ const $ do+ it "computes stats" $ const $ do let ps = reverse [5 .. 800] ++ [801 .. 1500] p90 = take (length ps * 90 `div` 100) (sort ps) p95 = take (length ps * 95 `div` 100) (sort ps)@@ -138,7 +138,7 @@ last t95.cumsquares `shouldBe` sumsq p95 last t95.cumsums `shouldBe` sum p95 median t95 `shouldBe` median' p95- it "reports timing stats" $ \(stats, report) -> do+ it "reports stats" $ \(stats, report) -> do let timings = [5 .. 1500] Just t <- newStatTiming stats "kittens" 0 forM_ timings (addTiming t)@@ -184,38 +184,52 @@ rs <- replicateM (length rs') report rs `shouldMatchList` rs' describe "gauge" $ do- it "reports gauge set events" $ \(stats, report) -> do+ it "reports set events" $ \(stats, report) -> do let gauges = [51 .. 55]- Just g <- newStatGauge stats "speed" 1 50+ Just g <- newStatGauge stats "speed" 50 forM_ gauges (setGauge g) rs <- replicateM (length gauges) report- let rs' = map (\n -> Report "speed" (Gauge n) 1.0) gauges+ let rs' = map (\n -> Report "speed" (Gauge n False) 1.0) gauges rs `shouldMatchList` rs'- it "reports gauge stats" $ \(stats, report) -> do+ it "reports stats" $ \(stats, report) -> do let gauges = [51 .. 55]- Just g <- newStatGauge stats "speed" 1 50+ Just g <- newStatGauge stats "radius" 50 r <- report- r `shouldBe` Report "stats.gauges.speed" (Gauge 50) 1.0+ r `shouldBe` Report "stats.gauges.radius" (Gauge 50 False) 1.0 forM_ gauges (setGauge g) replicateM_ (length gauges) report rs <- replicateM 2 report- let rs' = replicate 2 $ Report "stats.gauges.speed" (Gauge 55) 1.0+ let rs' = replicate 2 $ Report "stats.gauges.radius" (Gauge 55 False) 1.0 rs `shouldMatchList` rs'+ it "increments and decrements value" $ \(stats, report) -> do+ Just g <- newStatGauge stats "breadth" 50+ incrementGauge g 5+ report `shouldReturn` Report "breadth" (Gauge 5 True) 1.0+ report `shouldReturn` Report "stats.gauges.breadth" (Gauge 55 False) 1.0+ incrementGauge g (-10)+ report `shouldReturn` Report "breadth" (Gauge (-10) True) 1.0+ report `shouldReturn` Report "stats.gauges.breadth" (Gauge 45 False) 1.0+ decrementGauge g 50+ report `shouldReturn` Report "breadth" (Gauge (-50) True) 1.0+ report `shouldReturn` Report "stats.gauges.breadth" (Gauge 0 False) 1.0+ decrementGauge g (-25)+ report `shouldReturn` Report "breadth" (Gauge 25 True) 1.0+ report `shouldReturn` Report "stats.gauges.breadth" (Gauge 25 False) 1.0 describe "set" $ do- it "reports set events" $ \(stats, report) -> do+ it "reports events" $ \(stats, report) -> do let set = ["one", "two", "three", "three"]- Just s <- newStatSet stats "numbers"+ Just s <- newStatSet stats "potatoes" forM_ set (newSetElement s) rs <- replicateM (length set) report- let rs' = map (\x -> Report "numbers" (Set x) 1.0) set+ let rs' = map (\x -> Report "potatoes" (Set x) 1.0) set rs `shouldMatchList` rs'- it "reports set stats" $ \(stats, report) -> do+ it "reports stats" $ \(stats, report) -> do let set = ["two", "three", "one", "two", "three", "three"]- Just s <- newStatSet stats "numbers"+ Just s <- newStatSet stats "bananas" forM_ set (newSetElement s) let rs' =- [ Report "stats.sets.numbers.count" (Counter 3) 1.0,- Report "stats.sets.numbers.count" (Counter 0) 1.0+ [ Report "stats.sets.bananas.count" (Counter 3) 1.0,+ Report "stats.sets.bananas.count" (Counter 0) 1.0 ] rs <- replicateM (length set + length rs') report rs `shouldEndWith` rs'@@ -238,7 +252,7 @@ where fwd s2 q = forever $ do bs <- liftIO $ B.lines <$> recv s2 (2 ^ (20 :: Int))- let rs = mapMaybe parseReport bs+ let rs = map (fromJust . parseReport) bs mapM_ (atomically . writeTQueue q) rs withMockSockets :: (MonadUnliftIO m) => ((Socket, Socket) -> m a) -> m a