packages feed

otel-effectful-1.0.0: src/Effectful/OpenTelemetry/Logging/Severity.hs

module Effectful.OpenTelemetry.Logging.Severity (Severity (..), toJSON) where

import Data.Aeson.Types (ToJSON (..), Value (String))
import Data.Char (toLower)
import Data.Text qualified as Text
import GHC.Generics (Generic)
import Prettyprinter (Pretty (..), annotate)
import Prettyprinter.Extra (PrettyAnn (..))
import Prettyprinter.Render.Terminal (AnsiStyle, Color (..), color, colorDull)
import Proto3.Wire.Encode.Class qualified as Proto
import Prelude

-- | The severity of a log record.
-- Smaller values correspond to less severe events.
data Severity
    = -- | Fine-grained, highly verbose execution details.
      -- Typically used during active development or troubleshooting to track execution flow.
      -- Almost always disabled in production due to noise.
      Trace
    | Trace2
    | Trace3
    | Trace4
    | -- | Diagnostic event. Typically used for highlighting internal system events.
      Debug
    | Debug2
    | Debug3
    | Debug4
    | -- | Informational event. Typically used when something expected occurred.
      Info
    | Info2
    | Info3
    | Info4
    | -- | An unexpected event that may indicate potential future issues.
      Warn
    | Warn2
    | Warn3
    | Warn4
    | -- | An operation has failed, but the system can continue to run.
      Error
    | Error2
    | Error3
    | Error4
    | -- | An unrecoverable, terminal event that compromises the entire process.
      -- Indicates imminent crash or shutdown.
      Fatal
    | Fatal2
    | Fatal3
    | Fatal4
    deriving stock (Generic, Show, Eq, Ord, Bounded)

instance Read Severity where
    readsPrec _ s =
        [(it, "") | it <- [minBound .. maxBound], fmap toLower (show it) == fmap toLower s]

instance Enum Severity where
    toEnum 1 = Trace
    toEnum 2 = Trace2
    toEnum 3 = Trace3
    toEnum 4 = Trace4
    toEnum 5 = Debug
    toEnum 6 = Debug2
    toEnum 7 = Debug3
    toEnum 8 = Debug4
    toEnum 9 = Info
    toEnum 10 = Info2
    toEnum 11 = Info3
    toEnum 12 = Info4
    toEnum 13 = Warn
    toEnum 14 = Warn2
    toEnum 15 = Warn3
    toEnum 16 = Warn4
    toEnum 17 = Error
    toEnum 18 = Error2
    toEnum 19 = Error3
    toEnum 20 = Error4
    toEnum 21 = Fatal
    toEnum 22 = Fatal2
    toEnum 23 = Fatal3
    toEnum 24 = Fatal4
    toEnum _ = error "Enum.Severity.toEnum: bad argument"
    fromEnum Trace = 1
    fromEnum Trace2 = 2
    fromEnum Trace3 = 3
    fromEnum Trace4 = 4
    fromEnum Debug = 5
    fromEnum Debug2 = 6
    fromEnum Debug3 = 7
    fromEnum Debug4 = 8
    fromEnum Info = 9
    fromEnum Info2 = 10
    fromEnum Info3 = 11
    fromEnum Info4 = 12
    fromEnum Warn = 13
    fromEnum Warn2 = 14
    fromEnum Warn3 = 15
    fromEnum Warn4 = 16
    fromEnum Error = 17
    fromEnum Error2 = 18
    fromEnum Error3 = 19
    fromEnum Error4 = 20
    fromEnum Fatal = 21
    fromEnum Fatal2 = 22
    fromEnum Fatal3 = 23
    fromEnum Fatal4 = 24

instance ToJSON Severity where
    toJSON = String . Text.toUpper . Text.show

instance {-# OVERLAPPING #-} Proto.EncodeField Severity where
    encodeField n = Proto.int32 n . fromIntegral . fromEnum

instance PrettyAnn AnsiStyle Severity where
    prettyAnn severity =
        annotate colour . pretty . Text.justifyLeft 5 ' ' . Text.toUpper $
            Text.show severity
      where
        colour :: AnsiStyle
        colour
            | severity >= Error = color Red
            | severity >= Warn = color Yellow
            | severity >= Info = color Green
            | severity >= Debug = colorDull Blue
            | otherwise = color Magenta