diff options
author | Costa Tsaousis (ktsaou) <costa@tsaousis.gr> | 2015-11-18 01:07:09 +0200 |
---|---|---|
committer | Costa Tsaousis (ktsaou) <costa@tsaousis.gr> | 2015-11-18 01:07:09 +0200 |
commit | c5572d0ddaf88f58995cfe4f916494e714c2f7ca (patch) | |
tree | d1a6ce7de038535b41179c463069eb2c35e1f2f4 | |
parent | 1b68ee4b7b809471f52a63708d4fc020dbc93ee0 (diff) |
updated docs; nut.chart.sh now autodetects multiple UPSes, web and cache directories are chowned; charts.d is now enabled by default
-rwxr-xr-x | README.md | 9 | ||||
-rw-r--r-- | charts.d/Makefile.am | 1 | ||||
-rw-r--r-- | charts.d/README.md | 1 | ||||
-rwxr-xr-x | charts.d/mysql.chart.sh | 6 | ||||
-rwxr-xr-x | charts.d/nut.chart.sh | 74 | ||||
-rw-r--r-- | conf.d/Makefile.am | 1 | ||||
-rw-r--r-- | conf.d/charts.d.conf | 8 | ||||
-rw-r--r-- | plugins.d/Makefile.am | 4 | ||||
-rw-r--r-- | plugins.d/README | 195 | ||||
-rw-r--r-- | plugins.d/README.md | 236 | ||||
-rwxr-xr-x | plugins.d/charts.d.plugin | 1 | ||||
-rwxr-xr-x | src/plugins_d.c | 32 | ||||
-rw-r--r-- | web/Makefile.am | 7 |
13 files changed, 332 insertions, 243 deletions
@@ -77,7 +77,7 @@ Here is a screenshot: - `/proc/meminfo` (memory information) - `/proc/vmstat` (system performance) - `/proc/net/rpc/nfsd` (NFS server statistics for both v3 and v4 NFS) - - `tc` classes (QoS classes) + - `tc` classes (QoS classes - [with FireQOS class names](http://firehol.org/tutorial/fireqos-new-user/)) - It supports **plugins** for collecting information from other sources! @@ -89,12 +89,13 @@ Here is a screenshot: - `charts.d.plugin` provides a simple way to script data collection in BASH. It includes example plugins that collect values from: - - `nut` (UPS load, frequency, voltage, etc) + - `nut` (UPS load, frequency, voltage, etc, for multiple UPSes) - `sensors` (temperature, voltage, current, power, humidity, fans rotation sensors) - - `cpufreq` (current CPU clock frequency) + - `cpufreq` (current CPU clock frequency, for all CPUs) - `postfix` (e-mail queue size) - `squid` (web proxy statistics) - `mysql` (mysql global statistics) + - `opensips` (opensips statistics) Of course, you can write your own using BASH scripting. @@ -102,7 +103,7 @@ Here is a screenshot: It serves its own static files and dynamic files for rendering the site. It does not support authentication or SSL - limit its access using your firewall. - It does not allow ` .. ` or ` / ` in the files requested (so it can only serve files stored in the `web/` directory). + It does not allow ` .. ` or ` / ` in the files requested (so it can only serve files stored in the web directory `/usr/share/netdata/web`). # How it works diff --git a/charts.d/Makefile.am b/charts.d/Makefile.am index 431b0b8f51..7ff064c358 100644 --- a/charts.d/Makefile.am +++ b/charts.d/Makefile.am @@ -4,6 +4,7 @@ MAINTAINERCLEANFILES= $(srcdir)/Makefile.in dist_charts_SCRIPTS = \ + README.md \ airsearches.chart.sh \ cpu_apps.chart.sh \ cpufreq.chart.sh \ diff --git a/charts.d/README.md b/charts.d/README.md new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/charts.d/README.md @@ -0,0 +1 @@ + diff --git a/charts.d/mysql.chart.sh b/charts.d/mysql.chart.sh index 72cbb41949..9390f972fe 100755 --- a/charts.d/mysql.chart.sh +++ b/charts.d/mysql.chart.sh @@ -7,7 +7,7 @@ # This statement does not require any privilege. # It requires only the ability to connect to the server. -mysql_cmd_opts="" +mysql_cmd_opts= mysql_update_every=5 mysql_get_stats() { @@ -15,6 +15,10 @@ mysql_get_stats() { } mysql_check() { + require_cmd mysql || exit 1 + require_cmd egrep || exit 1 + require_cmd sed || exit 1 + # check once if the url works local x="$(mysql_get_stats | grep "^Connections[[:space:]]")" if [ ! $? -eq 0 -o -z "$x" ] diff --git a/charts.d/nut.chart.sh b/charts.d/nut.chart.sh index 551ee4074b..7762e6c65a 100755 --- a/charts.d/nut.chart.sh +++ b/charts.d/nut.chart.sh @@ -4,56 +4,70 @@ nut_ups= nut_update_every=2 nut_check() { - if [ -z "${nut_ups}" ] + local x all + + require_cmd upsc || return 1 + require_cmd awk || return 1 + + all="$nut_ups" + [ -z "$all" ] && all="$(upsc -l)" + + nut_ups= + for x in $all + do + upsc "$x" >/dev/null + [ $? -eq 0 ] && nut_ups="$nut_ups $x" && continue + echo >&2 "nut: ERROR: Cannot get information for NUT UPS '$x'." + done + + if [ -z "$nut_ups" ] then echo >&2 "nut: Please set nut_ups='ups_name' in $confd/nut.conf" return 1 fi - upsc "${nut_ups}" >/dev/null - if [ ! $? -eq 0 ] - then - echo >&2 "nut: failed to fetch info for ups '$nut_ups'. Please set nut_ups='ups_name' in $confd/nut.conf" - return 1 - fi - return 0 } nut_create() { # create the charts - cat <<EOF -CHART nut.charge '' "UPS Charge" "percentage" nut '' area 21001 $nut_update_every + local x + + for x in $nut_ups + do + cat <<EOF +CHART nut_$x.charge '' "UPS Charge" "percentage" $x nut area 21001 $nut_update_every DIMENSION battery_charge charge absolute 1 100 -CHART nut.battery_voltage '' "UPS Battery Voltage" "Volts" nut '' line 21002 $nut_update_every +CHART nut_$x.battery_voltage '' "UPS Battery Voltage" "Volts" $x nut line 21002 $nut_update_every DIMENSION battery_voltage voltage absolute 1 100 DIMENSION battery_voltage_high high absolute 1 100 DIMENSION battery_voltage_low low absolute 1 100 DIMENSION battery_voltage_nominal nominal absolute 1 100 -CHART nut.input_voltage '' "UPS Input Voltage" "Volts" nut '' line 21003 $nut_update_every +CHART nut_$x.input_voltage '' "UPS Input Voltage" "Volts" $x nut line 21003 $nut_update_every DIMENSION input_voltage voltage absolute 1 100 DIMENSION input_voltage_fault fault absolute 1 100 DIMENSION input_voltage_nominal nominal absolute 1 100 -CHART nut.input_current '' "UPS Input Current" "Ampere" nut '' line 21004 $nut_update_every +CHART nut_$x.input_current '' "UPS Input Current" "Ampere" $x nut line 21004 $nut_update_every DIMENSION input_current_nominal nominal absolute 1 100 -CHART nut.input_frequency '' "UPS Input Frequency" "Hz" nut '' line 21005 $nut_update_every +CHART nut_$x.input_frequency '' "UPS Input Frequency" "Hz" $x nut line 21005 $nut_update_every DIMENSION input_frequency frequency absolute 1 100 DIMENSION input_frequency_nominal nominal absolute 1 100 -CHART nut.output_voltage '' "UPS Output Voltage" "Volts" nut '' line 21006 $nut_update_every +CHART nut_$x.output_voltage '' "UPS Output Voltage" "Volts" $x nut line 21006 $nut_update_every DIMENSION output_voltage voltage absolute 1 100 -CHART nut.load '' "UPS Load" "percentage" nut '' area 21000 $nut_update_every +CHART nut_$x.load '' "UPS Load" "percentage" $x nut area 21000 $nut_update_every DIMENSION load load absolute 1 100 -CHART nut.temp '' "UPS Temperature" "temperature" nut '' line 21007 $nut_update_every +CHART nut_$x.temp '' "UPS Temperature" "temperature" $x nut line 21007 $nut_update_every DIMENSION temp temp absolute 1 100 EOF - + done + return 0 } @@ -66,7 +80,11 @@ nut_update() { # for each dimension # remember: KEEP IT SIMPLE AND SHORT - upsc "${nut_ups}" | awk " + local x + + for x in $nut_ups + do + upsc "$x" | awk " BEGIN { battery_charge = 0; battery_voltage = 0; @@ -98,45 +116,47 @@ BEGIN { /^ups.load: .*/ { load = \$2 * 100 }; /^ups.temperature: .*/ { temp = \$2 * 100 }; END { - print \"BEGIN nut.charge $1\"; + print \"BEGIN nut_$x.charge $1\"; print \"SET battery_charge = \" battery_charge; print \"END\" - print \"BEGIN nut.battery_voltage $1\"; + print \"BEGIN nut_$x.battery_voltage $1\"; print \"SET battery_voltage = \" battery_voltage; print \"SET battery_voltage_high = \" battery_voltage_high; print \"SET battery_voltage_low = \" battery_voltage_low; print \"SET battery_voltage_nominal = \" battery_voltage_nominal; print \"END\" - print \"BEGIN nut.input_voltage $1\"; + print \"BEGIN nut_$x.input_voltage $1\"; print \"SET input_voltage = \" input_voltage; print \"SET input_voltage_fault = \" input_voltage_fault; print \"SET input_voltage_nominal = \" input_voltage_nominal; print \"END\" - print \"BEGIN nut.input_current $1\"; + print \"BEGIN nut_$x.input_current $1\"; print \"SET input_current_nominal = \" input_current_nominal; print \"END\" - print \"BEGIN nut.input_frequency $1\"; + print \"BEGIN nut_$x.input_frequency $1\"; print \"SET input_frequency = \" input_frequency; print \"SET input_frequency_nominal = \" input_frequency_nominal; print \"END\" - print \"BEGIN nut.output_voltage $1\"; + print \"BEGIN nut_$x.output_voltage $1\"; print \"SET output_voltage = \" output_voltage; print \"END\" - print \"BEGIN nut.load $1\"; + print \"BEGIN nut_$x.load $1\"; print \"SET load = \" load; print \"END\" - print \"BEGIN nut.temp $1\"; + print \"BEGIN nut_$x.temp $1\"; print \"SET temp = \" temp; print \"END\" } " + done + return 0 } diff --git a/conf.d/Makefile.am b/conf.d/Makefile.am index 73e45c1920..1ccd0618cf 100644 --- a/conf.d/Makefile.am +++ b/conf.d/Makefile.am @@ -4,5 +4,6 @@ MAINTAINERCLEANFILES= $(srcdir)/Makefile.in dist_config_DATA = \ + charts.d.conf \ apps_groups.conf \ $(NULL) diff --git a/conf.d/charts.d.conf b/conf.d/charts.d.conf new file mode 100644 index 0000000000..553e3ede64 --- /dev/null +++ b/conf.d/charts.d.conf @@ -0,0 +1,8 @@ +nut=yes +squid=yes +postfix=yes +sensors=yes +cpufreq=yes +mysql=yes +#example=yes +#load_average=yes diff --git a/plugins.d/Makefile.am b/plugins.d/Makefile.am index 903fae268a..4b3d9a8a4e 100644 --- a/plugins.d/Makefile.am +++ b/plugins.d/Makefile.am @@ -4,12 +4,12 @@ MAINTAINERCLEANFILES= $(srcdir)/Makefile.in dist_plugins_DATA = \ - README \ - loopsleepms.sh.inc \ + README.md \ $(NULL) dist_plugins_SCRIPTS = \ charts.d.dryrun-helper.sh \ charts.d.plugin \ tc-qos-helper.sh \ + loopsleepms.sh.inc \ $(NULL) diff --git a/plugins.d/README b/plugins.d/README deleted file mode 100644 index 6491dcb479..0000000000 --- a/plugins.d/README +++ /dev/null @@ -1,195 +0,0 @@ - -------------------------------------------------------------------------------- -NETDATA CUSTOM PLUGINS - -custom chart plugins can be any program that can print a few values on its -standard output. - -There are 5 lines netdata parses. lines starting with: - -CHART - create a new chart -DIMENSION - add a dimension to the chart just created - -BEGIN - initialize data collection for a chart -SET - set the value of a dimension for the initialized chart -END - complete data collection for the initialized chart - -a single script can produce any number of charts with any number of dimensions -each. charts can also be added any time (not just the beginning). - -The script should accept just one parameter: the number of seconds it is -expected to update the values for its charts. The value passed by netdata -to the script is controlled via the configuration file. - -The script can overwrite the update frequency. For example, the server may -request per second updates, but the script may overwrite this to one update -every 5 seconds. - - -------------------------------------------------------------------------------- -CREATE NEW CHART - - > CHART type.id name title units family[=id] category[=type] charttype[=line] - priority[=1000] update_every[=user default] - - where: - - type.id - uniquely identifies the chart - this is what will be needed to add values to the chart - - - name - is the name that will be presented to the used for this chart - - - title - the text above the chart - - - units - the label of the vertical axis of the chart - - - family - is used to group charts together. - (for example all eth0 charts should say: eth0) - - - category - is not used currently. - it will be used to set the section under which the chart will appear - (for example mem.ram should appear in the 'system' section) - the special word 'none' means: do not show this chart on the home page - - - charttype - line, area or stacked - - - priority - is the relative priority of the charts as rendered on the web page - lower numbers make the charts appear before the ones with higher numbers - - - update_every - overwrite the update frequency set by the server - - -------------------------------------------------------------------------------- -ADD DIMENSIONS - - > DIMENSION id name[=id] algorithm[=absolute] multiplier[=1] divisor[=1] - hidden[=not set] - - where: - - - id - the id of this dimension (it is a text value, not numeric) - this will be needed to add values to the dimension - - - name - the name of the dimension as it will appear at the legend of the chart - - - algorithms - one of: - - * absolute - the value is to drawn as-is - - * incremental - the value increases over time. - the difference from the last value is presented in the chart. - the server stretches the difference to produce 1 second increments. - it does this at the microsecond level. - - * percentage-of-absolute-row - the % of this value compared to the total of all dimensions. - - * percentage-of-incremental-row - the % of this value compared to the differential total of - each dimension. - - - multiplier - a value to multiply the collected value. - - - divisor - a value to divide the collected value. - - - hidden - giving the keyword 'hidden' will make this dimension hidden. - it will take part in the calculation but will not be presented in the chart - - -------------------------------------------------------------------------------- -DATA COLLECTION - - data collection is defined as a series of BEGIN -> SET -> END lines. - - > BEGIN type.id - - - type.id - is the unique identification of the chart (created with CHART) - - > SET id = value - - - id - is the unique identification of the dimension (of the chart just began) - - - value - is the collected value - - more SET lines may appear to update all the dimensions of the chart. - all of them in one BEGIN -> END block. - All SET lines within a single BEGIN -> END block have to refer to the - same chart. If more charts need to be updated, each chart should have - its own BEGIN -> SET -> END block. - - > END - - END does not take any parameters. - it commits the collected values to the chart. - - - -------------------------------------------------------------------------------- -A NOTE ABOUT VALUES - - NetData will collect any signed value in the 64bit range: - - -9.223.372.036.854.775.808 to +9.223.372.036.854.775.807 - - However, to lower its memory requirements, it stores all values in the - signed 32bit range, divided by 10, that is: - - -214.748.364 to +214.748.364 - - This division by 10, is used to give a decimal point in the charts. - In memory, every number is 4 bytes (32bits). - - algorithm, multiplier and divisor help maintain all the detail required. - - The algorithm is applied in the wider 64bit numbers. Once the calculation - is complete the value is multiplied by the multiplier, by 10, and then - divided by the divider (all of these at the 64bit level). - The 64bit result is then stored in a 32 bit signed int. - - So, at the chart level: - - - the finest number is 0.1 - - the smallest -214.748.364,8 - - the highest 214.748.364,7 - - You should choose a multiplier and divisor to stay within these limits. - - Example: - - eth0 bytes-in is a 64bit number that is incremented every time. - let say it is 1.000.000.000.000.000.000 - and one second later it is 1.000.000.000.999.000.000 - - the dimension is 'incremental' with multiplier 8 (bytes to bits) - and divider 1024 (bits to kilobits). - - netdata will store this value: - - value = (1.000.000.000.000.000.000 - 1.000.000.000.999.000.000) - * 10 - * 8 - / 1024 - = 78.046.875 - - or 7.804.687,5 kilobits/second (a little less than 8 gigabits/second) - - diff --git a/plugins.d/README.md b/plugins.d/README.md new file mode 100644 index 0000000000..8f55cf816c --- /dev/null +++ b/plugins.d/README.md @@ -0,0 +1,236 @@ +netdata plugins +=============== + +Any program that can print a few values to its standard output can become +a netdata plugin. + +There are 5 lines netdata parses. lines starting with: + +- `CHART` - create a new chart +- `DIMENSION` - add a dimension to the chart just created +- `BEGIN` - initialize data collection for a chart +- `SET` - set the value of a dimension for the initialized chart +- `END` - complete data collection for the initialized chart + +a single program can produce any number of charts with any number of dimensions +each. + +charts can also be added any time (not just the beginning). + +### command line parameters + +The plugin should accept just **one** parameter: **the number of seconds it is +expected to update the values for its charts**. The value passed by netdata +to the plugin is controlled via its configuration file (so there is not need +for the plugin to handle this configuration option). + +The script can overwrite the update frequency. For example, the server may +request per second updates, but the script may overwrite this to one update +every 5 seconds. + +### environment variables + +There are a few environment variables that are set by `netdata` and are +available for the plugin to use. + +variable|description +:------:|:---------- +`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. +`NETDATA_PLUGINS_DIR`|The directory where all netdata plugins are stored. +`NETDATA_WEB_DIR`|The directory where the web files of netdata are saved. +`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. +`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. +`NETDATA_HOST_PREFIX`|This is used in environments where system directories like `/sys` and `/proc` have to be accessed at a different path. +`NETDATA_DEBUG_FLAGS`|This is number (probably in hex starting with `0x`), that enables certain netdata debugging features. +`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. + + +# the output of the plugin + +The plugin should output instructions for netdata to its output (`stdout`). + +## CHART + +`CHART` defines a new chart. + +the template is: + + > CHART type.id name title units [family [category [charttype [priority [update_every]]]]] + + where: + - `type.id` + + uniquely identifies the chart, + this is what will be needed to add values to the chart + + - `name` + + is the name that will be presented to the used for this chart + + - `title` + + the text above the chart + + - `units` + + the label of the vertical axis of the chart, + all dimensions added to a chart should have the same units + of measurement + + - `family` + + is used to group charts together + (for example all eth0 charts should say: eth0), + if empty or missing, the `id` part of `type.id` will be used + + - `category` + + the section under which the chart will appear + (for example mem.ram should appear in the 'system' section), + the special word 'none' means: do not show this chart on the home page, + if empty or missing, the `type` part of `type.id` will be used + + - `charttype` + + one of `line`, `area` or `stacked`, + if empty or missing, the `line` will be used + + - `priority` + + is the relative priority of the charts as rendered on the web page, + lower numbers make the charts appear before the ones with higher numbers, + if empty or missing, `1000` will be used + + - `update_every` + + overwrite the update frequency set by the server, + if empty or missing, the user configured value will be used + + +## DIMENSION + +`DIMENSION` defines a new dimension for the chart + +the template is: + + > DIMENSION id [name [algorithm [multiplier [divisor [hidden]]]]] + + where: + + - `id` + + the `id` of this dimension (it is a text value, not numeric), + this will be needed later to add values to the dimension + + - `name` + + the name of the dimension as it will appear at the legend of the chart, + if empty or missing the `id` will be used + + - `algorithm` + + one of: + + * `absolute` + + the value is to drawn as-is (interpolated to second boundary), + if `algorithm` is empty, invalid or missing, `absolute` is used + + * `incremental` + + the value increases over time, + the difference from the last value is presented in the chart, + the server interpolates the value and calculates a per second figure + + * `percentage-of-absolute-row` + + the % of this value compared to the total of all dimensions + + * `percentage-of-incremental-row` + + the % of this value compared to the incremental total of + all dimensions + + - `multiplier` + + an integer value to multiply the collected value, + if empty or missing, `1` is used + + - `divisor` + + an integer value to divide the collected value, + if empty or missing, `1` is used + + - `hidden` + + giving the keyword `hidden` will make this dimension hidden, + it will take part in the calculations but will not be presented in the chart + + +## data collection + +data collection is defined as a series of `BEGIN` -> `SET` -> `END` lines + + > BEGIN type.id [microseconds] + + - `type.id` + + is the unique identification of the chart (as given in `CHART`) + + - `microseconds` + + is the number of microseconds since the last update of the chart, + it is optional. + + Under heavy system load, the system may have some latency transfering + data from the plugins to netdata via the pipe. This number improves + accuracy significantly, since the plugin is able to calculate the + duration between its iterations better than netdata. + + The first time the plugin is started, no microseconds should be given + to netdata. + + > SET id = value + + - `id` + + is the unique identification of the dimension (of the chart just began) + + - `value` + + is the collected value + + > END + +END does not take any parameters, it commits the collected values to the chart. + +More `SET` lines may appear to update all the dimensions of the chart. +All of them in one `BEGIN` -> `END` block. + +All `SET` lines within a single `BEGIN` -> `END` block have to refer to the +same chart. + +If more charts need to be updated, each chart should have its own +`BEGIN` -> `SET` -> `END` block. + +If, for any reason, a plugin has issued a `BEGIN` but wants to cancel it, +it can issue a `FLUSH`. The `FLUSH` command will instruct netdata to ignore +the last `BEGIN` command. + +If a plugin does not behave properly (outputs invalid lines, or does not +follow these guidelines), will be disabled by netdata. + + +# collected values + +netdata will collect any **signed** value in the 64bit range: +`-9.223.372.036.854.775.808` to `+9.223.372.036.854.775.807` + +Internally, all calculations are made using 128 bit double precision and are +stored in 30 bits as floating point. + +If a value is not collected, leave it empty, like this: + +`SET id = ` + +or do not output the line at all. diff --git a/plugins.d/charts.d.plugin b/plugins.d/charts.d.plugin index 713019e88b..769d5ba69c 100755 --- a/plugins.d/charts.d.plugin +++ b/plugins.d/charts.d.plugin @@ -103,6 +103,7 @@ do then shift update_every=$x + [ $update_every -lt $minimum_update_frequency ] && update_every=$minimum_update_frequency continue fi diff --git a/src/plugins_d.c b/src/plugins_d.c index 71d1fb2def..584268b903 100755 --- a/src/plugins_d.c +++ b/src/plugins_d.c @@ -35,9 +35,9 @@ static inline int pluginsd_space(char c) { } } -static void pluginsd_split_words(char *str, char **words, int max_words) { +static int pluginsd_split_words(char *str, char **words, int max_words) { char *s = str, quote = 0; - int i = 0; + int i = 0, j; // skip all white space while(unlikely(pluginsd_space(*s))) s++; @@ -94,7 +94,10 @@ static void pluginsd_split_words(char *str, char **words, int max_words) { } // terminate the words - while(likely(i < max_words)) words[i++] = NULL; + j = i; + while(likely(j < max_words)) words[j++] = NULL; + + return i; } @@ -140,9 +143,9 @@ void *pluginsd_worker_thread(void *arg) // debug(D_PLUGINSD, "PLUGINSD: %s: %s", cd->filename, line); - pluginsd_split_words(line, words, MAX_WORDS); + int w = pluginsd_split_words(line, words, MAX_WORDS); s = words[0]; - if(unlikely(!s || !*s)) { + if(unlikely(!s || !*s || !w)) { // debug(D_PLUGINSD, "PLUGINSD: empty line"); continue; } @@ -156,23 +159,24 @@ void *pluginsd_worker_thread(void *arg) char *value = words[2]; if(unlikely(!dimension || !*dimension)) { - 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>"); + error("PLUGINSD: '%s' is requesting a SET on chart '%s', without a dimension. Disabling it.", cd->fullfilename, st->id); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } - if(unlikely(!value || !*value)) value = "0"; + if(unlikely(!value || !*value)) value = NULL; if(unlikely(!st)) { - error("PLUGINSD: '%s' is requesting a SET on dimension %s with value %s, without a BEGIN. Disabling it.", cd->fullfilename, dimension, value); + error("PLUGINSD: '%s' is requesting a SET on dimension %s with value %s, without a BEGIN. Disabling it.", cd->fullfilename, dimension, value?value:"<nothing>"); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } - if(unlikely(st->debug)) debug(D_PLUGINSD, "PLUGINSD: '%s' is setting dimension %s/%s to %s", cd->fullfilename, st->id, dimension, value); - rrddim_set(st, dimension, atoll(value)); + if(unlikely(st->debug)) debug(D_PLUGINSD, "PLUGINSD: '%s' is setting dimension %s/%s to %s", cd->fullfilename, st->id, dimension, value?value:"<nothing>"); + + if(value) rrddim_set(st, dimension, atoll(value)); count++; } @@ -404,14 +408,14 @@ void *pluginsd_main(void *ptr) error("Cannot set pthread cancel state to ENABLE."); char *dir_name = config_get("plugins", "plugins directory", PLUGINS_DIR); - int automatic_run = config_get_boolean("plugins", "enable running new plugins", 0); + int automatic_run = config_get_boolean("plugins", "enable running new plugins", 1); int scan_frequency = config_get_number("plugins", "check for new plugins every", 60); DIR *dir = NULL; struct dirent *file = NULL; struct plugind *cd; // enable the apps plugin by default - config_get_boolean("plugins", "apps", 1); + // config_get_boolean("plugins", "apps", 1); if(scan_frequency < 1) scan_frequency = 1; @@ -480,11 +484,11 @@ void *pluginsd_main(void *ptr) // spawn a new thread for it if(unlikely(pthread_create(&cd->thread, NULL, pluginsd_worker_thread, cd) != 0)) { - error("CHARTS.D: failed to create new thread for chart.d %s.", cd->filename); + error("PLUGINSD: failed to create new thread for plugin '%s'.", cd->filename); cd->obsolete = 1; } else if(unlikely(pthread_detach(cd->thread) != 0)) - error("CHARTS.D: Cannot request detach of newly created thread for chart.d %s.", cd->filename); + error("PLUGINSD: Cannot request detach of newly created thread for plugin '%s'.", cd->filename); } closedir(dir); diff --git a/web/Makefile.am b/web/Makefile.am index 2344edf31f..237a92e651 100644 --- a/web/Makefile.am +++ b/web/Makefile.am @@ -11,3 +11,10 @@ dist_web_DATA = \ robots.txt \ theme.css \ $(NULL) + +install-data-hook: + if [ `id -u` == 0 ]; then \ + getent group netdata > /dev/null || groupadd -r netdata; \ + getent passwd netdata > /dev/null || useradd -r -g netdata -c netdata -s /sbin/nologin -d / netdata; \ + chown -c -R netdata $(DESTDIR)$(cachedir) $(DESTDIR)$(webdir); \ + fi |