]> arthur.barton.de Git - netdata.git/blob - plugins.d/charts.d.plugin
added support for different update frequency per chart in charts.d.plugin
[netdata.git] / plugins.d / charts.d.plugin
1 #!/bin/sh
2
3 # -----------------------------------------------------------------------------
4 # insternal defaults
5
6 pause_method="sleep" # use either "suspend" or "sleep"
7                      # DO NOT USE SUSPEND - LINUX WILL SUSPEND NETDATA TOO
8                      # THE WHOLE PROCESS GROUP - NOT JUST THE SHELL
9
10 pluginsd="plugins.d"
11 confd="conf.d"
12 chartsd="charts.d"
13 myconfig="$confd/charts.d.conf"
14 minimum_update_frequency=1
15 update_every=1  # this is overwritten by the command line
16
17 # work around for non BASH shells
18 charts_create="_create"
19 charts_update="_update"
20 charts_check="_check"
21 charts_undescore="_"
22
23 # -----------------------------------------------------------------------------
24 # parse parameters
25
26 debug=0
27 check=0
28 chart_only=
29 while [ ! -z "$1" ]
30 do
31         if [ "$1" = "check" ]
32         then
33                 check=1
34                 shift
35                 continue
36         fi
37
38         if [ "$1" = "debug" -o "$1" = "all" ]
39         then
40                 debug=1
41                 shift
42                 continue
43         fi
44
45         if [ -f "$chartsd/$1.chart.sh" ]
46         then
47                 debug=1
48                 chart_only="`echo $1.chart.sh | sed "s/\.chart\.sh$//g"`"
49                 shift
50                 continue
51         fi
52
53         if [ -f "$chartsd/$1" ]
54         then
55                 debug=1
56                 chart_only="`echo $1 | sed "s/\.chart\.sh$//g"`"
57                 shift
58                 continue
59         fi
60
61         if [ -f "$1" ]
62         then
63                 debug=1
64                 chart_only="`basename "$1" | sed "s/\.chart\.sh$//g"`"
65                 shift
66                 continue
67         fi
68
69         # number check
70         n="$1"
71         x=$((n + 1 - 1))
72         if [ "$x" = "$n" ]
73         then
74                 update_every=$x
75                 shift
76                 continue
77         fi
78
79         echo >&2 "Cannot understand parameter $1. Aborting."
80         echo "DISABLE"
81         exit 1
82 done
83
84
85 # -----------------------------------------------------------------------------
86 # load my configuration
87
88 if [ -f "$myconfig" ]
89         then
90         . "$myconfig"
91         if [ $? -ne 0 ]
92         then
93                 echo >&2 "charts.d: cannot load $myconfig"
94                 echo "DISABLE"
95                 exit 1
96         fi
97 fi
98
99 if [ "$pause_method" = "suspend" ]
100 then
101         # enable bash job control
102         # this is required for suspend to work
103         set -m
104 fi
105
106 # -----------------------------------------------------------------------------
107 # internal checks
108
109 # netdata passes the requested update frequency as the first argument
110 update_every=$(( update_every + 1 - 1)) # makes sure it is a number
111 test $update_every -eq 0 && update_every=1 # if it is zero, make it 1
112
113 # check the charts.d directory
114 if [ ! -d "$chartsd" ]
115         then
116         echo >&2 "charts.d: cannot find charts directory '$chartsd'"
117         echo "DISABLE"
118 fi
119
120
121 # -----------------------------------------------------------------------------
122 # loop control
123
124 # default sleep function
125 loopsleepms() {
126         sleep $1
127 }
128 # if found and included, this file overwrites loopsleepms()
129 # with a high resolution timer function for precise looping.
130 . "`dirname $0`/loopsleepms.sh.inc"
131
132
133 # -----------------------------------------------------------------------------
134 # charts check functions
135
136 all_charts() {
137         cd "$chartsd"
138         ls *.chart.sh | sed "s/\.chart\.sh$//g"
139 }
140
141 all_enabled_charts() {
142         local charts=
143
144         # find all enabled charts
145
146         for chart in `all_charts`
147         do
148                 eval "enabled=\$$chart"
149                 if [ "$enabled" = "yes" ]
150                 then
151                         local charts="$charts $chart"
152                 else
153                         echo >&2 "charts.d: chart '$chart' is NOT enabled. Add a line with $chart=yes in $myconfig to enable it."
154                 fi
155         done
156
157         local charts2=
158         for chart in $charts
159         do
160                 # check the enabled charts
161                 local check="`cat "$chartsd/$chart.chart.sh" | sed "s/^ \+//g" | grep "^$chart$charts_check()"`"
162                 if [ -z "$check" ]
163                 then
164                         echo >&2 "charts.d: chart '$chart' does not seem to have a $chart$charts_check() function. Disabling it."
165                         continue
166                 fi
167
168                 local create="`cat "$chartsd/$chart.chart.sh" | sed "s/^ \+//g" | grep "^$chart$charts_create()"`"
169                 if [ -z "$create" ]
170                 then
171                         echo >&2 "charts.d: chart '$chart' does not seem to have a $chart$charts_create() function. Disabling it."
172                         continue
173                 fi
174
175                 local update="`cat "$chartsd/$chart.chart.sh" | sed "s/^ \+//g" | grep "^$chart$charts_update()"`"
176                 if [ -z "$update" ]
177                 then
178                         echo >&2 "charts.d: chart '$chart' does not seem to have a $chart$charts_update() function. Disabling it."
179                         continue
180                 fi
181
182                 # check its config
183                 if [ -f "$confd/$chart.conf" ]
184                 then
185                         if [ ! -z "`cat "$confd/$chart.conf" | sed "s/^ \+//g" | grep -v "^$" | grep -v "^#" | grep -v "^$chart$charts_undescore"`" ]
186                         then
187                                 echo >&2 "charts.d: chart's $chart config $confd/$chart.conf should only have lines starting with $chart$charts_undescore . Disabling it."
188                                 continue
189                         fi
190                 fi
191
192                 "$pluginsd/charts.d.dryrun-helper.sh" "$chart" "$chartsd/$chart.chart.sh" "$confd/$chart.conf" >/dev/null
193                 if [ $? -ne 0 ]
194                 then
195                         echo >&2 "charts.d: chart's $chart did not pass the dry run check. This means it uses global variables not starting with $chart. Disabling it."
196                         continue
197                 fi
198
199                 local charts2="$charts2 $chart"
200         done
201
202         echo $charts2
203 }
204
205
206 # -----------------------------------------------------------------------------
207 # load the charts
208
209 suffix_update_every="_update_every"
210 active_charts=
211 for chart in `all_enabled_charts`
212 do
213         . "$chartsd/$chart.chart.sh"
214
215         if [ -f "$confd/$chart.conf" ]
216         then
217                 . "$confd/$chart.conf"
218         fi
219
220         eval "dt=\$$chart$suffix_update_every"
221         dt=$(( dt + 1 - 1 )) # make sure it is a number
222         if [ $dt -lt $update_every ]
223         then
224                 eval "$chart$suffix_update_every=$update_every"
225         fi
226
227         $chart$charts_check
228         if [ $? -eq 0 ]
229         then
230                 active_charts="$active_charts $chart"
231         else
232                 echo >&2 "charts.d: chart '$chart' check() function reports failure."
233         fi
234 done
235
236
237 # -----------------------------------------------------------------------------
238 # check overwrites
239
240 # enable work time reporting
241 debug_time=
242 test $debug -eq 1 && debug_time=tellwork
243
244 # if we only need a specific chart, remove all the others
245 if [ ! -z "$chart_only" ]
246 then
247         check_charts=
248         for chart in $active_charts
249         do
250                 if [ "$chart" = "$chart_only" ]
251                 then
252                         check_charts="$chart"
253                         break
254                 fi
255         done
256         active_charts="$check_charts"
257 fi
258
259 # stop if we just need a pre-check
260 if [ $check -eq 1 ]
261 then
262         echo "CHECK RESULT"
263         echo "Will run the charts: $active_charts"
264         exit 0
265 fi
266
267
268 # -----------------------------------------------------------------------------
269 # create charts
270
271 run_charts=
272 for chart in $active_charts
273 do
274         $chart$charts_create
275         if [ $? -eq 0 ]
276         then
277                 run_charts="$run_charts $chart"
278         else
279                 echo >&2 "charts.d: chart '$chart' create() function reports failure."
280         fi
281 done
282
283
284 # -----------------------------------------------------------------------------
285 # update dimensions
286
287 global_update() {
288         local exit_after=$((3600 / update_every))
289
290         # return the current time in ms in $now_ms
291         current_time_ms
292
293         local chart=
294         for chart in $now_charts
295         do
296                 eval "local last_update_$chart=\$((now_ms - ($chart$suffix_update_every * 1000) ))"
297         done
298
299         # the main loop
300         local c=0
301         while [ 1 ]
302         do
303                 local c=$((c + 1))
304                 local now_charts="$run_charts"
305                 local run_charts=
306
307                 local chart=
308                 for chart in $now_charts
309                 do
310                         # return the current time in ms in $now_ms
311                         current_time_ms
312
313                         eval "local chart_min_dt=\$$chart$suffix_update_every"
314                         test -z "$chart_min_dt" && local chart_min_dt=$update_every
315                         local chart_min_dt=$((chart_min_dt * 1000000))
316
317                         eval "local last=\$last_update_$chart"
318                         test -z "$last" && local last=$((now_ms - (chart_min_dt / 1000) ))
319
320                         local dt=$(( (now_ms - last) * 1000 ))
321                         if [ $dt -ge $chart_min_dt ]
322                         then
323                                 eval "last_update_$chart=$now_ms"
324
325                                 # the first call should not give a duration
326                                 # so that netdata calibrates to current time
327                                 test $c -eq 1 && local dt=
328
329                                 $chart$charts_update $dt
330                                 if [ $? -eq 0 ]
331                                 then
332                                         run_charts="$run_charts $chart"
333                                 else
334                                         echo >&2 "charts.d: chart '$chart' update() function reports failure. Disabling it."
335                                 fi
336                         else
337                                 run_charts="$run_charts $chart"
338                         fi
339                 done
340
341                 if [ "$pause_method" = "suspend" ]
342                 then
343                         echo "STOPPING_WAKE_ME_UP_PLEASE"
344                         suspend || ( echo >&2 "suspend returned error $?, falling back to sleep."; loopsleepms $debug_time $update_every )
345                 else
346                         # wait the time you are required to
347                         loopsleepms $debug_time $update_every
348                 fi
349
350                 test $c -gt $exit_after && exit 0
351         done
352 }
353
354 global_update