packages feed

hnormalise 0.3.1.0 → 0.3.2.0

raw patch · 11 files changed

+249/−28 lines, 11 filesdep +deepseqPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: deepseq

API changes (from Hackage documentation)

- HNormalise.Internal: PR_H :: Huppel -> ParseResult
- HNormalise.Internal: PR_L :: LmodLoad -> ParseResult
- HNormalise.Internal: PR_S :: Shorewall -> ParseResult
- HNormalise.Internal: PR_T :: TorqueJobExit -> ParseResult
+ HNormalise.Internal: PR_Huppel :: Huppel -> ParseResult
+ HNormalise.Internal: PR_Lmod :: LmodLoad -> ParseResult
+ HNormalise.Internal: PR_Shorewall :: Shorewall -> ParseResult
+ HNormalise.Internal: PR_Snoopy :: Snoopy -> ParseResult
+ HNormalise.Internal: PR_Torque :: TorqueJobExit -> ParseResult
+ HNormalise.Snoopy.Internal: Snoopy :: !Int -> !Int -> !(Maybe Text) -> !Int -> !Text -> !Text -> !Text -> !Text -> Snoopy
+ HNormalise.Snoopy.Internal: [$sel:command:Snoopy] :: Snoopy -> !Text
+ HNormalise.Snoopy.Internal: [$sel:cwd:Snoopy] :: Snoopy -> !Text
+ HNormalise.Snoopy.Internal: [$sel:executable:Snoopy] :: Snoopy -> !Text
+ HNormalise.Snoopy.Internal: [$sel:pid:Snoopy] :: Snoopy -> !Int
+ HNormalise.Snoopy.Internal: [$sel:sid:Snoopy] :: Snoopy -> !Int
+ HNormalise.Snoopy.Internal: [$sel:tty:Snoopy] :: Snoopy -> !Text
+ HNormalise.Snoopy.Internal: [$sel:uid:Snoopy] :: Snoopy -> !Int
+ HNormalise.Snoopy.Internal: [$sel:username:Snoopy] :: Snoopy -> !(Maybe Text)
+ HNormalise.Snoopy.Internal: data Snoopy
+ HNormalise.Snoopy.Internal: instance GHC.Classes.Eq HNormalise.Snoopy.Internal.Snoopy
+ HNormalise.Snoopy.Internal: instance GHC.Generics.Generic HNormalise.Snoopy.Internal.Snoopy
+ HNormalise.Snoopy.Internal: instance GHC.Show.Show HNormalise.Snoopy.Internal.Snoopy
+ HNormalise.Snoopy.Json: instance Data.Aeson.Types.ToJSON.ToJSON HNormalise.Snoopy.Internal.Snoopy
+ HNormalise.Snoopy.Parser: parseSnoopy :: Parser (Text, Snoopy)

Files

