diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -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 ()
 
diff --git a/hnormalise.cabal b/hnormalise.cabal
--- a/hnormalise.cabal
+++ b/hnormalise.cabal
@@ -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
diff --git a/src/HNormalise.hs b/src/HNormalise.hs
--- a/src/HNormalise.hs
+++ b/src/HNormalise.hs
@@ -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,
diff --git a/src/HNormalise/Internal.hs b/src/HNormalise/Internal.hs
--- a/src/HNormalise/Internal.hs
+++ b/src/HNormalise/Internal.hs
@@ -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
diff --git a/src/HNormalise/Parser.hs b/src/HNormalise/Parser.hs
--- a/src/HNormalise/Parser.hs
+++ b/src/HNormalise/Parser.hs
@@ -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
diff --git a/src/HNormalise/Snoopy/Internal.hs b/src/HNormalise/Snoopy/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/HNormalise/Snoopy/Internal.hs
@@ -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)
diff --git a/src/HNormalise/Snoopy/Json.hs b/src/HNormalise/Snoopy/Json.hs
new file mode 100644
--- /dev/null
+++ b/src/HNormalise/Snoopy/Json.hs
@@ -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
diff --git a/src/HNormalise/Snoopy/Parser.hs b/src/HNormalise/Snoopy/Parser.hs
new file mode 100644
--- /dev/null
+++ b/src/HNormalise/Snoopy/Parser.hs
@@ -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
+        })
diff --git a/test/Bench.hs b/test/Bench.hs
--- a/test/Bench.hs
+++ b/test/Bench.hs
@@ -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
         ]
     ]
diff --git a/test/HNormalise/ParserSpec.hs b/test/HNormalise/ParserSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/HNormalise/ParserSpec.hs
@@ -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\"}}"
diff --git a/test/HNormalise/Snoopy/ParserSpec.hs b/test/HNormalise/Snoopy/ParserSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/HNormalise/Snoopy/ParserSpec.hs
@@ -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"
+                })
