on master help sign in
Add katip-elasticsearch style key annotation to logzio scribe

logzio is hosted kibana, so this is just as necessary as it is in elasticsearch, so it is a necessary feature.

commit4f48dbeb7549bee33b073bbdbfa5cd8dd42f3cb1 authorMichael Xavier <michael@michaelxavier.net> dateTue 22 Jan 2019, 13:42 (8 years ago) parente0cfc85
2 files changed+53−1
katip-logzio/katip-logzio.cabal+1 katip-logzio/src/Katip/Scribes/LogzIO/HTTPS.hs+52−1
katip-logzio/katip-logzio.cabal+1
@@ -47,6 +47,7 @@ library
4747 , http-types
4848 , text
4949 , bytestring
50+ , scientific
5051 hs-source-dirs: src
5152 default-language: Haskell2010
5253 hs-source-dirs: src
katip-logzio/src/Katip/Scribes/LogzIO/HTTPS.hs+52−1
@@ -49,6 +49,7 @@ import qualified Data.ByteString.Lazy as LBS
4949import qualified Data.ByteString.Lazy.Char8 as LBS8
5050import qualified Data.HashMap.Strict as HM
5151import Data.Int
52+import qualified Data.Scientific as Scientific
5253import Data.String (IsString)
5354import qualified Data.Text as T
5455import qualified Data.Text.Encoding as TE
@@ -472,7 +473,7 @@ fullItemObject verbosity item = HM.fromList
472473 , "thread" A..= K.getThreadIdText (K._itemThread item)
473474 , "host" A..= K._itemHost item
474475 , "pid" A..= pidInt
475− , "data" A..= K.payloadObject verbosity (K._itemPayload item)
476+ , "data" A..= annotateKeys (K.payloadObject verbosity (K._itemPayload item))
476477 -- Slight deviation, logz.io uses "message" instead of "msg"
477478 , "message" A..= TB.toLazyText (K.unLogStr (K._itemMessage item))
478479 -- Another slight deviation, logz.io uses "@timestamp" instead of
@@ -617,3 +618,53 @@ bufferItem' customMaxPayload customMaxItem maxItems verb item bulkBuffer =
617618-- will always return 'FlushNow' with an empty new buffer.
618619forceFlush :: (Monoid buf) => buf -> LogAction buf
619620forceFlush buf = FlushNow buf mempty
621+
622+
623+-------------------------------------------------------------------------------
624+-- Annotation borrowed from katip-elasticsearch. There are fixed
625+-- fields in katip logs which should stay the same type forever and
626+-- thus won't need annotation. However, any code in userland may
627+-- choose to add akey to their log's metadata with a type that's
628+-- incompatible with the mapping. If the first value that's picked up
629+-- restrictive (e.g. a long), subsequent values will be rejected. By
630+-- differentiating types by their name, this is guaranteed not to
631+-- happen.
632+
633+annotateValue :: A.Value -> A.Value
634+annotateValue (A.Object o) = A.Object (annotateKeys o)
635+annotateValue (A.Array a) = A.Array (annotateValue <$> a)
636+annotateValue x = x
637+
638+
639+annotateKeys :: A.Object -> A.Object
640+annotateKeys = HM.fromList . map go . HM.toList
641+ where
642+ go (k, A.Object o) = (k, A.Object (annotateKeys o))
643+ go (k, A.Array a) = (k, A.Array (annotateValue <$> a))
644+ go (k, s@(A.String _)) = (k <> stringAnn, s)
645+ go (k, n@(A.Number sci)) = if Scientific.isFloating sci
646+ then (k <> doubleAnn, n)
647+ else (k <> longAnn, n)
648+ go (k, b@(A.Bool _)) = (k <> booleanAnn, b)
649+ go (k, A.Null) = (k <> nullAnn, A.Null)
650+
651+
652+-------------------------------------------------------------------------------
653+-- Annotation Constants
654+-------------------------------------------------------------------------------
655+
656+
657+stringAnn :: T.Text
658+stringAnn = "::s"
659+
660+doubleAnn :: T.Text
661+doubleAnn = "::d"
662+
663+longAnn :: T.Text
664+longAnn = "::l"
665+
666+booleanAnn :: T.Text
667+booleanAnn = "::b"
668+
669+nullAnn :: T.Text
670+nullAnn = "::n"