app/Main.hs view
@@ -86,7 +86,7 @@                 loop             Just (Original l) -> do                 yield l $$ appSink failure-                yield (SBS.pack "\n") $$ appSink success+                yield (SBS.pack "\n") $$ appSink failure                 loop             Nothing -> return () 
hnormalise.cabal view
@@ -1,5 +1,5 @@ name:                hnormalise-version:             0.3.1.0+version:             0.3.2.0 synopsis:            Log message normalisation tool producing structured JSON messages description:         Log message normalisation tool producing structured JSON messages homepage:            https://github.com/itkovian/hnormalise#readme@@ -32,6 +32,9 @@                      , HNormalise.Shorewall.Internal                      , HNormalise.Shorewall.Json                      , HNormalise.Shorewall.Parser+                     , HNormalise.Snoopy.Internal+                     , HNormalise.Snoopy.Json+                     , HNormalise.Snoopy.Parser                      , HNormalise.Torque.Internal                      , HNormalise.Torque.Json                      , HNormalise.Torque.Parser@@ -79,9 +82,11 @@   type:                exitcode-stdio-1.0   hs-source-dirs:      test   main-is:             Spec.hs-  other-modules:     HNormalise.Common.ParserSpec+  other-modules:       HNormalise.ParserSpec+                     , HNormalise.Common.ParserSpec                      , HNormalise.Lmod.ParserSpec                      , HNormalise.Shorewall.ParserSpec+                     , HNormalise.Snoopy.ParserSpec                      , HNormalise.Torque.ParserSpec   build-depends:       base                      , aeson@@ -104,8 +109,10 @@   hs-source-dirs:      test   main-is:             Bench.hs   build-depends:       base+                     , aeson                      , attoparsec                      , criterion+                     , deepseq                      , hnormalise                      , random                      , text
src/HNormalise.hs view
@@ -19,6 +19,7 @@ import qualified Data.ByteString.Char8      as SBS import qualified Data.ByteString.Lazy.Char8 as BS import           Data.Text                  (Text, empty)+import           Data.Text.Encoding         (encodeUtf8) import           Data.Text.Lazy             (toStrict)  --------------------------------------------------------------------------------@@ -62,7 +63,7 @@                             _        -> original         _           -> original   where-    original = Original $ BS.toStrict $ Aeson.encode $ logLine+    original = Original $ encodeUtf8 $ logLine  -------------------------------------------------------------------------------- -- | The 'convertMessage' function transforms the actual message to a 'Maybe' 'ParseResult'. If parsing fails,
src/HNormalise/Internal.hs view
@@ -19,27 +19,32 @@ import           HNormalise.Lmod.Json import           HNormalise.Shorewall.Internal (Shorewall) import           HNormalise.Shorewall.Json+import           HNormalise.Snoopy.Internal (Snoopy)+import           HNormalise.Snoopy.Json import           HNormalise.Torque.Internal (TorqueJobExit) import           HNormalise.Torque.Json  -------------------------------------------------------------------------------- data ParseResult     -- | 'Huppel' Result for testing purposes, should you want to check the pipeline works without pushing in actual data-    = PR_H Huppel+    = PR_Huppel Huppel     -- | Represents a parsed 'LmodLoad' message-    | PR_L LmodLoad+    | PR_Lmod LmodLoad     -- | Represents a parsed 'Shorewall' message-    | PR_S Shorewall+    | PR_Shorewall Shorewall+    -- | Represents a parsed 'Snoopy' message+    | PR_Snoopy Snoopy     -- | Represents a parsed 'TorqueJobExit' message-    | PR_T TorqueJobExit+    | PR_Torque TorqueJobExit     deriving  (Show, Eq, Generic)  -------------------------------------------------------------------------------- instance ToJSON ParseResult where-    toEncoding (PR_H v) = toEncoding v-    toEncoding (PR_L v) = toEncoding v-    toEncoding (PR_S v) = toEncoding v-    toEncoding (PR_T v) = toEncoding v+    toEncoding (PR_Huppel v) = toEncoding v+    toEncoding (PR_Lmod v) = toEncoding v+    toEncoding (PR_Shorewall v) = toEncoding v+    toEncoding (PR_Snoopy v) = toEncoding v+    toEncoding (PR_Torque v) = toEncoding v  -------------------------------------------------------------------------------- data Rsyslog = Rsyslog
src/HNormalise/Parser.hs view
@@ -23,6 +23,7 @@ import           HNormalise.Json import           HNormalise.Lmod.Parser import           HNormalise.Shorewall.Parser+import           HNormalise.Snoopy.Parser import           HNormalise.Torque.Parser -------------------------------------------------------------------------------- rsyslogLogstashTemplate = "<%PRI%>1 %timegenerated:::date-rfc3339% %HOSTNAME% %syslogtag% - %APP-NAME%: %msg:::drop-last-lf%\n"@@ -31,17 +32,19 @@ -- | The 'parseMessage' function will try and use each configured parser to normalise the input it's given parseMessage :: Parser (Text, ParseResult) parseMessage =-        (parseLmodLoad >>= (\(a, v) -> return $ (a, PR_L v)))-    <|> (parseShorewall >>= (\(a, v) -> return $ (a, PR_S v)))-    <|> (parseTorqueExit >>= (\(a, v) -> return $ (a, PR_T v)))+        (parseLmodLoad   >>= (\(a, v) -> return $ (a, PR_Lmod v)))+    <|> (parseShorewall  >>= (\(a, v) -> return $ (a, PR_Shorewall v)))+    <|> (parseSnoopy     >>= (\(a, v) -> return $ (a, PR_Snoopy v)))+    <|> (parseTorqueExit >>= (\(a, v) -> return $ (a, PR_Torque v)))  -------------------------------------------------------------------------------- -- | The 'getJsonKey' function return the key under which the normalised message should appear when JSON is produced getJsonKey :: ParseResult -> Text-getJsonKey (PR_H _) = "huppel"-getJsonKey (PR_L _) = "lmod"-getJsonKey (PR_T _) = "torque"-getJsonKey (PR_S _) = "shorewall"+getJsonKey (PR_Huppel _) = "huppel"+getJsonKey (PR_Lmod _) = "lmod"+getJsonKey (PR_Torque _) = "torque"+getJsonKey (PR_Shorewall _) = "shorewall"+getJsonKey (PR_Snoopy _) = "snoopy"  -------------------------------------------------------------------------------- -- | The 'parseRsyslogLogstashString' currently is a placeholder function that will convert the incoming rsyslog message
+ src/HNormalise/Snoopy/Internal.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE DeriveGeneric             #-}+{-# LANGUAGE DuplicateRecordFields     #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE OverloadedStrings         #-}++module HNormalise.Snoopy.Internal where+++--------------------------------------------------------------------------------+import           Data.Aeson                 (FromJSON, ToJSON, toEncoding,+                                             toJSON)+import           Data.Text+import           GHC.Generics               (Generic)++--------------------------------------------------------------------------------+import           HNormalise.Common.Internal+-- snoopy[27316]::  [uid:110 sid:9379 tty:(none) cwd:/ filename:/usr/lib64/nagios/plugins/hpc/check_ifutil.pl]: /usr/lib64/nagios/plugins/hpc/check_ifutil.pl -i em1.295 -w 90 -c 95 -p -b 10000m+data Snoopy = Snoopy+    { pid        :: !Int+    , uid        :: !Int+    , username   :: !(Maybe Text)+    , sid        :: !Int+    , tty        :: !Text+    , cwd        :: !Text+    , executable :: !Text+    , command    :: !Text+    } deriving (Show, Eq, Generic)
+ src/HNormalise/Snoopy/Json.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE OverloadedStrings  #-}++module HNormalise.Snoopy.Json where++--------------------------------------------------------------------------------+import           Control.Monad+import           Data.Aeson+import           Data.Monoid++--------------------------------------------------------------------------------+import           HNormalise.Common.Json+import           HNormalise.Snoopy.Internal++--------------------------------------------------------------------------------+instance ToJSON Snoopy where+    toEncoding = genericToEncoding defaultOptions
+ src/HNormalise/Snoopy/Parser.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE DeriveDataTypeable    #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE OverloadedStrings     #-}++module HNormalise.Snoopy.Parser where++--------------------------------------------------------------------------------+import           Control.Applicative        ((<|>))+import           Data.Attoparsec.Combinator (lookAhead, manyTill)+import           Data.Attoparsec.Text+import           Data.Char                  (isSpace)+import           Data.Text                  (Text)++--------------------------------------------------------------------------------+import           HNormalise.Common.Parser+import           HNormalise.Snoopy.Internal++--------------------------------------------------------------------------------+-- snoopy[27316]::  [uid:110 sid:9379 tty:(none) cwd:/ filename:/usr/lib64/nagios/plugins/hpc/check_ifutil.pl]: /usr/lib64/nagios/plugins/hpc/check_ifutil.pl -i em1.295 -w 90 -c 95 -p -b 10000m+parseSnoopy :: Parser (Text, Snoopy)+parseSnoopy = do+    string "snoopy["+    pid <- decimal+    takeTill ( == '[') *> char '['+    uid <- string "uid:" *> decimal+    username <- maybeOption $ skipSpace *> string "username:" *> takeTill isSpace+    sid <- skipSpace *> string "sid:" *> decimal+    tty <- skipSpace *> string "tty:" *> takeTill isSpace+    cwd <- skipSpace *> string "cwd:" *> takeTill isSpace+    executable <- skipSpace *> "filename:" *> takeTill ( == ']')+    string "]:"+    command <- skipSpace *> takeText+    return $ ("snoopy", Snoopy+        { pid = pid+        , uid = uid+        , username = username+        , sid = sid+        , tty = tty+        , cwd = cwd+        , executable = executable+        , command = command+        })
test/Bench.hs view
@@ -5,14 +5,22 @@ module Main where  --------------------------------------------------------------------------------+import           Control.DeepSeq import           Criterion.Main-import qualified Data.Attoparsec.Text      as AT-import           Data.Text                 (Text)+import qualified Data.Aeson                   as Aeson+import qualified Data.Attoparsec.Text         as AT+import           Data.Text                    (Text) ---------------------------------------------------------------------------------import qualified HNormalise.Lmod.Parser  as LmodP+import qualified HNormalise.Lmod.Parser       as LmodP import qualified HNormalise.Shorewall.Parser  as ShorewallP-import qualified HNormalise.Torque.Parser  as TorqueP+import qualified HNormalise.Snoopy.Parser     as SnoopyP+import qualified HNormalise.Torque.Parser     as TorqueP+import qualified HNormalise                   as H +--------------------------------------------------------------------------------+instance NFData H.Normalised where+    rnf (H.Transformed s) = rnf s+    rnf (H.Original s) = rnf s  -------------------------------------------------------------------------------- torqueJobExitInput1 = "04/05/2017 13:06:53;E;45.master23.banette.gent.vsc;user=vsc40075 group=vsc40075 jobname=STDIN queue=short ctime=1491390300 qtime=1491390300 etime=1491390300 start=1491390307 owner=vsc40075@gligar01.gligar.gent.vsc exec_host=node2801.banette.gent.vsc/0-1+node2803.banette.gent.vsc/0-1 Resource_List.nodes=node2801.banette.gent.vsc:ppn=2+node2803.banette.gent.vsc:ppn=2 Resource_List.vmem=1gb Resource_List.nodect=2 Resource_List.neednodes=node2801.banette.gent.vsc:ppn=2+node2803.banette.gent.vsc:ppn=2 Resource_List.nice=0 Resource_List.walltime=01:00:00 session=15273 total_execution_slots=4 unique_node_count=2 end=1491390413 Exit_status=0 resources_used.cput=0 resources_used.energy_used=0 resources_used.mem=55048kb resources_used.vmem=92488kb resources_used.walltime=00:01:44" :: Text@@ -21,25 +29,35 @@ torqueJobExitFailInput1 = "04/05/2017 13:06:53;E;45.master23.banette.gent.vsc;user=vsc40075 group=vsc40075 jobname=STDIN queue=short HUPPEL"  lmodLoadInput1 = "lmod::  username=myuser, cluster=mycluster, jobid=3230905.master.mycluster.mydomain, userload=yes, module=GSL/2.3-intel-2016b, fn=/apps/gent/CO7/sandybridge/modules/all/GSL/2.3-intel-2016b" :: Text+fullLmodInput = "<13>1 2016-06-07T17:50:22.495571+02:00 node2159 lmod: - lmod:: username=vsc40307, cluster=delcatty, jobid=434.master16.delcatty.gent.vsc, userload=no, module=binutils/2.25-GCCcore-4.9.3, fn=/apps/gent/SL6/sandybridge/modules/all/binutils/2.25-GCCcore-4.9.3" :: Text  shorewallTCPInput = "kernel:: Shorewall:ext2fw:REJECT:IN=em3 OUT= MAC=aa:aa:bb:ff:88:bc:bc:15:80:8b:f8:f8:80:00 SRC=78.0.0.1 DST=150.0.0.1 LEN=52 TOS=0x00 PREC=0x00 TTL=117 ID=7564 DF PROTO=TCP SPT=60048 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0" shorewallUDPInput = "kernel:: Shorewall:ipmi2int:REJECT:IN=em4 OUT=em1 SRC=10.0.0.2 DST=10.0.0.1 LEN=57 TOS=0x00 PREC=0x00 TTL=63 ID=62392 PROTO=UDP SPT=57002 DPT=53 LEN=37" shorewallICMPInput = "kernel:: Shorewall:ipmi2ext:REJECT:IN=em4 OUT=em3 SRC=10.0.0.2 DST=10.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=63 ID=36216 PROTO=ICMP TYPE=8 CODE=0 ID=0 SEQ=1421" +snoopyInput = "snoopy[27316]::  [uid:110 sid:9379 tty:(none) cwd:/ filename:/usr/lib64/nagios/plugins/hpc/check_ifutil.pl]: /usr/lib64/nagios/plugins/hpc/check_ifutil.pl -i em1.295 -w 90 -c 95 -p -b 10000m" :: Text+fullSnoopyInput = "<86>1 2015-12-20T09:59:40.844711+01:00 gligar03 snoopy[46513]: - snoopy[46513]:: [uid:2540337 sid:19403 tty:ERROR(ttyname_r->EUNKNOWN) cwd:/vscmnt/gent_vulpix/_/user/home/gent/vsc403/vsc40337/UCS_LABELLED_NEW/20000_to_30000 filename:/usr/bin/qsub]: qsub -l walltime=72:00:00 job7_21293_30000_doit" :: Text++ -------------------------------------------------------------------------------- main :: IO () main = defaultMain-    [ bgroup "torque"+    [ bgroup "parse torque"         [ bench "jobexit full resource node list"  $ whnf (AT.parse TorqueP.parseTorqueExit) torqueJobExitInput1         , bench "jobexit short resource node number"  $ whnf (AT.parse TorqueP.parseTorqueExit) torqueJobExitInput1         , bench "jobexit borked input"  $ whnf (AT.parse TorqueP.parseTorqueExit) torqueJobExitFailInput1         ]-    , bgroup "lmod"-        [ bench "lmod successfull module load parse" $ whnf (AT.parse LmodP.parseLmodLoad) lmodLoadInput1-        ]-    , bgroup "shorewall"+    , bgroup "parse lmod"+        [ bench "lmod successfull module load parse" $ whnf (AT.parse LmodP.parseLmodLoad) lmodLoadInput1]+    , bgroup "parse shorewall"         [ bench "tcp successfull input" $ whnf (AT.parse ShorewallP.parseShorewallTCP) shorewallTCPInput         , bench "udp successfull input" $ whnf (AT.parse ShorewallP.parseShorewallUDP) shorewallUDPInput         , bench "icmp successfull input" $ whnf (AT.parse ShorewallP.parseShorewallICMP) shorewallICMPInput+        ]+    , bgroup "parse snoopy"+        [ bench "successfull input" $ whnf (AT.parse SnoopyP.parseSnoopy) snoopyInput]+    , bgroup "normaliseText"+        [ bench "snoopy" $ nf H.normaliseText fullSnoopyInput+        , bench "lmod" $ nf H.normaliseText fullLmodInput         ]     ]
+ test/HNormalise/ParserSpec.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE OverloadedStrings     #-}++module HNormalise.ParserSpec (main, spec) where++--------------------------------------------------------------------------------+import           Data.Text                 (Text)+import qualified Data.Text.Read            as TR+import           Test.Hspec+import           Test.Hspec.Attoparsec+import qualified Net.IPv4                  as NT++--------------------------------------------------------------------------------+import           HNormalise.Common.Internal+import           HNormalise.Lmod.Internal+import           HNormalise.Internal+import           HNormalise.Parser+--------------------------------------------------------------------------------+main :: IO ()+main = hspec spec++--------------------------------------------------------------------------------+spec :: Spec+spec = do+    describe "parse full rsyslog message" $ do+        it "lmod load" $ do+            let s = "<13>1 2016-06-07T17:50:22.658452+02:00 node2159 lmod: - lmod:: username=myuser, cluster=dmycluster, jobid=434.master.mycluster.mydomain, userload=yes, module=intel/2016a, fn=/apps/gent/SL6/sandybridge/modules/all/intel/2016" :: Text+            s ~> parseRsyslogLogstashString `shouldParse`+                "{\"message\":\"lmod:: username=myuser, cluster=dmycluster, jobid=434.master.mycluster.mydomain, userload=yes, module=intel/2016a, fn=/apps/gent/SL6/sandybridge/modules/all/intel/2016\",\"syslog_abspri\":\"\",\"program\":\"lmod\",\"lmod\":{\"info\":{\"username\":\"myuser\",\"cluster\":\"dmycluster\",\"jobid\":\"434.master.mycluster.mydomain\"},\"userload\":true,\"module\":{\"name\":\"intel\",\"version\":\"2016a\"},\"filename\":\"/apps/gent/SL6/sandybridge/modules/all/intel/2016\"}}"++        it "imfile torque input" $ do+            let s = "<133>1 2017-05-24T18:01:53.367275+02:00 test2802 torque - torque: 01/25/2017 15:04:10;E;0.master23.banette.gent.vsc;user=vsc40075 group=vsc40075 jobname=STDIN queue=short ctime=1485350399 qtime=1485350399 etime=1485350399 start=1485350407 owner=vsc40075@gligar03.gligar.gent.vsc exec_host=node2801.banette.gent.vsc/0 Resource_List.walltime=01:00:00 Resource_List.vmem=4224531456b Resource_List.nodect=1 Resource_List.nodes=1 Resource_List.neednodes=1 Resource_List.nice=0 session=22598 total_execution_slots=1 unique_node_count=1 end=1485353050 Exit_status=265 resources_used.cput=0 resources_used.energy_used=0 resources_used.mem=31032kb resources_used.vmem=1541612kb resources_used.walltime=00:44:04" :: Text+            s ~> parseRsyslogLogstashString `shouldParse` "{\"message\":\"torque: 01/25/2017 15:04:10;E;0.master23.banette.gent.vsc;user=vsc40075 group=vsc40075 jobname=STDIN queue=short ctime=1485350399 qtime=1485350399 etime=1485350399 start=1485350407 owner=vsc40075@gligar03.gligar.gent.vsc exec_host=node2801.banette.gent.vsc/0 Resource_List.walltime=01:00:00 Resource_List.vmem=4224531456b Resource_List.nodect=1 Resource_List.nodes=1 Resource_List.neednodes=1 Resource_List.nice=0 session=22598 total_execution_slots=1 unique_node_count=1 end=1485353050 Exit_status=265 resources_used.cput=0 resources_used.energy_used=0 resources_used.mem=31032kb resources_used.vmem=1541612kb resources_used.walltime=00:44:04\",\"syslog_abspri\":\"\",\"program\":\"torque\",\"torque\":{\"name\":{\"number\":0,\"array_id\":null,\"master\":\"master23\",\"cluster\":\"banette\"},\"user\":\"vsc40075\",\"group\":\"vsc40075\",\"jobname\":\"STDIN\",\"queue\":\"short\",\"startCount\":null,\"owner\":\"vsc40075@gligar03.gligar.gent.vsc\",\"session\":22598,\"times\":{\"ctime\":1485350399,\"qtime\":1485350399,\"etime\":1485350399,\"startTime\":1485350407,\"endTime\":1485353050},\"resourceRequest\":{\"mem\":null,\"advres\":null,\"naccesspolicy\":null,\"ncpus\":null,\"neednodes\":{\"Left\":{\"number\":1,\"ppn\":null}},\"nice\":0,\"nodeCount\":1,\"nodes\":{\"Left\":{\"number\":1,\"ppn\":null}},\"select\":null,\"qos\":null,\"pmem\":null,\"vmem\":4224531456,\"pvmem\":null,\"walltime\":{\"days\":0,\"hours\":1,\"minutes\":0,\"seconds\":0}},\"resourceUsage\":{\"cputime\":0,\"energy\":0,\"mem\":31776768,\"vmem\":1578610688,\"walltime\":{\"days\":0,\"hours\":0,\"minutes\":44,\"seconds\":4}},\"totalExecutionSlots\":1,\"uniqueNodeCount\":1,\"exitStatus\":265}}"++        it "snoopy with process ID" $ do+            let s = "<86>1 2017-05-29T16:40:48.275334+02:00 master23 snoopy[28949]: - snoopy[28949]::  [uid:992 username:nrpe sid:11542 tty:(none) cwd:/ filename:/usr/bin/which]: which python" :: Text+            s ~> parseRsyslogLogstashString `shouldParse` "{\"message\":\"snoopy[28949]::  [uid:992 username:nrpe sid:11542 tty:(none) cwd:/ filename:/usr/bin/which]: which python\",\"syslog_abspri\":\"\",\"program\":\"snoopy\",\"snoopy\":{\"pid\":28949,\"uid\":992,\"username\":\"nrpe\",\"sid\":11542,\"tty\":\"(none)\",\"cwd\":\"/\",\"executable\":\"/usr/bin/which\",\"command\":\"which python\"}}"
+ test/HNormalise/Snoopy/ParserSpec.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE OverloadedStrings     #-}++module HNormalise.Snoopy.ParserSpec (main, spec) where++--------------------------------------------------------------------------------+import           Data.Text                 (Text)+import qualified Data.Text.Read            as TR+import           Test.Hspec+import           Test.Hspec.Attoparsec+import qualified Net.IPv4                  as NT++--------------------------------------------------------------------------------+import           HNormalise.Common.Internal+import           HNormalise.Snoopy.Internal+import           HNormalise.Snoopy.Parser+--------------------------------------------------------------------------------+main :: IO ()+main = hspec spec++--------------------------------------------------------------------------------+spec :: Spec+spec = do+    describe "Snoopy" $ do+        it "regular entry" $ do+            let s = "snoopy[27316]::  [uid:110 sid:9379 tty:(none) cwd:/ filename:/usr/lib64/nagios/plugins/hpc/check_ifutil.pl]: /usr/lib64/nagios/plugins/hpc/check_ifutil.pl -i em1.295 -w 90 -c 95 -p -b 10000m" :: Text+            s ~> parseSnoopy `shouldParse` ("snoopy", Snoopy+                { pid = 27316+                , uid = 110+                , username = Nothing+                , sid = 9379+                , tty = "(none)"+                , cwd = "/"+                , executable = "/usr/lib64/nagios/plugins/hpc/check_ifutil.pl"+                , command = "/usr/lib64/nagios/plugins/hpc/check_ifutil.pl -i em1.295 -w 90 -c 95 -p -b 10000m"+                })++        it "regular entry" $ do+            let s = "snoopy[46513]:: [uid:2540337 sid:19403 tty:ERROR(ttyname_r->EUNKNOWN) cwd:/vscmnt/gent_vulpix/_/user/home/gent/vsc403/vsc40337/UCS_LABELLED_NEW/20000_to_30000 filename:/usr/bin/qsub]: qsub -l walltime=72:00:00 job7_21293_30000_doit" :: Text+            s ~> parseSnoopy `shouldParse` ("snoopy", Snoopy+                { pid = 46513+                , uid = 2540337+                , username = Nothing+                , sid = 19403+                , tty = "ERROR(ttyname_r->EUNKNOWN)"+                , cwd = "/vscmnt/gent_vulpix/_/user/home/gent/vsc403/vsc40337/UCS_LABELLED_NEW/20000_to_30000"+                , executable = "/usr/bin/qsub"+                , command = "qsub -l walltime=72:00:00 job7_21293_30000_doit"+                })++        it "failing" $ do+            let s = "snoopy[28949]::  [uid:992 username:nrpe sid:11542 tty:(none) cwd:/ filename:/usr/bin/which]: which python" :: Text+            s ~> parseSnoopy `shouldParse` ("snoopy", Snoopy+                { pid = 28949+                , uid = 992+                , username = Just "nrpe"+                , sid = 11542+                , tty = "(none)"+                , cwd = "/"+                , executable = "/usr/bin/which"+                , command = "which python"+                })