commit
a08d3e6867
@ -0,0 +1,8 @@ |
||||
/bower_components/ |
||||
/node_modules/ |
||||
/.pulp-cache/ |
||||
/output/ |
||||
/generated-docs/ |
||||
/.psc* |
||||
/.purs* |
||||
/.psa* |
@ -0,0 +1,19 @@ |
||||
{ |
||||
"name": "purescript-metrics", |
||||
"ignore": [ |
||||
"**/.*", |
||||
"node_modules", |
||||
"bower_components", |
||||
"output" |
||||
], |
||||
"dependencies": { |
||||
"purescript-prelude": "^3.1.1", |
||||
"purescript-console": "^3.0.0", |
||||
"purescript-aff": "^3.1.0", |
||||
"purescript-maybe": "^3.0.0", |
||||
"purescript-foreign-generic": "^5.0.0" |
||||
}, |
||||
"devDependencies": { |
||||
"purescript-psci-support": "^3.0.0" |
||||
} |
||||
} |
@ -0,0 +1,213 @@ |
||||
module System.Metrics |
||||
( Store |
||||
, MetricSampler(..) |
||||
, Value(..) |
||||
, newStore |
||||
, register |
||||
, registerOrGet |
||||
, get |
||||
, registerCounter |
||||
, registerGauge |
||||
, registerHistogram |
||||
, registerMeter |
||||
, registerTimer |
||||
, createOrGetCounter |
||||
, createOrGetGuage |
||||
, createOrGetHistogramWithExponentialDecaySampling |
||||
, createOrGetHistogramWithUniformSampling |
||||
, createOrGetMeter |
||||
, createOrGetTimer |
||||
, sampleOne |
||||
, sample |
||||
) where |
||||
|
||||
import Prelude |
||||
|
||||
import Control.Monad.Aff (Aff) |
||||
import Control.Monad.Eff (Eff) |
||||
import Control.Monad.Eff.Class (liftEff) |
||||
import Control.Monad.Eff.Exception (EXCEPTION, throw) |
||||
import Control.Monad.Eff.Ref (REF, Ref, modifyRef', newRef, readRef) |
||||
import Data.Generic.Rep (class Generic) |
||||
import Data.Generic.Rep.Show (genericShow) |
||||
import Data.Map as Map |
||||
import Data.Maybe (Maybe(..)) |
||||
import Data.Traversable (sequence) |
||||
import System.Metrics.Counter (Counter) |
||||
import System.Metrics.Counter as Counter |
||||
import System.Metrics.Gauge (Gauge) |
||||
import System.Metrics.Gauge as Gauge |
||||
import System.Metrics.Histogram (Histogram) |
||||
import System.Metrics.Histogram as Histogram |
||||
import System.Metrics.Meter (Meter) |
||||
import System.Metrics.Meter as Meter |
||||
import System.Metrics.Timer (Timer) |
||||
import System.Metrics.Timer as Timer |
||||
|
||||
-- | A mutable metric store. |
||||
newtype Store = Store (Ref State) |
||||
|
||||
-- | The 'Store' state. |
||||
type State = Map.Map String MetricSampler |
||||
|
||||
data MetricSampler = CounterS Counter |
||||
| GaugeS Gauge |
||||
| HistogramS Histogram |
||||
| MeterS Meter |
||||
| TimerS Timer |
||||
|
||||
-- | Create a new, empty metric store. |
||||
newStore ::forall eff. Eff (ref :: REF | eff) Store |
||||
newStore = do |
||||
ref <- newRef Map.empty |
||||
pure $ Store ref |
||||
|
||||
register :: forall eff. |
||||
String -> MetricSampler -> Store -> Eff (ref :: REF | eff) Boolean |
||||
register name sampler (Store store) = modifyRef' store $ \state -> |
||||
case Map.lookup name state of |
||||
Just s -> { state : state, value : false } |
||||
Nothing -> { state : Map.insert name sampler state, value : true } |
||||
|
||||
registerOrGet :: forall eff. |
||||
String -> MetricSampler -> Store -> Eff (ref :: REF | eff) MetricSampler |
||||
registerOrGet name sampler (Store store) = modifyRef' store $ \state -> |
||||
case Map.lookup name state of |
||||
Just s -> { state : state, value : s } |
||||
Nothing -> { state : Map.insert name sampler state, value : sampler } |
||||
|
||||
get :: forall eff. String -> Store -> Eff (ref :: REF | eff) (Maybe MetricSampler) |
||||
get name (Store store) = readRef store >>= pure <<< Map.lookup name |
||||
|
||||
-- | Register a non-negative, monotonically increasing, integer-valued metric. |
||||
-- | |
||||
-- | Also see 'createCounter'. |
||||
registerCounter :: forall eff. |
||||
String -> Counter -> Store -> Eff (ref :: REF | eff) Boolean |
||||
registerCounter name counter = register name (CounterS counter) |
||||
|
||||
-- | Create and register a zero-initialized counter. Throw exception is the counter is already created. |
||||
createOrGetCounter :: forall eff. |
||||
String |
||||
-> Store |
||||
-> Eff (ref :: REF, exception :: EXCEPTION | eff) Counter |
||||
createOrGetCounter name store = do |
||||
counter <- Counter.new |
||||
registerOrGet name (CounterS counter) store >>= case _ of |
||||
CounterS c -> pure c |
||||
_ -> throw $ "Metric name is already registered: " <> name |
||||
|
||||
-- | Register an integer-valued metric. |
||||
-- | |
||||
-- | Also see 'createGuage'. |
||||
registerGauge :: forall eff. |
||||
String -> Gauge -> Store -> Eff (ref :: REF | eff) Boolean |
||||
registerGauge name gauge = register name (GaugeS gauge) |
||||
|
||||
-- | Create and register a guage. Throw exception is the guage is already created. |
||||
createOrGetGuage :: forall eff. |
||||
String |
||||
-> (forall e. Aff e Int) |
||||
-> Store |
||||
-> Eff (ref :: REF, exception :: EXCEPTION | eff) Gauge |
||||
createOrGetGuage name f store = do |
||||
let gauge = Gauge.new f |
||||
registerOrGet name (GaugeS gauge) store >>= case _ of |
||||
GaugeS g -> pure g |
||||
_ -> throw $ "Metric name is already registered: " <> name |
||||
|
||||
registerHistogram :: forall eff. |
||||
String -> Histogram -> Store -> Eff (ref :: REF | eff) Boolean |
||||
registerHistogram name hist = register name (HistogramS hist) |
||||
|
||||
createOrGetHistogramWithExponentialDecaySampling |
||||
:: forall eff. |
||||
String |
||||
-> Int |
||||
-> Number |
||||
-> Store |
||||
-> Eff (ref :: REF, exception :: EXCEPTION | eff) Histogram |
||||
createOrGetHistogramWithExponentialDecaySampling name size alpha store = do |
||||
hist <- Histogram.newWithExponentialDecaySampling size alpha |
||||
registerOrGet name (HistogramS hist) store >>= case _ of |
||||
HistogramS c -> pure c |
||||
_ -> throw $ "Metric name is already registered: " <> name |
||||
|
||||
createOrGetHistogramWithUniformSampling |
||||
:: forall eff. |
||||
String |
||||
-> Int |
||||
-> Store |
||||
-> Eff (ref :: REF, exception :: EXCEPTION | eff) Histogram |
||||
createOrGetHistogramWithUniformSampling name size store = do |
||||
hist <- Histogram.newWithUniformSampling size |
||||
registerOrGet name (HistogramS hist) store >>= case _ of |
||||
HistogramS c -> pure c |
||||
_ -> throw $ "Metric name is already registered: " <> name |
||||
|
||||
registerMeter :: forall eff. String -> Meter -> Store -> Eff (ref :: REF | eff) Boolean |
||||
registerMeter name meter = register name (MeterS meter) |
||||
|
||||
createOrGetMeter |
||||
:: forall eff. |
||||
String |
||||
-> Store |
||||
-> Eff (ref :: REF, exception :: EXCEPTION | eff) Meter |
||||
createOrGetMeter name store = do |
||||
meter <- Meter.new |
||||
registerOrGet name (MeterS meter) store >>= case _ of |
||||
MeterS c -> pure c |
||||
_ -> throw $ "Metric name is already registered: " <> name |
||||
|
||||
registerTimer :: forall eff. String -> Timer -> Store -> Eff (ref :: REF | eff) Boolean |
||||
registerTimer name timer = register name (TimerS timer) |
||||
|
||||
createOrGetTimer |
||||
:: forall eff. |
||||
String |
||||
-> Store |
||||
-> Eff (ref :: REF, exception :: EXCEPTION | eff) Timer |
||||
createOrGetTimer name store = do |
||||
timer <- Timer.new |
||||
registerOrGet name (TimerS timer) store >>= case _ of |
||||
TimerS c -> pure c |
||||
_ -> throw $ "Metric name is already registered: " <> name |
||||
|
||||
type Sample = Map.Map String Value |
||||
|
||||
data Value = CounterV Int |
||||
| GaugeV Int |
||||
| HistogramV Histogram.Summary |
||||
| MeterV Meter.Summary |
||||
| TimerV Timer.Summary |
||||
|
||||
derive instance eqVal :: Eq Value |
||||
derive instance genVal :: Generic Value _ |
||||
instance showVal :: Show Value where |
||||
show = genericShow |
||||
|
||||
sampleOne :: forall eff. MetricSampler -> Aff (ref :: REF | eff) Value |
||||
sampleOne (CounterS c) = CounterV <$> liftEff (Counter.read c) |
||||
sampleOne (GaugeS g) = GaugeV <$> Gauge.read g |
||||
sampleOne (HistogramS h) = HistogramV <$> liftEff (Histogram.read h) |
||||
sampleOne (MeterS h) = MeterV <$> liftEff (Meter.read h) |
||||
sampleOne (TimerS h) = TimerV <$> liftEff (Timer.read h) |
||||
|
||||
sample :: forall eff. Store -> Aff (ref :: REF | eff) Sample |
||||
sample (Store store) = do |
||||
state <- liftEff $ readRef store |
||||
sequence $ map sampleOne state |
||||
|
||||
-- main = do |
||||
-- store <- newStore |
||||
-- counter <- createOrGetCounter "testc" store |
||||
-- gauge <- createOrGetGuage "testg" (pure 3) store |
||||
-- hist <- createOrGetHistogramWithExponentialDecaySampling "hizz" 1028 0.015 store |
||||
-- meter <- createOrGetMeter "mmm" store |
||||
-- timer <- createOrGetTimer "ttt" store |
||||
-- Counter.inc counter 2 |
||||
-- Histogram.update hist 1.2 |
||||
-- Histogram.update hist 2.1 |
||||
-- Meter.mark meter |
||||
-- Timer.update timer (Milliseconds 1000.0) |
||||
-- launchAff $ sample store >>= logShow |
@ -0,0 +1,28 @@ |
||||
var Counter = require("metrics/metrics/counter"); |
||||
|
||||
var _new = function() { |
||||
return new Counter(); |
||||
}; |
||||
|
||||
var read = function(c) { |
||||
return function() { |
||||
return c.count; |
||||
}; |
||||
}; |
||||
|
||||
var _inc = function(c, v) { |
||||
return function() { |
||||
c.inc(v); |
||||
}; |
||||
}; |
||||
|
||||
var reset = function(c) { |
||||
return function() { |
||||
c.value = 0; |
||||
} |
||||
} |
||||
|
||||
exports._new = _new; |
||||
exports.read = read; |
||||
exports._inc = _inc; |
||||
exports.reset = reset; |
@ -0,0 +1,18 @@ |
||||
module System.Metrics.Counter (Counter, new, read, inc) where |
||||
|
||||
import Control.Monad.Eff (Eff) |
||||
import Control.Monad.Eff.Ref (REF) |
||||
import Data.Function.Uncurried (Fn2, runFn2) |
||||
import Prelude (Unit) |
||||
|
||||
foreign import data Counter :: Type |
||||
foreign import _new :: forall eff. Eff (ref :: REF | eff) Counter |
||||
foreign import read :: forall eff. Counter -> Eff (ref :: REF | eff) Int |
||||
foreign import reset :: forall eff. Counter -> Eff (ref :: REF | eff) Unit |
||||
foreign import _inc :: forall eff. Fn2 Counter Int (Eff (ref :: REF | eff) Unit) |
||||
|
||||
new :: forall eff. Eff (ref :: REF | eff) Counter |
||||
new = _new |
||||
|
||||
inc :: forall eff. Counter -> Int -> Eff (ref :: REF | eff) Unit |
||||
inc c = runFn2 _inc c |
@ -0,0 +1,11 @@ |
||||
module System.Metrics.Gauge (Gauge, new, read) where |
||||
|
||||
import Control.Monad.Aff (Aff) |
||||
|
||||
newtype Gauge = Gauge (forall eff. Aff eff Int) |
||||
|
||||
new :: (forall eff. Aff eff Int) -> Gauge |
||||
new = Gauge |
||||
|
||||
read :: forall eff. Gauge -> Aff eff Int |
||||
read (Gauge f) = f |
@ -0,0 +1,60 @@ |
||||
var Histogram = require("metrics/metrics/histogram"); |
||||
|
||||
var clear = function(h) { |
||||
return function() { |
||||
h.clear(); |
||||
}; |
||||
}; |
||||
|
||||
var _update = function(h, v) { |
||||
return function() { |
||||
h.update(v); |
||||
}; |
||||
}; |
||||
|
||||
var _percentiles = function(h, ptiles) { |
||||
return function() { |
||||
var scoresM = h.percentiles(ptiles); |
||||
var scores = []; |
||||
for (var i = 0; i < ptiles.length; i++) { |
||||
scores.push(scoresM[ptiles[i]]); |
||||
} |
||||
if (scores[0]) { |
||||
return scores; |
||||
} |
||||
return null; |
||||
}; |
||||
}; |
||||
|
||||
var _variance = function(h) { return function() { return h.variance(); }; }; |
||||
var _mean = function(h) { return function() { return h.mean(); }; }; |
||||
var _stdDev = function(h) { return function() { return h.stdDev(); }; }; |
||||
var _min = function(h) { return function() { return h.min; }; }; |
||||
var _max = function(h) { return function() { return h.max; }; }; |
||||
var _sum = function(h) { return function() { return h.sum; }; }; |
||||
var count = function(h) { return function() { return h.count; }; }; |
||||
|
||||
var _newWithExponentialDecaySampling = function(size, alpha) { |
||||
return function() { |
||||
return Histogram.createExponentialDecayHistogram(size, alpha); |
||||
}; |
||||
}; |
||||
|
||||
var newWithUniformSampling = function(size) { |
||||
return function() { |
||||
return Histogram.createUniformHistogram(size); |
||||
}; |
||||
}; |
||||
|
||||
exports.clear = clear; |
||||
exports._update = _update; |
||||
exports._percentiles = _percentiles; |
||||
exports._variance = _variance; |
||||
exports._mean = _mean; |
||||
exports._stdDev = _stdDev; |
||||
exports._min = _min; |
||||
exports._max = _max; |
||||
exports._sum = _sum; |
||||
exports.count = count; |
||||
exports._newWithExponentialDecaySampling = _newWithExponentialDecaySampling; |
||||
exports.newWithUniformSampling = newWithUniformSampling; |
@ -0,0 +1,114 @@ |
||||
module System.Metrics.Histogram |
||||
( Histogram |
||||
, Summary |
||||
, newWithExponentialDecaySampling |
||||
, newWithUniformSampling |
||||
, clear |
||||
, update |
||||
, percentiles |
||||
, variance |
||||
, mean |
||||
, stdDev |
||||
, min |
||||
, max |
||||
, sum |
||||
, count |
||||
, read |
||||
) where |
||||
|
||||
import Control.Monad.Eff (Eff) |
||||
import Control.Monad.Eff.Ref (REF) |
||||
import Data.Array (index) |
||||
import Data.Function.Uncurried (Fn2, runFn2) |
||||
import Data.Generic.Rep (class Generic) |
||||
import Data.Generic.Rep.Show (genericShow) |
||||
import Data.Maybe (Maybe) |
||||
import Data.Nullable (Nullable, toMaybe) |
||||
import Prelude |
||||
|
||||
foreign import data Histogram :: Type |
||||
foreign import _newWithExponentialDecaySampling :: |
||||
forall eff. Fn2 Int Number (Eff (ref :: REF | eff) Histogram) |
||||
foreign import newWithUniformSampling :: |
||||
forall eff. Int -> Eff (ref :: REF | eff) Histogram |
||||
foreign import clear :: forall eff. Histogram -> Eff (ref :: REF | eff) Unit |
||||
foreign import _update :: forall eff. Fn2 Histogram Number (Eff (ref :: REF | eff) Unit) |
||||
foreign import _percentiles |
||||
:: forall eff. Fn2 Histogram (Array Number) (Eff (ref :: REF | eff) (Nullable (Array Number))) |
||||
foreign import _variance :: forall eff. Histogram -> Eff (ref :: REF | eff) (Nullable Number) |
||||
foreign import _mean :: forall eff. Histogram -> Eff (ref :: REF | eff) (Nullable Number) |
||||
foreign import _stdDev :: forall eff. Histogram -> Eff (ref :: REF | eff) (Nullable Number) |
||||
foreign import _min :: forall eff. Histogram -> Eff (ref :: REF | eff) (Nullable Number) |
||||
foreign import _max :: forall eff. Histogram -> Eff (ref :: REF | eff) (Nullable Number) |
||||
foreign import _sum :: forall eff. Histogram -> Eff (ref :: REF | eff) (Nullable Number) |
||||
foreign import count :: forall eff. Histogram -> Eff (ref :: REF | eff) Int |
||||
|
||||
newWithExponentialDecaySampling :: forall eff. Int -> Number -> Eff (ref :: REF | eff) Histogram |
||||
newWithExponentialDecaySampling = runFn2 _newWithExponentialDecaySampling |
||||
|
||||
update :: forall eff. Histogram -> Number -> Eff (ref :: REF | eff) Unit |
||||
update = runFn2 _update |
||||
|
||||
percentiles :: forall eff. Histogram -> Array Number -> Eff (ref :: REF | eff) (Maybe (Array Number)) |
||||
percentiles h ptiles = toMaybe <$> runFn2 _percentiles h ptiles |
||||
|
||||
variance :: forall eff. Histogram -> Eff (ref :: REF | eff) (Maybe Number) |
||||
variance h = toMaybe <$> _variance h |
||||
|
||||
mean :: forall eff. Histogram -> Eff (ref :: REF | eff) (Maybe Number) |
||||
mean h = toMaybe <$> _mean h |
||||
|
||||
stdDev :: forall eff. Histogram -> Eff (ref :: REF | eff) (Maybe Number) |
||||
stdDev h = toMaybe <$> _stdDev h |
||||
|
||||
min :: forall eff. Histogram -> Eff (ref :: REF | eff) (Maybe Number) |
||||
min h = toMaybe <$> _min h |
||||
|
||||
max :: forall eff. Histogram -> Eff (ref :: REF | eff) (Maybe Number) |
||||
max h = toMaybe <$> _max h |
||||
|
||||
sum :: forall eff. Histogram -> Eff (ref :: REF | eff) (Maybe Number) |
||||
sum h = toMaybe <$> _sum h |
||||
|
||||
newtype Summary = Summary { |
||||
min :: Maybe Number |
||||
, max :: Maybe Number |
||||
, sum :: Maybe Number |
||||
, variance :: Maybe Number |
||||
, mean :: Maybe Number |
||||
, stdDev :: Maybe Number |
||||
, count :: Int |
||||
, median :: Maybe Number |
||||
, p75 :: Maybe Number |
||||
, p95 :: Maybe Number |
||||
, p99 :: Maybe Number |
||||
, p999 :: Maybe Number |
||||
} |
||||
|
||||
derive instance eqSummary :: Eq Summary |
||||
derive instance genericSummary :: Generic Summary _ |
||||
instance showSummary :: Show Summary where |
||||
show = genericShow |
||||
|
||||
read :: forall eff. Histogram -> Eff (ref :: REF | eff) Summary |
||||
read h = do |
||||
ptiles <- percentiles h [0.5, 0.75, 0.95, 0.99, 0.999] |
||||
Summary <$> ({ min: _ |
||||
, max: _ |
||||
, sum: _ |
||||
, variance: _ |
||||
, mean: _ |
||||
, stdDev: _ |
||||
, count: _ |
||||
, median: ptiles >>= flip index 0 |
||||
, p75: ptiles >>= flip index 1 |
||||
, p95: ptiles >>= flip index 2 |
||||
, p99: ptiles >>= flip index 3 |
||||
, p999: ptiles >>= flip index 4 |
||||
} <$> min h |
||||
<*> max h |
||||
<*> sum h |
||||
<*> variance h |
||||
<*> mean h |
||||
<*> stdDev h |
||||
<*> count h) |
@ -0,0 +1,49 @@ |
||||
var Meter = require("metrics/metrics/meter"); |
||||
|
||||
var _new = function() { |
||||
return new Meter(); |
||||
}; |
||||
|
||||
var _markN = function(m, n) { |
||||
return function() { |
||||
m.mark(n); |
||||
}; |
||||
}; |
||||
|
||||
var fifteenMinuteRate = function(m) { |
||||
return function() { |
||||
return m.fifteenMinuteRate(); |
||||
}; |
||||
}; |
||||
|
||||
var fiveMinuteRate = function(m) { |
||||
return function() { |
||||
return m.fiveMinuteRate(); |
||||
}; |
||||
}; |
||||
|
||||
var oneMinuteRate = function(m) { |
||||
return function() { |
||||
return m.oneMinuteRate(); |
||||
}; |
||||
}; |
||||
|
||||
var meanRate = function(m) { |
||||
return function() { |
||||
return m.meanRate(); |
||||
}; |
||||
}; |
||||
|
||||
var count = function(m) { |
||||
return function() { |
||||
return m.count; |
||||
}; |
||||
}; |
||||
|
||||
exports._new = _new; |
||||
exports._markN = _markN; |
||||
exports.fifteenMinuteRate = fifteenMinuteRate; |
||||
exports.fiveMinuteRate = fiveMinuteRate; |
||||
exports.oneMinuteRate = oneMinuteRate; |
||||
exports.meanRate = meanRate; |
||||
exports.count = count; |
@ -0,0 +1,63 @@ |
||||
module System.Metrics.Meter |
||||
( Meter |
||||
, Summary |
||||
, new |
||||
, markN |
||||
, mark |
||||
, fifteenMinuteRate |
||||
, fiveMinuteRate |
||||
, oneMinuteRate |
||||
, meanRate |
||||
, count |
||||
, read |
||||
) where |
||||
|
||||
import Control.Monad.Eff (Eff) |
||||
import Control.Monad.Eff.Ref (REF) |
||||
import Data.Function.Uncurried (Fn2, runFn2) |
||||
import Data.Generic.Rep (class Generic) |
||||
import Data.Generic.Rep.Show (genericShow) |
||||
import Prelude (class Eq, class Show, Unit, (<$>), (<*>)) |
||||
|
||||
foreign import data Meter :: Type |
||||
foreign import _new :: forall eff. Eff (ref :: REF | eff) Meter |
||||
foreign import _markN :: forall eff. Fn2 Meter Int (Eff (ref :: REF | eff) Unit) |
||||
foreign import fifteenMinuteRate :: forall eff. Meter -> Eff (ref :: REF | eff) Number |
||||
foreign import fiveMinuteRate :: forall eff. Meter -> Eff (ref :: REF | eff) Number |
||||
foreign import oneMinuteRate :: forall eff. Meter -> Eff (ref :: REF | eff) Number |
||||
foreign import meanRate :: forall eff. Meter -> Eff (ref :: REF | eff) Number |
||||
foreign import count :: forall eff. Meter -> Eff (ref :: REF | eff) Int |
||||
|
||||
new :: forall eff. Eff (ref :: REF | eff) Meter |
||||
new = _new |
||||
|
||||
markN :: forall eff. Meter -> Int -> Eff (ref :: REF | eff) Unit |
||||
markN = runFn2 _markN |
||||
|
||||
mark :: forall eff. Meter -> Eff (ref :: REF | eff) Unit |
||||
mark m = markN m 1 |
||||
|
||||
newtype Summary = Summary { |
||||
count :: Int |
||||
, m1 :: Number |
||||
, m5 :: Number |
||||
, m15 :: Number |
||||
, mean :: Number |
||||
} |
||||
|
||||
derive instance eqSummary :: Eq Summary |
||||
derive instance genericSummary :: Generic Summary _ |
||||
instance showSummary :: Show Summary where |
||||
show = genericShow |
||||
|
||||
read :: forall eff. Meter -> Eff (ref :: REF | eff) Summary |
||||
read m = Summary <$> ({ count: _ |
||||
, m1: _ |
||||
, m5: _ |
||||
, m15: _ |
||||
, mean: _ |
||||
} <$> count m |
||||
<*> oneMinuteRate m |
||||
<*> fiveMinuteRate m |
||||
<*> fifteenMinuteRate m |
||||
<*> meanRate m) |
@ -0,0 +1,92 @@ |
||||
module System.Metrics.Timer |
||||
( Timer |
||||
, Summary |
||||
, new |
||||
, update |
||||
, fifteenMinuteRate |
||||
, fiveMinuteRate |
||||
, oneMinuteRate |
||||
, meanRate |
||||
, clear |
||||
, percentiles |
||||
, mean |
||||
, stdDev |
||||
, min |
||||
, max |
||||
, sum |
||||
, count |
||||
, read |
||||
) where |
||||
|
||||
import Prelude |
||||
|
||||
import Control.Monad.Eff (Eff) |
||||
import Control.Monad.Eff.Ref (REF) |
||||
import Data.Generic.Rep (class Generic) |
||||
import Data.Generic.Rep.Show (genericShow) |
||||
import Data.Maybe (Maybe) |
||||
import Data.Time.Duration (class Duration, Milliseconds(..), fromDuration) |
||||
import System.Metrics.Histogram (Histogram) |
||||
import System.Metrics.Histogram as Histogram |
||||
import System.Metrics.Meter (Meter) |
||||
import System.Metrics.Meter as Meter |
||||
|
||||
newtype Timer = Timer { meter :: Meter, histogram :: Histogram } |
||||
|
||||
new :: forall eff. Eff (ref :: REF | eff) Timer |
||||
new = Timer <$> ({ meter: _, histogram: _ } |
||||
<$> Meter.new |
||||
<*> Histogram.newWithExponentialDecaySampling 1028 0.015) |
||||
|
||||
update :: forall a eff. Duration a => Timer -> a -> Eff (ref :: REF | eff) Unit |
||||
update (Timer { meter, histogram }) d = do |
||||
let (Milliseconds ms) = fromDuration d |
||||
Histogram.update histogram ms |
||||
Meter.mark meter |
||||
|
||||
fifteenMinuteRate :: forall eff. Timer -> Eff (ref :: REF | eff) Number |
||||
fifteenMinuteRate (Timer { meter }) = Meter.fifteenMinuteRate meter |
||||
|
||||
fiveMinuteRate :: forall eff. Timer -> Eff (ref :: REF | eff) Number |
||||
fiveMinuteRate (Timer { meter }) = Meter.fiveMinuteRate meter |
||||
|
||||
oneMinuteRate :: forall eff. Timer -> Eff (ref :: REF | eff) Number |
||||
oneMinuteRate (Timer { meter }) = Meter.oneMinuteRate meter |
||||
|
||||
meanRate :: forall eff. Timer -> Eff (ref :: REF | eff) Number |
||||
meanRate (Timer { meter }) = Meter.meanRate meter |
||||
|
||||
clear :: forall eff. Timer -> Eff (ref :: REF | eff) Unit |
||||
clear (Timer { histogram }) = Histogram.clear histogram |
||||
|
||||
percentiles :: forall eff. Timer -> Array Number -> Eff (ref :: REF | eff) (Maybe (Array Number)) |
||||
percentiles (Timer { histogram }) = Histogram.percentiles histogram |
||||
|
||||
mean :: forall eff. Timer -> Eff (ref :: REF | eff) (Maybe Number) |
||||
mean (Timer { histogram }) = Histogram.mean histogram |
||||
|
||||
stdDev :: forall eff. Timer -> Eff (ref :: REF | eff) (Maybe Number) |
||||
stdDev (Timer { histogram }) = Histogram.stdDev histogram |
||||
|
||||
min :: forall eff. Timer -> Eff (ref :: REF | eff) (Maybe Number) |
||||
min (Timer { histogram }) = Histogram.min histogram |
||||
|
||||
max :: forall eff. Timer -> Eff (ref :: REF | eff) (Maybe Number) |
||||
max (Timer { histogram }) = Histogram.max histogram |
||||
|
||||
sum :: forall eff. Timer -> Eff (ref :: REF | eff) (Maybe Number) |
||||
sum (Timer { histogram }) = Histogram.sum histogram |
||||
|
||||
count :: forall eff. Timer -> Eff (ref :: REF | eff) Int |
||||
count (Timer { histogram }) = Histogram.count histogram |
||||
|
||||
newtype Summary = Summary { duration :: Histogram.Summary, rate :: Meter.Summary } |
||||
|
||||
derive instance eqSummary :: Eq Summary |
||||
derive instance genericSummary :: Generic Summary _ |
||||
instance showSummary :: Show Summary where |
||||
show = genericShow |
||||
|
||||
read :: forall eff. Timer -> Eff (ref :: REF | eff) Summary |
||||
read (Timer { meter, histogram }) = |
||||
Summary <$> ({ duration: _, rate: _} <$> Histogram.read histogram <*> Meter.read meter) |
Loading…
Reference in new issue