packages feed

network-carbon (empty) → 1.0.0

raw patch · 5 files changed

+165/−0 lines, 5 filesdep +basedep +bytestringdep +networksetup-changed

Dependencies added: base, bytestring, network, text, time, vector

Files

+ Changelog.md view
@@ -0,0 +1,3 @@+## 1.0.0++* Initial release.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, Oliver Charles++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Oliver Charles nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ network-carbon.cabal view
@@ -0,0 +1,28 @@+name: network-carbon+version: 1.0.0+synopsis: A Haskell implementation of the Carbon protocol (part of the Graphite monitoring tools)+homepage: http://github.com/ocharles/network-carbon+license: BSD3+license-file: LICENSE+author: Oliver Charles+maintainer: ollie@ocharles.org.uk+build-type: Simple+cabal-version: >=1.10+extra-source-files: Changelog.md++library+  exposed-modules:+    Network.Carbon.Plaintext++  build-depends:+    base >=4.6 && <4.8,+    bytestring >=0.10.2.0 && <0.11,+    network >= 2.5.0.0 && < 2.6,+    text >= 1.1.1.3 && < 1.2,+    time >= 1.4.2 && < 1.5,+    vector >= 0.10.11.0 && < 0.11++  hs-source-dirs: src+  default-language: Haskell2010++  ghc-options: -Wall -O2 -fwarn-incomplete-uni-patterns
+ src/Network/Carbon/Plaintext.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE OverloadedStrings #-}+module Network.Carbon.Plaintext+  ( -- * Interacting with Carbon+    -- ** Connections+    Connection(..)+  , connect+  , disconnect++    -- ** Metrics+  , sendMetrics+  , sendMetric+  , Metric(..)++    -- * Protocol details+  , encodeMetric+  )+  where++import Control.Monad (unless)+import Data.Monoid ((<>), mempty, mappend)+import Data.Typeable (Typeable)++import qualified Data.ByteString.Builder as Builder+import qualified Data.Time as Time+import qualified Data.Time.Clock.POSIX as Time+import qualified Data.Vector as V+import qualified Data.Text as Text+import qualified Data.Text.Encoding as Text+import qualified Network.Socket as Network+import qualified Network.Socket.ByteString.Lazy as Network++--------------------------------------------------------------------------------+-- | Low-level representation of a Carbon connection. It's suggested that you+-- construct this via 'connect'. It is henceforth assumed that+-- 'Network.getPeerName' will return something useful, which usually means+-- 'connectionSocket' should have been 'Network.connect'ed at least once.+data Connection = Connection+  { connectionSocket :: !Network.Socket+    -- ^ The connection socket to Carbon.+  }+  deriving (Eq, Show, Typeable)+++--------------------------------------------------------------------------------+-- | Connect to Carbon.+connect :: Network.SockAddr -> IO Connection+connect sockAddr = fmap Connection $ do+  s <- Network.socket Network.AF_INET Network.Stream Network.defaultProtocol+  Network.connect s sockAddr+  return s+++--------------------------------------------------------------------------------+-- | Disconnect from Carbon. Note that it's still valid to 'sendMetrics' to this+-- 'Connection', and it will result in a reconnection.+disconnect :: Connection -> IO ()+disconnect (Connection s) = Network.close s+++--------------------------------------------------------------------------------+reconnect :: Connection -> IO ()+reconnect (Connection s) = do+  peer <- Network.getPeerName s+  Network.connect s peer+++--------------------------------------------------------------------------------+-- | A single data point. A metric has a path that names it, a value, and the+-- time the metric was sampled.+data Metric = Metric+  { metricPath :: !Text.Text+  , metricValue :: !Double+  , metricTimeStamp :: !Time.UTCTime+  }+  deriving (Eq, Show, Typeable)+++--------------------------------------------------------------------------------+-- | Send a collection of metrics to Carbon.+sendMetrics :: Connection -> V.Vector Metric -> IO ()+sendMetrics c ms = do+  let socket = connectionSocket c++  do isWritable <- Network.isWritable socket+     unless isWritable (reconnect c)++  Network.sendAll socket (Builder.toLazyByteString (V.foldl' mappend mempty (V.map encodeMetric ms)))++--------------------------------------------------------------------------------+-- | Send a single metric.+sendMetric :: Connection -> Text.Text -> Double -> Time.UTCTime -> IO ()+sendMetric c k v t = sendMetrics c (V.singleton (Metric k v t))+++--------------------------------------------------------------------------------+-- | Encode a 'Metric' for transmission over the plain text protocol.+encodeMetric :: Metric -> Builder.Builder+encodeMetric (Metric k v t) =+  Builder.byteString (Text.encodeUtf8 k) <> " " <>+  Builder.stringUtf8 (show v) <> " " <>+  Builder.stringUtf8 (show (round (Time.utcTimeToPOSIXSeconds t) :: Int)) <> "\n"