Factor out the getInstances function
[ganeti-local] / src / Ganeti / DataCollectors / Diskstats.hs
1 {-| @/proc/diskstats@ data collector.
2
3 -}
4
5 {-
6
7 Copyright (C) 2013 Google Inc.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 02110-1301, USA.
23
24 -}
25
26 module Ganeti.DataCollectors.Diskstats
27   ( main
28   , options
29   , arguments
30   , dcName
31   , dcVersion
32   , dcFormatVersion
33   , dcCategory
34   , dcKind
35   , dcReport
36   ) where
37
38
39 import qualified Control.Exception as E
40 import Control.Monad
41 import Data.Attoparsec.Text.Lazy as A
42 import Data.Maybe
43 import Data.Text.Lazy (pack, unpack)
44 import qualified Text.JSON as J
45
46 import qualified Ganeti.BasicTypes as BT
47 import qualified Ganeti.Constants as C
48 import Ganeti.Storage.Diskstats.Parser(diskstatsParser)
49 import Ganeti.Common
50 import Ganeti.DataCollectors.CLI
51 import Ganeti.DataCollectors.Types
52 import Ganeti.Utils
53
54
55 -- | The default path of the diskstats status file.
56 -- It is hardcoded because it is not likely to change.
57 defaultFile :: FilePath
58 defaultFile = C.diskstatsFile
59
60 -- | The default setting for the maximum amount of not parsed character to
61 -- print in case of error.
62 -- It is set to use most of the screen estate on a standard 80x25 terminal.
63 -- TODO: add the possibility to set this with a command line parameter.
64 defaultCharNum :: Int
65 defaultCharNum = 80*20
66
67 -- | The name of this data collector.
68 dcName :: String
69 dcName = "diskstats"
70
71 -- | The version of this data collector.
72 dcVersion :: DCVersion
73 dcVersion = DCVerBuiltin
74
75 -- | The version number for the data format of this data collector.
76 dcFormatVersion :: Int
77 dcFormatVersion = 1
78
79 -- | The category of this data collector.
80 dcCategory :: Maybe DCCategory
81 dcCategory = Just DCStorage
82
83 -- | The kind of this data collector.
84 dcKind :: DCKind
85 dcKind = DCKPerf
86
87 -- | The data exported by the data collector, taken from the default location.
88 dcReport :: IO DCReport
89 dcReport = buildDCReport defaultFile
90
91 -- * Command line options
92
93 options :: IO [OptType]
94 options =
95   return
96     [ oInputFile
97     ]
98
99 -- | The list of arguments supported by the program.
100 arguments :: [ArgCompletion]
101 arguments = [ArgCompletion OptComplFile 0 (Just 0)]
102
103 -- | This function computes the JSON representation of the diskstats status.
104 buildJsonReport :: FilePath -> IO J.JSValue
105 buildJsonReport inputFile = do
106   contents <-
107     ((E.try $ readFile inputFile) :: IO (Either IOError String)) >>=
108       exitIfBad "reading from file" . either (BT.Bad . show) BT.Ok
109   diskstatsData <-
110     case A.parse diskstatsParser $ pack contents of
111       A.Fail unparsedText contexts errorMessage -> exitErr $
112         show (Prelude.take defaultCharNum $ unpack unparsedText) ++ "\n"
113           ++ show contexts ++ "\n" ++ errorMessage
114       A.Done _ diskstatsD -> return diskstatsD
115   return $ J.showJSON diskstatsData
116
117 -- | This function computes the DCReport for the diskstats status.
118 buildDCReport :: FilePath -> IO DCReport
119 buildDCReport inputFile =
120   buildJsonReport inputFile >>=
121     buildReport dcName dcVersion dcFormatVersion dcCategory dcKind
122
123 -- | Main function.
124 main :: Options -> [String] -> IO ()
125 main opts args = do
126   let inputFile = fromMaybe defaultFile $ optInputFile opts
127   unless (null args) . exitErr $ "This program takes exactly zero" ++
128                                   " arguments, got '" ++ unwords args ++ "'"
129   report <- buildDCReport inputFile
130   putStrLn $ J.encode report