packages feed

sbp-6.2.2: src/SwiftNav/SBP/Linux.hs

{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# LANGUAGE NoImplicitPrelude           #-}
{-# LANGUAGE TemplateHaskell             #-}
{-# LANGUAGE RecordWildCards             #-}

-- |
-- Module:      SwiftNav.SBP.Linux
-- Copyright:   Copyright (C) 2015-2021 Swift Navigation, Inc.
-- License:     MIT
-- Contact:     https://support.swiftnav.com
-- Stability:   experimental
-- Portability: portable
--
-- \< Linux state monitoring. \>

module SwiftNav.SBP.Linux
  ( module SwiftNav.SBP.Linux
  ) where

import BasicPrelude
import Control.Lens
import Control.Monad.Loops
import Data.Binary
import Data.Binary.Get
import Data.Binary.IEEE754
import Data.Binary.Put
import Data.ByteString.Lazy    hiding (ByteString)
import Data.Int
import Data.Word
import SwiftNav.SBP.TH
import SwiftNav.SBP.Types

{-# ANN module ("HLint: ignore Use camelCase"::String) #-}
{-# ANN module ("HLint: ignore Redundant do"::String) #-}
{-# ANN module ("HLint: ignore Use newtype instead of data"::String) #-}


msgLinuxCpuStateDepA :: Word16
msgLinuxCpuStateDepA = 0x7F00

-- | SBP class for message MSG_LINUX_CPU_STATE_DEP_A (0x7F00).
--
-- Deprecated.
data MsgLinuxCpuStateDepA = MsgLinuxCpuStateDepA
  { _msgLinuxCpuStateDepA_index :: !Word8
    -- ^ sequence of this status message, values from 0-9
  , _msgLinuxCpuStateDepA_pid   :: !Word16
    -- ^ the PID of the process
  , _msgLinuxCpuStateDepA_pcpu  :: !Word8
    -- ^ percent of cpu used, expressed as a fraction of 256
  , _msgLinuxCpuStateDepA_tname :: !Text
    -- ^ fixed length string representing the thread name
  , _msgLinuxCpuStateDepA_cmdline :: !Text
    -- ^ the command line (as much as it fits in the remaining packet)
  } deriving ( Show, Read, Eq )

instance Binary MsgLinuxCpuStateDepA where
  get = do
    _msgLinuxCpuStateDepA_index <- getWord8
    _msgLinuxCpuStateDepA_pid <- getWord16le
    _msgLinuxCpuStateDepA_pcpu <- getWord8
    _msgLinuxCpuStateDepA_tname <- decodeUtf8 <$> getByteString 15
    _msgLinuxCpuStateDepA_cmdline <- decodeUtf8 . toStrict <$> getRemainingLazyByteString
    pure MsgLinuxCpuStateDepA {..}

  put MsgLinuxCpuStateDepA {..} = do
    putWord8 _msgLinuxCpuStateDepA_index
    putWord16le _msgLinuxCpuStateDepA_pid
    putWord8 _msgLinuxCpuStateDepA_pcpu
    putByteString $ encodeUtf8 _msgLinuxCpuStateDepA_tname
    putByteString $ encodeUtf8 _msgLinuxCpuStateDepA_cmdline

$(makeSBP 'msgLinuxCpuStateDepA ''MsgLinuxCpuStateDepA)
$(makeJSON "_msgLinuxCpuStateDepA_" ''MsgLinuxCpuStateDepA)
$(makeLenses ''MsgLinuxCpuStateDepA)

msgLinuxMemStateDepA :: Word16
msgLinuxMemStateDepA = 0x7F01

-- | SBP class for message MSG_LINUX_MEM_STATE_DEP_A (0x7F01).
--
-- Deprecated.
data MsgLinuxMemStateDepA = MsgLinuxMemStateDepA
  { _msgLinuxMemStateDepA_index :: !Word8
    -- ^ sequence of this status message, values from 0-9
  , _msgLinuxMemStateDepA_pid   :: !Word16
    -- ^ the PID of the process
  , _msgLinuxMemStateDepA_pmem  :: !Word8
    -- ^ percent of memory used, expressed as a fraction of 256
  , _msgLinuxMemStateDepA_tname :: !Text
    -- ^ fixed length string representing the thread name
  , _msgLinuxMemStateDepA_cmdline :: !Text
    -- ^ the command line (as much as it fits in the remaining packet)
  } deriving ( Show, Read, Eq )

instance Binary MsgLinuxMemStateDepA where
  get = do
    _msgLinuxMemStateDepA_index <- getWord8
    _msgLinuxMemStateDepA_pid <- getWord16le
    _msgLinuxMemStateDepA_pmem <- getWord8
    _msgLinuxMemStateDepA_tname <- decodeUtf8 <$> getByteString 15
    _msgLinuxMemStateDepA_cmdline <- decodeUtf8 . toStrict <$> getRemainingLazyByteString
    pure MsgLinuxMemStateDepA {..}

  put MsgLinuxMemStateDepA {..} = do
    putWord8 _msgLinuxMemStateDepA_index
    putWord16le _msgLinuxMemStateDepA_pid
    putWord8 _msgLinuxMemStateDepA_pmem
    putByteString $ encodeUtf8 _msgLinuxMemStateDepA_tname
    putByteString $ encodeUtf8 _msgLinuxMemStateDepA_cmdline

$(makeSBP 'msgLinuxMemStateDepA ''MsgLinuxMemStateDepA)
$(makeJSON "_msgLinuxMemStateDepA_" ''MsgLinuxMemStateDepA)
$(makeLenses ''MsgLinuxMemStateDepA)

msgLinuxSysStateDepA :: Word16
msgLinuxSysStateDepA = 0x7F02

-- | SBP class for message MSG_LINUX_SYS_STATE_DEP_A (0x7F02).
--
-- Deprecated.
data MsgLinuxSysStateDepA = MsgLinuxSysStateDepA
  { _msgLinuxSysStateDepA_mem_total    :: !Word16
    -- ^ total system memory
  , _msgLinuxSysStateDepA_pcpu         :: !Word8
    -- ^ percent of total cpu currently utilized
  , _msgLinuxSysStateDepA_pmem         :: !Word8
    -- ^ percent of total memory currently utilized
  , _msgLinuxSysStateDepA_procs_starting :: !Word16
    -- ^ number of processes that started during collection phase
  , _msgLinuxSysStateDepA_procs_stopping :: !Word16
    -- ^ number of processes that stopped during collection phase
  , _msgLinuxSysStateDepA_pid_count    :: !Word16
    -- ^ the count of processes on the system
  } deriving ( Show, Read, Eq )

instance Binary MsgLinuxSysStateDepA where
  get = do
    _msgLinuxSysStateDepA_mem_total <- getWord16le
    _msgLinuxSysStateDepA_pcpu <- getWord8
    _msgLinuxSysStateDepA_pmem <- getWord8
    _msgLinuxSysStateDepA_procs_starting <- getWord16le
    _msgLinuxSysStateDepA_procs_stopping <- getWord16le
    _msgLinuxSysStateDepA_pid_count <- getWord16le
    pure MsgLinuxSysStateDepA {..}

  put MsgLinuxSysStateDepA {..} = do
    putWord16le _msgLinuxSysStateDepA_mem_total
    putWord8 _msgLinuxSysStateDepA_pcpu
    putWord8 _msgLinuxSysStateDepA_pmem
    putWord16le _msgLinuxSysStateDepA_procs_starting
    putWord16le _msgLinuxSysStateDepA_procs_stopping
    putWord16le _msgLinuxSysStateDepA_pid_count

$(makeSBP 'msgLinuxSysStateDepA ''MsgLinuxSysStateDepA)
$(makeJSON "_msgLinuxSysStateDepA_" ''MsgLinuxSysStateDepA)
$(makeLenses ''MsgLinuxSysStateDepA)

msgLinuxProcessSocketCounts :: Word16
msgLinuxProcessSocketCounts = 0x7F03

-- | SBP class for message MSG_LINUX_PROCESS_SOCKET_COUNTS (0x7F03).
--
-- Top 10 list of processes with high socket counts.
data MsgLinuxProcessSocketCounts = MsgLinuxProcessSocketCounts
  { _msgLinuxProcessSocketCounts_index       :: !Word8
    -- ^ sequence of this status message, values from 0-9
  , _msgLinuxProcessSocketCounts_pid         :: !Word16
    -- ^ the PID of the process in question
  , _msgLinuxProcessSocketCounts_socket_count :: !Word16
    -- ^ the number of sockets the process is using
  , _msgLinuxProcessSocketCounts_socket_types :: !Word16
    -- ^ A bitfield indicating the socket types used: 0x1 (tcp), 0x2 (udp), 0x4
    -- (unix stream), 0x8 (unix dgram), 0x10 (netlink), and 0x8000 (unknown)
  , _msgLinuxProcessSocketCounts_socket_states :: !Word16
    -- ^ A bitfield indicating the socket states: 0x1 (established), 0x2 (syn-
    -- sent), 0x4 (syn-recv), 0x8 (fin-wait-1), 0x10 (fin-wait-2), 0x20 (time-
    -- wait), 0x40 (closed), 0x80 (close-wait), 0x100 (last-ack), 0x200
    -- (listen), 0x400 (closing), 0x800 (unconnected), and 0x8000 (unknown)
  , _msgLinuxProcessSocketCounts_cmdline     :: !Text
    -- ^ the command line of the process in question
  } deriving ( Show, Read, Eq )

instance Binary MsgLinuxProcessSocketCounts where
  get = do
    _msgLinuxProcessSocketCounts_index <- getWord8
    _msgLinuxProcessSocketCounts_pid <- getWord16le
    _msgLinuxProcessSocketCounts_socket_count <- getWord16le
    _msgLinuxProcessSocketCounts_socket_types <- getWord16le
    _msgLinuxProcessSocketCounts_socket_states <- getWord16le
    _msgLinuxProcessSocketCounts_cmdline <- decodeUtf8 . toStrict <$> getRemainingLazyByteString
    pure MsgLinuxProcessSocketCounts {..}

  put MsgLinuxProcessSocketCounts {..} = do
    putWord8 _msgLinuxProcessSocketCounts_index
    putWord16le _msgLinuxProcessSocketCounts_pid
    putWord16le _msgLinuxProcessSocketCounts_socket_count
    putWord16le _msgLinuxProcessSocketCounts_socket_types
    putWord16le _msgLinuxProcessSocketCounts_socket_states
    putByteString $ encodeUtf8 _msgLinuxProcessSocketCounts_cmdline

$(makeSBP 'msgLinuxProcessSocketCounts ''MsgLinuxProcessSocketCounts)
$(makeJSON "_msgLinuxProcessSocketCounts_" ''MsgLinuxProcessSocketCounts)
$(makeLenses ''MsgLinuxProcessSocketCounts)

msgLinuxProcessSocketQueues :: Word16
msgLinuxProcessSocketQueues = 0x7F04

-- | SBP class for message MSG_LINUX_PROCESS_SOCKET_QUEUES (0x7F04).
--
-- Top 10 list of sockets with deep queues.
data MsgLinuxProcessSocketQueues = MsgLinuxProcessSocketQueues
  { _msgLinuxProcessSocketQueues_index            :: !Word8
    -- ^ sequence of this status message, values from 0-9
  , _msgLinuxProcessSocketQueues_pid              :: !Word16
    -- ^ the PID of the process in question
  , _msgLinuxProcessSocketQueues_recv_queued      :: !Word16
    -- ^ the total amount of receive data queued for this process
  , _msgLinuxProcessSocketQueues_send_queued      :: !Word16
    -- ^ the total amount of send data queued for this process
  , _msgLinuxProcessSocketQueues_socket_types     :: !Word16
    -- ^ A bitfield indicating the socket types used: 0x1 (tcp), 0x2 (udp), 0x4
    -- (unix stream), 0x8 (unix dgram), 0x10 (netlink), and 0x8000 (unknown)
  , _msgLinuxProcessSocketQueues_socket_states    :: !Word16
    -- ^ A bitfield indicating the socket states: 0x1 (established), 0x2 (syn-
    -- sent), 0x4 (syn-recv), 0x8 (fin-wait-1), 0x10 (fin-wait-2), 0x20 (time-
    -- wait), 0x40 (closed), 0x80 (close-wait), 0x100 (last-ack), 0x200
    -- (listen), 0x400 (closing), 0x800 (unconnected), and 0x8000 (unknown)
  , _msgLinuxProcessSocketQueues_address_of_largest :: !Text
    -- ^ Address of the largest queue, remote or local depending on the
    -- directionality of the connection.
  , _msgLinuxProcessSocketQueues_cmdline          :: !Text
    -- ^ the command line of the process in question
  } deriving ( Show, Read, Eq )

instance Binary MsgLinuxProcessSocketQueues where
  get = do
    _msgLinuxProcessSocketQueues_index <- getWord8
    _msgLinuxProcessSocketQueues_pid <- getWord16le
    _msgLinuxProcessSocketQueues_recv_queued <- getWord16le
    _msgLinuxProcessSocketQueues_send_queued <- getWord16le
    _msgLinuxProcessSocketQueues_socket_types <- getWord16le
    _msgLinuxProcessSocketQueues_socket_states <- getWord16le
    _msgLinuxProcessSocketQueues_address_of_largest <- decodeUtf8 <$> getByteString 64
    _msgLinuxProcessSocketQueues_cmdline <- decodeUtf8 . toStrict <$> getRemainingLazyByteString
    pure MsgLinuxProcessSocketQueues {..}

  put MsgLinuxProcessSocketQueues {..} = do
    putWord8 _msgLinuxProcessSocketQueues_index
    putWord16le _msgLinuxProcessSocketQueues_pid
    putWord16le _msgLinuxProcessSocketQueues_recv_queued
    putWord16le _msgLinuxProcessSocketQueues_send_queued
    putWord16le _msgLinuxProcessSocketQueues_socket_types
    putWord16le _msgLinuxProcessSocketQueues_socket_states
    putByteString $ encodeUtf8 _msgLinuxProcessSocketQueues_address_of_largest
    putByteString $ encodeUtf8 _msgLinuxProcessSocketQueues_cmdline

$(makeSBP 'msgLinuxProcessSocketQueues ''MsgLinuxProcessSocketQueues)
$(makeJSON "_msgLinuxProcessSocketQueues_" ''MsgLinuxProcessSocketQueues)
$(makeLenses ''MsgLinuxProcessSocketQueues)

msgLinuxSocketUsage :: Word16
msgLinuxSocketUsage = 0x7F05

-- | SBP class for message MSG_LINUX_SOCKET_USAGE (0x7F05).
--
-- Summaries the socket usage across the system.
data MsgLinuxSocketUsage = MsgLinuxSocketUsage
  { _msgLinuxSocketUsage_avg_queue_depth   :: !Word32
    -- ^ average socket queue depths across all sockets on the system
  , _msgLinuxSocketUsage_max_queue_depth   :: !Word32
    -- ^ the max queue depth seen within the reporting period
  , _msgLinuxSocketUsage_socket_state_counts :: ![Word16]
    -- ^ A count for each socket type reported in the `socket_types_reported`
    -- field, the first entry corresponds to the first enabled bit in
    -- `types_reported`.
  , _msgLinuxSocketUsage_socket_type_counts :: ![Word16]
    -- ^ A count for each socket type reported in the `socket_types_reported`
    -- field, the first entry corresponds to the first enabled bit in
    -- `types_reported`.
  } deriving ( Show, Read, Eq )

instance Binary MsgLinuxSocketUsage where
  get = do
    _msgLinuxSocketUsage_avg_queue_depth <- getWord32le
    _msgLinuxSocketUsage_max_queue_depth <- getWord32le
    _msgLinuxSocketUsage_socket_state_counts <- replicateM 16 getWord16le
    _msgLinuxSocketUsage_socket_type_counts <- replicateM 16 getWord16le
    pure MsgLinuxSocketUsage {..}

  put MsgLinuxSocketUsage {..} = do
    putWord32le _msgLinuxSocketUsage_avg_queue_depth
    putWord32le _msgLinuxSocketUsage_max_queue_depth
    mapM_ putWord16le _msgLinuxSocketUsage_socket_state_counts
    mapM_ putWord16le _msgLinuxSocketUsage_socket_type_counts

$(makeSBP 'msgLinuxSocketUsage ''MsgLinuxSocketUsage)
$(makeJSON "_msgLinuxSocketUsage_" ''MsgLinuxSocketUsage)
$(makeLenses ''MsgLinuxSocketUsage)

msgLinuxProcessFdCount :: Word16
msgLinuxProcessFdCount = 0x7F06

-- | SBP class for message MSG_LINUX_PROCESS_FD_COUNT (0x7F06).
--
-- Top 10 list of processes with a large number of open file descriptors.
data MsgLinuxProcessFdCount = MsgLinuxProcessFdCount
  { _msgLinuxProcessFdCount_index  :: !Word8
    -- ^ sequence of this status message, values from 0-9
  , _msgLinuxProcessFdCount_pid    :: !Word16
    -- ^ the PID of the process in question
  , _msgLinuxProcessFdCount_fd_count :: !Word16
    -- ^ a count of the number of file descriptors opened by the process
  , _msgLinuxProcessFdCount_cmdline :: !Text
    -- ^ the command line of the process in question
  } deriving ( Show, Read, Eq )

instance Binary MsgLinuxProcessFdCount where
  get = do
    _msgLinuxProcessFdCount_index <- getWord8
    _msgLinuxProcessFdCount_pid <- getWord16le
    _msgLinuxProcessFdCount_fd_count <- getWord16le
    _msgLinuxProcessFdCount_cmdline <- decodeUtf8 . toStrict <$> getRemainingLazyByteString
    pure MsgLinuxProcessFdCount {..}

  put MsgLinuxProcessFdCount {..} = do
    putWord8 _msgLinuxProcessFdCount_index
    putWord16le _msgLinuxProcessFdCount_pid
    putWord16le _msgLinuxProcessFdCount_fd_count
    putByteString $ encodeUtf8 _msgLinuxProcessFdCount_cmdline

$(makeSBP 'msgLinuxProcessFdCount ''MsgLinuxProcessFdCount)
$(makeJSON "_msgLinuxProcessFdCount_" ''MsgLinuxProcessFdCount)
$(makeLenses ''MsgLinuxProcessFdCount)

msgLinuxProcessFdSummary :: Word16
msgLinuxProcessFdSummary = 0x7F07

-- | SBP class for message MSG_LINUX_PROCESS_FD_SUMMARY (0x7F07).
--
-- Summary of open file descriptors on the system.
data MsgLinuxProcessFdSummary = MsgLinuxProcessFdSummary
  { _msgLinuxProcessFdSummary_sys_fd_count :: !Word32
    -- ^ count of total FDs open on the system
  , _msgLinuxProcessFdSummary_most_opened :: !Text
    -- ^ A null delimited list of strings which alternates between a string
    -- representation of the process count and the file name whose count it
    -- being reported.  That is, in C string syntax
    -- "32\0/var/log/syslog\012\0/tmp/foo\0" with the end of the list being 2
    -- NULL terminators in a row.
  } deriving ( Show, Read, Eq )

instance Binary MsgLinuxProcessFdSummary where
  get = do
    _msgLinuxProcessFdSummary_sys_fd_count <- getWord32le
    _msgLinuxProcessFdSummary_most_opened <- decodeUtf8 . toStrict <$> getRemainingLazyByteString
    pure MsgLinuxProcessFdSummary {..}

  put MsgLinuxProcessFdSummary {..} = do
    putWord32le _msgLinuxProcessFdSummary_sys_fd_count
    putByteString $ encodeUtf8 _msgLinuxProcessFdSummary_most_opened

$(makeSBP 'msgLinuxProcessFdSummary ''MsgLinuxProcessFdSummary)
$(makeJSON "_msgLinuxProcessFdSummary_" ''MsgLinuxProcessFdSummary)
$(makeLenses ''MsgLinuxProcessFdSummary)

msgLinuxCpuState :: Word16
msgLinuxCpuState = 0x7F08

-- | SBP class for message MSG_LINUX_CPU_STATE (0x7F08).
--
-- This message indicates the process state of the top 10 heaviest consumers
-- of CPU on the system, including a timestamp.
data MsgLinuxCpuState = MsgLinuxCpuState
  { _msgLinuxCpuState_index :: !Word8
    -- ^ sequence of this status message, values from 0-9
  , _msgLinuxCpuState_pid   :: !Word16
    -- ^ the PID of the process
  , _msgLinuxCpuState_pcpu  :: !Word8
    -- ^ percent of CPU used, expressed as a fraction of 256
  , _msgLinuxCpuState_time  :: !Word32
    -- ^ timestamp of message, refer to flags field for how to interpret
  , _msgLinuxCpuState_flags :: !Word8
    -- ^ flags
  , _msgLinuxCpuState_tname :: !Text
    -- ^ fixed length string representing the thread name
  , _msgLinuxCpuState_cmdline :: !Text
    -- ^ the command line (as much as it fits in the remaining packet)
  } deriving ( Show, Read, Eq )

instance Binary MsgLinuxCpuState where
  get = do
    _msgLinuxCpuState_index <- getWord8
    _msgLinuxCpuState_pid <- getWord16le
    _msgLinuxCpuState_pcpu <- getWord8
    _msgLinuxCpuState_time <- getWord32le
    _msgLinuxCpuState_flags <- getWord8
    _msgLinuxCpuState_tname <- decodeUtf8 <$> getByteString 15
    _msgLinuxCpuState_cmdline <- decodeUtf8 . toStrict <$> getRemainingLazyByteString
    pure MsgLinuxCpuState {..}

  put MsgLinuxCpuState {..} = do
    putWord8 _msgLinuxCpuState_index
    putWord16le _msgLinuxCpuState_pid
    putWord8 _msgLinuxCpuState_pcpu
    putWord32le _msgLinuxCpuState_time
    putWord8 _msgLinuxCpuState_flags
    putByteString $ encodeUtf8 _msgLinuxCpuState_tname
    putByteString $ encodeUtf8 _msgLinuxCpuState_cmdline

$(makeSBP 'msgLinuxCpuState ''MsgLinuxCpuState)
$(makeJSON "_msgLinuxCpuState_" ''MsgLinuxCpuState)
$(makeLenses ''MsgLinuxCpuState)

msgLinuxMemState :: Word16
msgLinuxMemState = 0x7F09

-- | SBP class for message MSG_LINUX_MEM_STATE (0x7F09).
--
-- This message indicates the process state of the top 10 heaviest consumers
-- of memory on the system, including a timestamp.
data MsgLinuxMemState = MsgLinuxMemState
  { _msgLinuxMemState_index :: !Word8
    -- ^ sequence of this status message, values from 0-9
  , _msgLinuxMemState_pid   :: !Word16
    -- ^ the PID of the process
  , _msgLinuxMemState_pmem  :: !Word8
    -- ^ percent of memory used, expressed as a fraction of 256
  , _msgLinuxMemState_time  :: !Word32
    -- ^ timestamp of message, refer to flags field for how to interpret
  , _msgLinuxMemState_flags :: !Word8
    -- ^ flags
  , _msgLinuxMemState_tname :: !Text
    -- ^ fixed length string representing the thread name
  , _msgLinuxMemState_cmdline :: !Text
    -- ^ the command line (as much as it fits in the remaining packet)
  } deriving ( Show, Read, Eq )

instance Binary MsgLinuxMemState where
  get = do
    _msgLinuxMemState_index <- getWord8
    _msgLinuxMemState_pid <- getWord16le
    _msgLinuxMemState_pmem <- getWord8
    _msgLinuxMemState_time <- getWord32le
    _msgLinuxMemState_flags <- getWord8
    _msgLinuxMemState_tname <- decodeUtf8 <$> getByteString 15
    _msgLinuxMemState_cmdline <- decodeUtf8 . toStrict <$> getRemainingLazyByteString
    pure MsgLinuxMemState {..}

  put MsgLinuxMemState {..} = do
    putWord8 _msgLinuxMemState_index
    putWord16le _msgLinuxMemState_pid
    putWord8 _msgLinuxMemState_pmem
    putWord32le _msgLinuxMemState_time
    putWord8 _msgLinuxMemState_flags
    putByteString $ encodeUtf8 _msgLinuxMemState_tname
    putByteString $ encodeUtf8 _msgLinuxMemState_cmdline

$(makeSBP 'msgLinuxMemState ''MsgLinuxMemState)
$(makeJSON "_msgLinuxMemState_" ''MsgLinuxMemState)
$(makeLenses ''MsgLinuxMemState)

msgLinuxSysState :: Word16
msgLinuxSysState = 0x7F0A

-- | SBP class for message MSG_LINUX_SYS_STATE (0x7F0A).
--
-- This presents a summary of CPU and memory utilization, including a
-- timestamp.
data MsgLinuxSysState = MsgLinuxSysState
  { _msgLinuxSysState_mem_total    :: !Word16
    -- ^ total system memory, in MiB
  , _msgLinuxSysState_pcpu         :: !Word8
    -- ^ percent of CPU used, expressed as a fraction of 256
  , _msgLinuxSysState_pmem         :: !Word8
    -- ^ percent of memory used, expressed as a fraction of 256
  , _msgLinuxSysState_procs_starting :: !Word16
    -- ^ number of processes that started during collection phase
  , _msgLinuxSysState_procs_stopping :: !Word16
    -- ^ number of processes that stopped during collection phase
  , _msgLinuxSysState_pid_count    :: !Word16
    -- ^ the count of processes on the system
  , _msgLinuxSysState_time         :: !Word32
    -- ^ timestamp of message, refer to flags field for how to interpret
  , _msgLinuxSysState_flags        :: !Word8
    -- ^ flags
  } deriving ( Show, Read, Eq )

instance Binary MsgLinuxSysState where
  get = do
    _msgLinuxSysState_mem_total <- getWord16le
    _msgLinuxSysState_pcpu <- getWord8
    _msgLinuxSysState_pmem <- getWord8
    _msgLinuxSysState_procs_starting <- getWord16le
    _msgLinuxSysState_procs_stopping <- getWord16le
    _msgLinuxSysState_pid_count <- getWord16le
    _msgLinuxSysState_time <- getWord32le
    _msgLinuxSysState_flags <- getWord8
    pure MsgLinuxSysState {..}

  put MsgLinuxSysState {..} = do
    putWord16le _msgLinuxSysState_mem_total
    putWord8 _msgLinuxSysState_pcpu
    putWord8 _msgLinuxSysState_pmem
    putWord16le _msgLinuxSysState_procs_starting
    putWord16le _msgLinuxSysState_procs_stopping
    putWord16le _msgLinuxSysState_pid_count
    putWord32le _msgLinuxSysState_time
    putWord8 _msgLinuxSysState_flags

$(makeSBP 'msgLinuxSysState ''MsgLinuxSysState)
$(makeJSON "_msgLinuxSysState_" ''MsgLinuxSysState)
$(makeLenses ''MsgLinuxSysState)