updated docs; nut.chart.sh now autodetects multiple UPSes, web and cache directories are chowned; charts.d is now enabled by default
Costa Tsaousis (ktsaou) committed
Nov 18, 2015 at 01:07 UTC
c5572d0ddaf88f58995cfe4f916494e714c2f7ca
13 files changed
+332
-243
README.md
+5
-4
@@ -77,7 +77,7 @@ Here is a screenshot:
77
- `/proc/meminfo` (memory information)
78
- `/proc/vmstat` (system performance)
79
- `/proc/net/rpc/nfsd` (NFS server statistics for both v3 and v4 NFS)
80
- - `tc` classes (QoS classes)
80
+ - `tc` classes (QoS classes - [with FireQOS class names](http://firehol.org/tutorial/fireqos-new-user/))
81
82
- It supports **plugins** for collecting information from other sources!
83
@@ -89,12 +89,13 @@ Here is a screenshot:
89
90
- `charts.d.plugin` provides a simple way to script data collection in BASH. It includes example plugins that collect values from:
91
92
- - `nut` (UPS load, frequency, voltage, etc)
92
+ - `nut` (UPS load, frequency, voltage, etc, for multiple UPSes)
93
- `sensors` (temperature, voltage, current, power, humidity, fans rotation sensors)
94
- - `cpufreq` (current CPU clock frequency)
94
+ - `cpufreq` (current CPU clock frequency, for all CPUs)
95
- `postfix` (e-mail queue size)
96
- `squid` (web proxy statistics)
97
- `mysql` (mysql global statistics)
98
+ - `opensips` (opensips statistics)
99
100
Of course, you can write your own using BASH scripting.
101
@@ -102,7 +103,7 @@ Here is a screenshot:
103
104
It serves its own static files and dynamic files for rendering the site.
105
It does not support authentication or SSL - limit its access using your firewall.
105
- It does not allow ` .. ` or ` / ` in the files requested (so it can only serve files stored in the `web/` directory).
106
+ It does not allow ` .. ` or ` / ` in the files requested (so it can only serve files stored in the web directory `/usr/share/netdata/web`).
107
108
109
# How it works
charts.d/Makefile.am
+1
@@ -4,6 +4,7 @@
4
MAINTAINERCLEANFILES= $(srcdir)/Makefile.in
5
6
dist_charts_SCRIPTS = \
7
+ README.md \
8
airsearches.chart.sh \
9
cpu_apps.chart.sh \
10
cpufreq.chart.sh \
charts.d/README.md
new
+1
@@ -0,0 +1 @@
1
+
charts.d/mysql.chart.sh
+5
-1
@@ -7,7 +7,7 @@
7
# This statement does not require any privilege.
8
# It requires only the ability to connect to the server.
9
10
-mysql_cmd_opts=""
10
+mysql_cmd_opts=
11
mysql_update_every=5
12
13
mysql_get_stats() {
@@ -15,6 +15,10 @@ mysql_get_stats() {
15
}
16
17
mysql_check() {
18
+ require_cmd mysql || exit 1
19
+ require_cmd egrep || exit 1
20
+ require_cmd sed || exit 1
21
+
22
# check once if the url works
23
local x="$(mysql_get_stats | grep "^Connections[[:space:]]")"
24
if [ ! $? -eq 0 -o -z "$x" ]
charts.d/nut.chart.sh
+47
-27
@@ -4,56 +4,70 @@ nut_ups=
4
nut_update_every=2
5
6
nut_check() {
7
- if [ -z "${nut_ups}" ]
7
+ local x all
8
+
9
+ require_cmd upsc || return 1
10
+ require_cmd awk || return 1
11
+
12
+ all="$nut_ups"
13
+ [ -z "$all" ] && all="$(upsc -l)"
14
+
15
+ nut_ups=
16
+ for x in $all
17
+ do
18
+ upsc "$x" >/dev/null
19
+ [ $? -eq 0 ] && nut_ups="$nut_ups $x" && continue
20
+ echo >&2 "nut: ERROR: Cannot get information for NUT UPS '$x'."
21
+ done
22
+
23
+ if [ -z "$nut_ups" ]
24
then
25
echo >&2 "nut: Please set nut_ups='ups_name' in $confd/nut.conf"
26
return 1
27
fi
28
13
- upsc "${nut_ups}" >/dev/null
14
- if [ ! $? -eq 0 ]
15
- then
16
- echo >&2 "nut: failed to fetch info for ups '$nut_ups'. Please set nut_ups='ups_name' in $confd/nut.conf"
17
- return 1
18
- fi
19
-
29
return 0
30
}
31
32
nut_create() {
33
# create the charts
25
- cat <<EOF
26
-CHART nut.charge '' "UPS Charge" "percentage" nut '' area 21001 $nut_update_every
34
+ local x
35
+
36
+ for x in $nut_ups
37
+ do
38
+ cat <<EOF
39
+CHART nut_$x.charge '' "UPS Charge" "percentage" $x nut area 21001 $nut_update_every
40
DIMENSION battery_charge charge absolute 1 100
41
29
-CHART nut.battery_voltage '' "UPS Battery Voltage" "Volts" nut '' line 21002 $nut_update_every
42
+CHART nut_$x.battery_voltage '' "UPS Battery Voltage" "Volts" $x nut line 21002 $nut_update_every
43
DIMENSION battery_voltage voltage absolute 1 100
44
DIMENSION battery_voltage_high high absolute 1 100
45
DIMENSION battery_voltage_low low absolute 1 100
46
DIMENSION battery_voltage_nominal nominal absolute 1 100
47
35
-CHART nut.input_voltage '' "UPS Input Voltage" "Volts" nut '' line 21003 $nut_update_every
48
+CHART nut_$x.input_voltage '' "UPS Input Voltage" "Volts" $x nut line 21003 $nut_update_every
49
DIMENSION input_voltage voltage absolute 1 100
50
DIMENSION input_voltage_fault fault absolute 1 100
51
DIMENSION input_voltage_nominal nominal absolute 1 100
52
40
-CHART nut.input_current '' "UPS Input Current" "Ampere" nut '' line 21004 $nut_update_every
53
+CHART nut_$x.input_current '' "UPS Input Current" "Ampere" $x nut line 21004 $nut_update_every
54
DIMENSION input_current_nominal nominal absolute 1 100
55
43
-CHART nut.input_frequency '' "UPS Input Frequency" "Hz" nut '' line 21005 $nut_update_every
56
+CHART nut_$x.input_frequency '' "UPS Input Frequency" "Hz" $x nut line 21005 $nut_update_every
57
DIMENSION input_frequency frequency absolute 1 100
58
DIMENSION input_frequency_nominal nominal absolute 1 100
59
47
-CHART nut.output_voltage '' "UPS Output Voltage" "Volts" nut '' line 21006 $nut_update_every
60
+CHART nut_$x.output_voltage '' "UPS Output Voltage" "Volts" $x nut line 21006 $nut_update_every
61
DIMENSION output_voltage voltage absolute 1 100
62
50
-CHART nut.load '' "UPS Load" "percentage" nut '' area 21000 $nut_update_every
63
+CHART nut_$x.load '' "UPS Load" "percentage" $x nut area 21000 $nut_update_every
64
DIMENSION load load absolute 1 100
65
53
-CHART nut.temp '' "UPS Temperature" "temperature" nut '' line 21007 $nut_update_every
66
+CHART nut_$x.temp '' "UPS Temperature" "temperature" $x nut line 21007 $nut_update_every
67
DIMENSION temp temp absolute 1 100
68
EOF
56
-
69
+ done
70
+
71
return 0
72
}
73
@@ -66,7 +80,11 @@ nut_update() {
80
# for each dimension
81
# remember: KEEP IT SIMPLE AND SHORT
82
69
- upsc "${nut_ups}" | awk "
83
+ local x
84
+
85
+ for x in $nut_ups
86
+ do
87
+ upsc "$x" | awk "
88
BEGIN {
89
battery_charge = 0;
90
battery_voltage = 0;
@@ -98,45 +116,47 @@ BEGIN {
116
/^ups.load: .*/ { load = \$2 * 100 };
117
/^ups.temperature: .*/ { temp = \$2 * 100 };
118
END {
101
- print \"BEGIN nut.charge $1\";
119
+ print \"BEGIN nut_$x.charge $1\";
120
print \"SET battery_charge = \" battery_charge;
121
print \"END\"
122
105
- print \"BEGIN nut.battery_voltage $1\";
123
+ print \"BEGIN nut_$x.battery_voltage $1\";
124
print \"SET battery_voltage = \" battery_voltage;
125
print \"SET battery_voltage_high = \" battery_voltage_high;
126
print \"SET battery_voltage_low = \" battery_voltage_low;
127
print \"SET battery_voltage_nominal = \" battery_voltage_nominal;
128
print \"END\"
129
112
- print \"BEGIN nut.input_voltage $1\";
130
+ print \"BEGIN nut_$x.input_voltage $1\";
131
print \"SET input_voltage = \" input_voltage;
132
print \"SET input_voltage_fault = \" input_voltage_fault;
133
print \"SET input_voltage_nominal = \" input_voltage_nominal;
134
print \"END\"
135
118
- print \"BEGIN nut.input_current $1\";
136
+ print \"BEGIN nut_$x.input_current $1\";
137
print \"SET input_current_nominal = \" input_current_nominal;
138
print \"END\"
139
122
- print \"BEGIN nut.input_frequency $1\";
140
+ print \"BEGIN nut_$x.input_frequency $1\";
141
print \"SET input_frequency = \" input_frequency;
142
print \"SET input_frequency_nominal = \" input_frequency_nominal;
143
print \"END\"
144
127
- print \"BEGIN nut.output_voltage $1\";
145
+ print \"BEGIN nut_$x.output_voltage $1\";
146
print \"SET output_voltage = \" output_voltage;
147
print \"END\"
148
131
- print \"BEGIN nut.load $1\";
149
+ print \"BEGIN nut_$x.load $1\";
150
print \"SET load = \" load;
151
print \"END\"
152
135
- print \"BEGIN nut.temp $1\";
153
+ print \"BEGIN nut_$x.temp $1\";
154
print \"SET temp = \" temp;
155
print \"END\"
156
}
157
"
158
+ done
159
+
160
return 0
161
}
162
conf.d/Makefile.am
+1
@@ -4,5 +4,6 @@
4
MAINTAINERCLEANFILES= $(srcdir)/Makefile.in
5
6
dist_config_DATA = \
7
+ charts.d.conf \
8
apps_groups.conf \
9
$(NULL)
conf.d/charts.d.conf
new
+8
@@ -0,0 +1,8 @@
1
+nut=yes
2
+squid=yes
3
+postfix=yes
4
+sensors=yes
5
+cpufreq=yes
6
+mysql=yes
7
+#example=yes
8
+#load_average=yes
plugins.d/Makefile.am
+2
-2
@@ -4,12 +4,12 @@
4
MAINTAINERCLEANFILES= $(srcdir)/Makefile.in
5
6
dist_plugins_DATA = \
7
- README \
8
- loopsleepms.sh.inc \
7
+ README.md \
8
$(NULL)
9
10
dist_plugins_SCRIPTS = \
11
charts.d.dryrun-helper.sh \
12
charts.d.plugin \
13
tc-qos-helper.sh \
14
+ loopsleepms.sh.inc \
15
$(NULL)
plugins.d/README
deleted
-195
@@ -1,195 +0,0 @@
1
-
2
--------------------------------------------------------------------------------
3
-NETDATA CUSTOM PLUGINS
4
-
5
-custom chart plugins can be any program that can print a few values on its
6
-standard output.
7
-
8
-There are 5 lines netdata parses. lines starting with:
9
-
10
-CHART - create a new chart
11
-DIMENSION - add a dimension to the chart just created
12
-
13
-BEGIN - initialize data collection for a chart
14
-SET - set the value of a dimension for the initialized chart
15
-END - complete data collection for the initialized chart
16
-
17
-a single script can produce any number of charts with any number of dimensions
18
-each. charts can also be added any time (not just the beginning).
19
-
20
-The script should accept just one parameter: the number of seconds it is
21
-expected to update the values for its charts. The value passed by netdata
22
-to the script is controlled via the configuration file.
23
-
24
-The script can overwrite the update frequency. For example, the server may
25
-request per second updates, but the script may overwrite this to one update
26
-every 5 seconds.
27
-
28
-
29
--------------------------------------------------------------------------------
30
-CREATE NEW CHART
31
-
32
- > CHART type.id name title units family[=id] category[=type] charttype[=line]
33
- priority[=1000] update_every[=user default]
34
-
35
- where:
36
- - type.id
37
- uniquely identifies the chart
38
- this is what will be needed to add values to the chart
39
-
40
- - name
41
- is the name that will be presented to the used for this chart
42
-
43
- - title
44
- the text above the chart
45
-
46
- - units
47
- the label of the vertical axis of the chart
48
-
49
- - family
50
- is used to group charts together.
51
- (for example all eth0 charts should say: eth0)
52
-
53
- - category
54
- is not used currently.
55
- it will be used to set the section under which the chart will appear
56
- (for example mem.ram should appear in the 'system' section)
57
- the special word 'none' means: do not show this chart on the home page
58
-
59
- - charttype
60
- line, area or stacked
61
-
62
- - priority
63
- is the relative priority of the charts as rendered on the web page
64
- lower numbers make the charts appear before the ones with higher numbers
65
-
66
- - update_every
67
- overwrite the update frequency set by the server
68
-
69
-
70
--------------------------------------------------------------------------------
71
-ADD DIMENSIONS
72
-
73
- > DIMENSION id name[=id] algorithm[=absolute] multiplier[=1] divisor[=1]
74
- hidden[=not set]
75
-
76
- where:
77
-
78
- - id
79
- the id of this dimension (it is a text value, not numeric)
80
- this will be needed to add values to the dimension
81
-
82
- - name
83
- the name of the dimension as it will appear at the legend of the chart
84
-
85
- - algorithms
86
- one of:
87
-
88
- * absolute
89
- the value is to drawn as-is
90
-
91
- * incremental
92
- the value increases over time.
93
- the difference from the last value is presented in the chart.
94
- the server stretches the difference to produce 1 second increments.
95
- it does this at the microsecond level.
96
-
97
- * percentage-of-absolute-row
98
- the % of this value compared to the total of all dimensions.
99
-
100
- * percentage-of-incremental-row
101
- the % of this value compared to the differential total of
102
- each dimension.
103
-
104
- - multiplier
105
- a value to multiply the collected value.
106
-
107
- - divisor
108
- a value to divide the collected value.
109
-
110
- - hidden
111
- giving the keyword 'hidden' will make this dimension hidden.
112
- it will take part in the calculation but will not be presented in the chart
113
-
114
-
115
--------------------------------------------------------------------------------
116
-DATA COLLECTION
117
-
118
- data collection is defined as a series of BEGIN -> SET -> END lines.
119
-
120
- > BEGIN type.id
121
-
122
- - type.id
123
- is the unique identification of the chart (created with CHART)
124
-
125
- > SET id = value
126
-
127
- - id
128
- is the unique identification of the dimension (of the chart just began)
129
-
130
- - value
131
- is the collected value
132
-
133
- more SET lines may appear to update all the dimensions of the chart.
134
- all of them in one BEGIN -> END block.
135
- All SET lines within a single BEGIN -> END block have to refer to the
136
- same chart. If more charts need to be updated, each chart should have
137
- its own BEGIN -> SET -> END block.
138
-
139
- > END
140
-
141
- END does not take any parameters.
142
- it commits the collected values to the chart.
143
-
144
-
145
-
146
--------------------------------------------------------------------------------
147
-A NOTE ABOUT VALUES
148
-
149
- NetData will collect any signed value in the 64bit range:
150
-
151
- -9.223.372.036.854.775.808 to +9.223.372.036.854.775.807
152
-
153
- However, to lower its memory requirements, it stores all values in the
154
- signed 32bit range, divided by 10, that is:
155
-
156
- -214.748.364 to +214.748.364
157
-
158
- This division by 10, is used to give a decimal point in the charts.
159
- In memory, every number is 4 bytes (32bits).
160
-
161
- algorithm, multiplier and divisor help maintain all the detail required.
162
-
163
- The algorithm is applied in the wider 64bit numbers. Once the calculation
164
- is complete the value is multiplied by the multiplier, by 10, and then
165
- divided by the divider (all of these at the 64bit level).
166
- The 64bit result is then stored in a 32 bit signed int.
167
-
168
- So, at the chart level:
169
-
170
- - the finest number is 0.1
171
- - the smallest -214.748.364,8
172
- - the highest 214.748.364,7
173
-
174
- You should choose a multiplier and divisor to stay within these limits.
175
-
176
- Example:
177
-
178
- eth0 bytes-in is a 64bit number that is incremented every time.
179
- let say it is 1.000.000.000.000.000.000
180
- and one second later it is 1.000.000.000.999.000.000
181
-
182
- the dimension is 'incremental' with multiplier 8 (bytes to bits)
183
- and divider 1024 (bits to kilobits).
184
-
185
- netdata will store this value:
186
-
187
- value = (1.000.000.000.000.000.000 - 1.000.000.000.999.000.000)
188
- * 10
189
- * 8
190
- / 1024
191
- = 78.046.875
192
-
193
- or 7.804.687,5 kilobits/second (a little less than 8 gigabits/second)
194
-
195
-
plugins.d/README.md
new
+236
@@ -0,0 +1,236 @@
1
+netdata plugins
2
+===============
3
+
4
+Any program that can print a few values to its standard output can become
5
+a netdata plugin.
6
+
7
+There are 5 lines netdata parses. lines starting with:
8
+
9
+- `CHART` - create a new chart
10
+- `DIMENSION` - add a dimension to the chart just created
11
+- `BEGIN` - initialize data collection for a chart
12
+- `SET` - set the value of a dimension for the initialized chart
13
+- `END` - complete data collection for the initialized chart
14
+
15
+a single program can produce any number of charts with any number of dimensions
16
+each.
17
+
18
+charts can also be added any time (not just the beginning).
19
+
20
+### command line parameters
21
+
22
+The plugin should accept just **one** parameter: **the number of seconds it is
23
+expected to update the values for its charts**. The value passed by netdata
24
+to the plugin is controlled via its configuration file (so there is not need
25
+for the plugin to handle this configuration option).
26
+
27
+The script can overwrite the update frequency. For example, the server may
28
+request per second updates, but the script may overwrite this to one update
29
+every 5 seconds.
30
+
31
+### environment variables
32
+
33
+There are a few environment variables that are set by `netdata` and are
34
+available for the plugin to use.
35
+
36
+variable|description
37
+:------:|:----------
38
+`NETDATA_CONFIG_DIR`|The directory where all netdata related configuration should be stored. If the plugin requires custom configuration, this is the place to save it.
39
+`NETDATA_PLUGINS_DIR`|The directory where all netdata plugins are stored.
40
+`NETDATA_WEB_DIR`|The directory where the web files of netdata are saved.
41
+`NETDATA_CACHE_DIR`|The directory where the cache files of netdata are stored. Use this directory if the plugin requires a place to store data. A new directory should be created for the plugin for this purpose, inside this directory.
42
+`NETDATA_LOG_DIR`|The directory where the log files are stored. By default the `stderr` output of the plugin will be saved in the `error.log` file of netdata.
43
+`NETDATA_HOST_PREFIX`|This is used in environments where system directories like `/sys` and `/proc` have to be accessed at a different path.
44
+`NETDATA_DEBUG_FLAGS`|This is number (probably in hex starting with `0x`), that enables certain netdata debugging features.
45
+`NETDATA_UPDATE_EVERY`|The minimum number of seconds between chart refreshes. This is like the **internal clock** of netdata (it is user configurable, defaulting to `1`). There is no meaning for a plugin to update its values more frequently than this number of seconds.
46
+
47
+
48
+# the output of the plugin
49
+
50
+The plugin should output instructions for netdata to its output (`stdout`).
51
+
52
+## CHART
53
+
54
+`CHART` defines a new chart.
55
+
56
+the template is:
57
+
58
+ > CHART type.id name title units [family [category [charttype [priority [update_every]]]]]
59
+
60
+ where:
61
+ - `type.id`
62
+
63
+ uniquely identifies the chart,
64
+ this is what will be needed to add values to the chart
65
+
66
+ - `name`
67
+
68
+ is the name that will be presented to the used for this chart
69
+
70
+ - `title`
71
+
72
+ the text above the chart
73
+
74
+ - `units`
75
+
76
+ the label of the vertical axis of the chart,
77
+ all dimensions added to a chart should have the same units
78
+ of measurement
79
+
80
+ - `family`
81
+
82
+ is used to group charts together
83
+ (for example all eth0 charts should say: eth0),
84
+ if empty or missing, the `id` part of `type.id` will be used
85
+
86
+ - `category`
87
+
88
+ the section under which the chart will appear
89
+ (for example mem.ram should appear in the 'system' section),
90
+ the special word 'none' means: do not show this chart on the home page,
91
+ if empty or missing, the `type` part of `type.id` will be used
92
+
93
+ - `charttype`
94
+
95
+ one of `line`, `area` or `stacked`,
96
+ if empty or missing, the `line` will be used
97
+
98
+ - `priority`
99
+
100
+ is the relative priority of the charts as rendered on the web page,
101
+ lower numbers make the charts appear before the ones with higher numbers,
102
+ if empty or missing, `1000` will be used
103
+
104
+ - `update_every`
105
+
106
+ overwrite the update frequency set by the server,
107
+ if empty or missing, the user configured value will be used
108
+
109
+
110
+## DIMENSION
111
+
112
+`DIMENSION` defines a new dimension for the chart
113
+
114
+the template is:
115
+
116
+ > DIMENSION id [name [algorithm [multiplier [divisor [hidden]]]]]
117
+
118
+ where:
119
+
120
+ - `id`
121
+
122
+ the `id` of this dimension (it is a text value, not numeric),
123
+ this will be needed later to add values to the dimension
124
+
125
+ - `name`
126
+
127
+ the name of the dimension as it will appear at the legend of the chart,
128
+ if empty or missing the `id` will be used
129
+
130
+ - `algorithm`
131
+
132
+ one of:
133
+
134
+ * `absolute`
135
+
136
+ the value is to drawn as-is (interpolated to second boundary),
137
+ if `algorithm` is empty, invalid or missing, `absolute` is used
138
+
139
+ * `incremental`
140
+
141
+ the value increases over time,
142
+ the difference from the last value is presented in the chart,
143
+ the server interpolates the value and calculates a per second figure
144
+
145
+ * `percentage-of-absolute-row`
146
+
147
+ the % of this value compared to the total of all dimensions
148
+
149
+ * `percentage-of-incremental-row`
150
+
151
+ the % of this value compared to the incremental total of
152
+ all dimensions
153
+
154
+ - `multiplier`
155
+
156
+ an integer value to multiply the collected value,
157
+ if empty or missing, `1` is used
158
+
159
+ - `divisor`
160
+
161
+ an integer value to divide the collected value,
162
+ if empty or missing, `1` is used
163
+
164
+ - `hidden`
165
+
166
+ giving the keyword `hidden` will make this dimension hidden,
167
+ it will take part in the calculations but will not be presented in the chart
168
+
169
+
170
+## data collection
171
+
172
+data collection is defined as a series of `BEGIN` -> `SET` -> `END` lines
173
+
174
+ > BEGIN type.id [microseconds]
175
+
176
+ - `type.id`
177
+
178
+ is the unique identification of the chart (as given in `CHART`)
179
+
180
+ - `microseconds`
181
+
182
+ is the number of microseconds since the last update of the chart,
183
+ it is optional.
184
+
185
+ Under heavy system load, the system may have some latency transfering
186
+ data from the plugins to netdata via the pipe. This number improves
187
+ accuracy significantly, since the plugin is able to calculate the
188
+ duration between its iterations better than netdata.
189
+
190
+ The first time the plugin is started, no microseconds should be given
191
+ to netdata.
192
+
193
+ > SET id = value
194
+
195
+ - `id`
196
+
197
+ is the unique identification of the dimension (of the chart just began)
198
+
199
+ - `value`
200
+
201
+ is the collected value
202
+
203
+ > END
204
+
205
+END does not take any parameters, it commits the collected values to the chart.
206
+
207
+More `SET` lines may appear to update all the dimensions of the chart.
208
+All of them in one `BEGIN` -> `END` block.
209
+
210
+All `SET` lines within a single `BEGIN` -> `END` block have to refer to the
211
+same chart.
212
+
213
+If more charts need to be updated, each chart should have its own
214
+`BEGIN` -> `SET` -> `END` block.
215
+
216
+If, for any reason, a plugin has issued a `BEGIN` but wants to cancel it,
217
+it can issue a `FLUSH`. The `FLUSH` command will instruct netdata to ignore
218
+the last `BEGIN` command.
219
+
220
+If a plugin does not behave properly (outputs invalid lines, or does not
221
+follow these guidelines), will be disabled by netdata.
222
+
223
+
224
+# collected values
225
+
226
+netdata will collect any **signed** value in the 64bit range:
227
+`-9.223.372.036.854.775.808` to `+9.223.372.036.854.775.807`
228
+
229
+Internally, all calculations are made using 128 bit double precision and are
230
+stored in 30 bits as floating point.
231
+
232
+If a value is not collected, leave it empty, like this:
233
+
234
+`SET id = `
235
+
236
+or do not output the line at all.
plugins.d/charts.d.plugin
+1
@@ -103,6 +103,7 @@ do
103
then
104
shift
105
update_every=$x
106
+ [ $update_every -lt $minimum_update_frequency ] && update_every=$minimum_update_frequency
107
continue
108
fi
109
src/plugins_d.c
+18
-14
@@ -35,9 +35,9 @@ static inline int pluginsd_space(char c) {
35
}
36
}
37
38
-static void pluginsd_split_words(char *str, char **words, int max_words) {
38
+static int pluginsd_split_words(char *str, char **words, int max_words) {
39
char *s = str, quote = 0;
40
- int i = 0;
40
+ int i = 0, j;
41
42
// skip all white space
43
while(unlikely(pluginsd_space(*s))) s++;
@@ -94,7 +94,10 @@ static void pluginsd_split_words(char *str, char **words, int max_words) {
94
}
95
96
// terminate the words
97
- while(likely(i < max_words)) words[i++] = NULL;
97
+ j = i;
98
+ while(likely(j < max_words)) words[j++] = NULL;
99
+
100
+ return i;
101
}
102
103
@@ -140,9 +143,9 @@ void *pluginsd_worker_thread(void *arg)
143
144
// debug(D_PLUGINSD, "PLUGINSD: %s: %s", cd->filename, line);
145
143
- pluginsd_split_words(line, words, MAX_WORDS);
146
+ int w = pluginsd_split_words(line, words, MAX_WORDS);
147
s = words[0];
145
- if(unlikely(!s || !*s)) {
148
+ if(unlikely(!s || !*s || !w)) {
149
// debug(D_PLUGINSD, "PLUGINSD: empty line");
150
continue;
151
}
@@ -156,23 +159,24 @@ void *pluginsd_worker_thread(void *arg)
159
char *value = words[2];
160
161
if(unlikely(!dimension || !*dimension)) {
159
- error("PLUGINSD: '%s' is requesting a SET on chart '%s', like this: 'SET %s = %s'. Disabling it.", cd->fullfilename, st->id, dimension?dimension:"<nothing>", value?value:"<nothing>");
162
+ error("PLUGINSD: '%s' is requesting a SET on chart '%s', without a dimension. Disabling it.", cd->fullfilename, st->id);
163
cd->enabled = 0;
164
killpid(cd->pid, SIGTERM);
165
break;
166
}
167
165
- if(unlikely(!value || !*value)) value = "0";
168
+ if(unlikely(!value || !*value)) value = NULL;
169
170
if(unlikely(!st)) {
168
- error("PLUGINSD: '%s' is requesting a SET on dimension %s with value %s, without a BEGIN. Disabling it.", cd->fullfilename, dimension, value);
171
+ error("PLUGINSD: '%s' is requesting a SET on dimension %s with value %s, without a BEGIN. Disabling it.", cd->fullfilename, dimension, value?value:"<nothing>");
172
cd->enabled = 0;
173
killpid(cd->pid, SIGTERM);
174
break;
175
}
176
174
- if(unlikely(st->debug)) debug(D_PLUGINSD, "PLUGINSD: '%s' is setting dimension %s/%s to %s", cd->fullfilename, st->id, dimension, value);
175
- rrddim_set(st, dimension, atoll(value));
177
+ if(unlikely(st->debug)) debug(D_PLUGINSD, "PLUGINSD: '%s' is setting dimension %s/%s to %s", cd->fullfilename, st->id, dimension, value?value:"<nothing>");
178
+
179
+ if(value) rrddim_set(st, dimension, atoll(value));
180
181
count++;
182
}
@@ -404,14 +408,14 @@ void *pluginsd_main(void *ptr)
408
error("Cannot set pthread cancel state to ENABLE.");
409
410
char *dir_name = config_get("plugins", "plugins directory", PLUGINS_DIR);
407
- int automatic_run = config_get_boolean("plugins", "enable running new plugins", 0);
411
+ int automatic_run = config_get_boolean("plugins", "enable running new plugins", 1);
412
int scan_frequency = config_get_number("plugins", "check for new plugins every", 60);
413
DIR *dir = NULL;
414
struct dirent *file = NULL;
415
struct plugind *cd;
416
417
// enable the apps plugin by default
414
- config_get_boolean("plugins", "apps", 1);
418
+ // config_get_boolean("plugins", "apps", 1);
419
420
if(scan_frequency < 1) scan_frequency = 1;
421
@@ -480,11 +484,11 @@ void *pluginsd_main(void *ptr)
484
485
// spawn a new thread for it
486
if(unlikely(pthread_create(&cd->thread, NULL, pluginsd_worker_thread, cd) != 0)) {
483
- error("CHARTS.D: failed to create new thread for chart.d %s.", cd->filename);
487
+ error("PLUGINSD: failed to create new thread for plugin '%s'.", cd->filename);
488
cd->obsolete = 1;
489
}
490
else if(unlikely(pthread_detach(cd->thread) != 0))
487
- error("CHARTS.D: Cannot request detach of newly created thread for chart.d %s.", cd->filename);
491
+ error("PLUGINSD: Cannot request detach of newly created thread for plugin '%s'.", cd->filename);
492
}
493
494
closedir(dir);
web/Makefile.am
+7
@@ -11,3 +11,10 @@ dist_web_DATA = \
11
robots.txt \
12
theme.css \
13
$(NULL)
14
+
15
+install-data-hook:
16
+ if [ `id -u` == 0 ]; then \
17
+ getent group netdata > /dev/null || groupadd -r netdata; \
18
+ getent passwd netdata > /dev/null || useradd -r -g netdata -c netdata -s /sbin/nologin -d / netdata; \
19
+ chown -c -R netdata $(DESTDIR)$(cachedir) $(DESTDIR)$(webdir); \
20
+ fi