Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / DataCollectors / Types.hs @ 55c87175

History | View | Annotate | Download (6.2 kB)

1 13d3acab Michele Tartara
{-# LANGUAGE TemplateHaskell #-}
2 13d3acab Michele Tartara
3 13d3acab Michele Tartara
{-| Implementation of the Ganeti data collector types.
4 13d3acab Michele Tartara
5 13d3acab Michele Tartara
-}
6 13d3acab Michele Tartara
7 13d3acab Michele Tartara
{-
8 13d3acab Michele Tartara
9 a895fa19 Michele Tartara
Copyright (C) 2012, 2013 Google Inc.
10 13d3acab Michele Tartara
11 13d3acab Michele Tartara
This program is free software; you can redistribute it and/or modify
12 13d3acab Michele Tartara
it under the terms of the GNU General Public License as published by
13 13d3acab Michele Tartara
the Free Software Foundation; either version 2 of the License, or
14 13d3acab Michele Tartara
(at your option) any later version.
15 13d3acab Michele Tartara
16 13d3acab Michele Tartara
This program is distributed in the hope that it will be useful, but
17 13d3acab Michele Tartara
WITHOUT ANY WARRANTY; without even the implied warranty of
18 13d3acab Michele Tartara
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 13d3acab Michele Tartara
General Public License for more details.
20 13d3acab Michele Tartara
21 13d3acab Michele Tartara
You should have received a copy of the GNU General Public License
22 13d3acab Michele Tartara
along with this program; if not, write to the Free Software
23 13d3acab Michele Tartara
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 13d3acab Michele Tartara
02110-1301, USA.
25 13d3acab Michele Tartara
26 13d3acab Michele Tartara
-}
27 13d3acab Michele Tartara
28 13d3acab Michele Tartara
module Ganeti.DataCollectors.Types
29 82437b28 Michele Tartara
  ( addStatus
30 f0e4b2a4 Michele Tartara
  , DCCategory(..)
31 54c7dff7 Michele Tartara
  , DCKind(..)
32 82437b28 Michele Tartara
  , DCReport(..)
33 82437b28 Michele Tartara
  , DCStatus(..)
34 82437b28 Michele Tartara
  , DCStatusCode(..)
35 a895fa19 Michele Tartara
  , DCVersion(..)
36 2da679f7 Spyros Trigazis
  , CollectorData(..)
37 2da679f7 Spyros Trigazis
  , CollectorMap
38 13d3acab Michele Tartara
  , buildReport
39 dd69cd3c Michele Tartara
  , mergeStatuses
40 c32c4e4d Spyros Trigazis
  , getCategoryName
41 13d3acab Michele Tartara
  ) where
42 13d3acab Michele Tartara
43 a5ec6d88 Michele Tartara
import Data.Char
44 e5fe8978 Spyros Trigazis
import Data.Ratio
45 2da679f7 Spyros Trigazis
import qualified Data.Map as Map
46 2da679f7 Spyros Trigazis
import qualified Data.Sequence as Seq
47 13d3acab Michele Tartara
import Text.JSON
48 13d3acab Michele Tartara
49 13d3acab Michele Tartara
import Ganeti.Constants as C
50 13d3acab Michele Tartara
import Ganeti.THH
51 13d3acab Michele Tartara
import Ganeti.Utils (getCurrentTime)
52 13d3acab Michele Tartara
53 f0e4b2a4 Michele Tartara
-- | The possible classes a data collector can belong to.
54 f0e4b2a4 Michele Tartara
data DCCategory = DCInstance | DCStorage | DCDaemon | DCHypervisor
55 e5fe8978 Spyros Trigazis
  deriving (Show, Eq, Read)
56 f0e4b2a4 Michele Tartara
57 c32c4e4d Spyros Trigazis
-- | Get the category name and return it as a string.
58 c32c4e4d Spyros Trigazis
getCategoryName :: DCCategory -> String
59 c32c4e4d Spyros Trigazis
getCategoryName dcc = map toLower . drop 2 . show $ dcc
60 c32c4e4d Spyros Trigazis
61 e5fe8978 Spyros Trigazis
categoryNames :: Map.Map String DCCategory
62 e5fe8978 Spyros Trigazis
categoryNames =
63 e5fe8978 Spyros Trigazis
  let l = [DCInstance, DCStorage, DCDaemon, DCHypervisor]
64 e5fe8978 Spyros Trigazis
  in Map.fromList $ zip (map getCategoryName l) l
65 e5fe8978 Spyros Trigazis
66 f0e4b2a4 Michele Tartara
-- | The JSON instance for DCCategory.
67 f0e4b2a4 Michele Tartara
instance JSON DCCategory where
68 c32c4e4d Spyros Trigazis
  showJSON = showJSON . getCategoryName
69 e5fe8978 Spyros Trigazis
  readJSON (JSString s) =
70 e5fe8978 Spyros Trigazis
    let s' = fromJSString s
71 e5fe8978 Spyros Trigazis
    in case Map.lookup s' categoryNames of
72 e5fe8978 Spyros Trigazis
         Just category -> Ok category
73 e5fe8978 Spyros Trigazis
         Nothing -> fail $ "Invalid category name " ++ s' ++ " for type\
74 e5fe8978 Spyros Trigazis
                           \ DCCategory"
75 e5fe8978 Spyros Trigazis
  readJSON v = fail $ "Invalid JSON value " ++ show v ++ " for type DCCategory"
76 f0e4b2a4 Michele Tartara
77 82437b28 Michele Tartara
-- | The possible status codes of a data collector.
78 82437b28 Michele Tartara
data DCStatusCode = DCSCOk      -- ^ Everything is OK
79 82437b28 Michele Tartara
                  | DCSCTempBad -- ^ Bad, but being automatically fixed
80 82437b28 Michele Tartara
                  | DCSCUnknown -- ^ Unable to determine the status
81 82437b28 Michele Tartara
                  | DCSCBad     -- ^ Bad. External intervention required
82 82437b28 Michele Tartara
                  deriving (Show, Eq, Ord)
83 82437b28 Michele Tartara
84 82437b28 Michele Tartara
-- | The JSON instance for CollectorStatus.
85 82437b28 Michele Tartara
instance JSON DCStatusCode where
86 82437b28 Michele Tartara
  showJSON DCSCOk      = showJSON (0 :: Int)
87 82437b28 Michele Tartara
  showJSON DCSCTempBad = showJSON (1 :: Int)
88 82437b28 Michele Tartara
  showJSON DCSCUnknown = showJSON (2 :: Int)
89 82437b28 Michele Tartara
  showJSON DCSCBad     = showJSON (4 :: Int)
90 82437b28 Michele Tartara
  readJSON = error "JSON read instance not implemented for type DCStatusCode"
91 82437b28 Michele Tartara
92 82437b28 Michele Tartara
-- | The status of a \"status reporting data collector\".
93 82437b28 Michele Tartara
$(buildObject "DCStatus" "dcStatus"
94 82437b28 Michele Tartara
  [ simpleField "code"    [t| DCStatusCode |]
95 82437b28 Michele Tartara
  , simpleField "message" [t| String |]
96 82437b28 Michele Tartara
  ])
97 82437b28 Michele Tartara
98 54c7dff7 Michele Tartara
-- | The type representing the kind of the collector.
99 54c7dff7 Michele Tartara
data DCKind = DCKPerf   -- ^ Performance reporting collector
100 54c7dff7 Michele Tartara
            | DCKStatus -- ^ Status reporting collector
101 54c7dff7 Michele Tartara
            deriving (Show, Eq)
102 54c7dff7 Michele Tartara
103 54c7dff7 Michele Tartara
-- | The JSON instance for CollectorKind.
104 54c7dff7 Michele Tartara
instance JSON DCKind where
105 54c7dff7 Michele Tartara
  showJSON DCKPerf   = showJSON (0 :: Int)
106 54c7dff7 Michele Tartara
  showJSON DCKStatus = showJSON (1 :: Int)
107 e5fe8978 Spyros Trigazis
  readJSON (JSRational _ x) =
108 e5fe8978 Spyros Trigazis
    if denominator x /= 1
109 e5fe8978 Spyros Trigazis
    then fail $ "Invalid JSON value " ++ show x ++ " for type DCKind"
110 e5fe8978 Spyros Trigazis
    else
111 e5fe8978 Spyros Trigazis
      let x' = (fromIntegral . numerator $ x) :: Int
112 e5fe8978 Spyros Trigazis
      in if x' == 0 then Ok DCKPerf
113 e5fe8978 Spyros Trigazis
         else if x' == 1 then Ok DCKStatus
114 e5fe8978 Spyros Trigazis
         else fail $ "Invalid JSON value " ++ show x' ++ " for type DCKind"
115 e5fe8978 Spyros Trigazis
  readJSON v = fail $ "Invalid JSON value " ++ show v ++ " for type DCKind"
116 54c7dff7 Michele Tartara
117 a895fa19 Michele Tartara
-- | Type representing the version number of a data collector.
118 a895fa19 Michele Tartara
data DCVersion = DCVerBuiltin | DCVersion String deriving (Show, Eq)
119 a895fa19 Michele Tartara
120 a895fa19 Michele Tartara
-- | The JSON instance for DCVersion.
121 a895fa19 Michele Tartara
instance JSON DCVersion where
122 a895fa19 Michele Tartara
  showJSON DCVerBuiltin = showJSON C.builtinDataCollectorVersion
123 a895fa19 Michele Tartara
  showJSON (DCVersion v) = showJSON v
124 e5fe8978 Spyros Trigazis
  readJSON (JSString s) =
125 e5fe8978 Spyros Trigazis
    if fromJSString s == C.builtinDataCollectorVersion
126 e5fe8978 Spyros Trigazis
    then Ok DCVerBuiltin else Ok . DCVersion $ fromJSString s
127 e5fe8978 Spyros Trigazis
  readJSON v = fail $ "Invalid JSON value " ++ show v ++ " for type DCVersion"
128 a895fa19 Michele Tartara
129 2da679f7 Spyros Trigazis
-- | Type for the value field of the above map.
130 2da679f7 Spyros Trigazis
data CollectorData = CPULoadData (Seq.Seq (Integer, [Int]))
131 2da679f7 Spyros Trigazis
132 2da679f7 Spyros Trigazis
-- | Type for the map storing the data of the statefull DataCollectors.
133 2da679f7 Spyros Trigazis
type CollectorMap = Map.Map String CollectorData
134 2da679f7 Spyros Trigazis
135 13d3acab Michele Tartara
-- | This is the format of the report produced by each data collector.
136 13d3acab Michele Tartara
$(buildObject "DCReport" "dcReport"
137 13d3acab Michele Tartara
  [ simpleField "name"           [t| String |]
138 a895fa19 Michele Tartara
  , simpleField "version"        [t| DCVersion |]
139 13d3acab Michele Tartara
  , simpleField "format_version" [t| Int |]
140 13d3acab Michele Tartara
  , simpleField "timestamp"      [t| Integer |]
141 f0e4b2a4 Michele Tartara
  , optionalNullSerField $
142 f0e4b2a4 Michele Tartara
      simpleField "category"     [t| DCCategory |]
143 54c7dff7 Michele Tartara
  , simpleField "kind"           [t| DCKind |]
144 13d3acab Michele Tartara
  , simpleField "data"           [t| JSValue |]
145 13d3acab Michele Tartara
  ])
146 13d3acab Michele Tartara
147 82437b28 Michele Tartara
-- | Add the data collector status information to the JSON representation of
148 82437b28 Michele Tartara
-- the collector data.
149 82437b28 Michele Tartara
addStatus :: DCStatus -> JSValue -> JSValue
150 82437b28 Michele Tartara
addStatus dcStatus (JSObject obj) =
151 82437b28 Michele Tartara
  makeObj $ ("status", showJSON dcStatus) : fromJSObject obj
152 82437b28 Michele Tartara
addStatus dcStatus value = makeObj
153 82437b28 Michele Tartara
  [ ("status", showJSON dcStatus)
154 82437b28 Michele Tartara
  , ("data", value)
155 82437b28 Michele Tartara
  ]
156 82437b28 Michele Tartara
157 dd69cd3c Michele Tartara
-- | Helper function for merging statuses.
158 dd69cd3c Michele Tartara
mergeStatuses :: (DCStatusCode, String) -> (DCStatusCode, [String])
159 dd69cd3c Michele Tartara
              -> (DCStatusCode, [String])
160 dd69cd3c Michele Tartara
mergeStatuses (newStat, newStr) (storedStat, storedStrs) =
161 dd69cd3c Michele Tartara
  let resStat = max newStat storedStat
162 dd69cd3c Michele Tartara
      resStrs =
163 dd69cd3c Michele Tartara
        if newStr == ""
164 dd69cd3c Michele Tartara
          then storedStrs
165 dd69cd3c Michele Tartara
          else storedStrs ++ [newStr]
166 dd69cd3c Michele Tartara
  in (resStat, resStrs)
167 dd69cd3c Michele Tartara
168 13d3acab Michele Tartara
-- | Utility function for building a report automatically adding the current
169 13d3acab Michele Tartara
-- timestamp (rounded up to seconds).
170 13d3acab Michele Tartara
-- If the version is not specified, it will be set to the value indicating
171 13d3acab Michele Tartara
-- a builtin collector.
172 54c7dff7 Michele Tartara
buildReport :: String -> DCVersion -> Int -> Maybe DCCategory -> DCKind
173 54c7dff7 Michele Tartara
            -> JSValue -> IO DCReport
174 54c7dff7 Michele Tartara
buildReport name version format_version category kind jsonData = do
175 13d3acab Michele Tartara
  now <- getCurrentTime
176 13d3acab Michele Tartara
  let timestamp = now * 1000000000 :: Integer
177 54c7dff7 Michele Tartara
  return $
178 54c7dff7 Michele Tartara
    DCReport name version format_version timestamp category kind
179 54c7dff7 Michele Tartara
      jsonData