Skip to content

Commit

Permalink
Implement JSON parsing in the external module.
Browse files Browse the repository at this point in the history
  • Loading branch information
postwait committed Mar 24, 2016
1 parent d5a17d6 commit cdee833
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 13 deletions.
2 changes: 1 addition & 1 deletion docs/config/modules/external.xml
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@
</listitem>
</varlistentry>
</variablelist>
<para>This is a regular expression that is globally applied to the stdout of the command. Each match is turned into a metric. It is a requirement to used named capturing in the regular expression where "key" is the named match of the metric name and "value" is the named match for the matric value. A sample for extracting performance data from Nagios commands would be: (?&lt;key&gt;\S+)=(?&lt;value&gt;[^;\s]+)(?=[;\s]). "NAGIOS" may also be specified as a value, which will configure the external check to do Nagios parsing based on the nagios_regex module configuration parameter.</para>
<para>This is a regular expression that is globally applied to the stdout of the command. Each match is turned into a metric. It is a requirement to used named capturing in the regular expression where "key" is the named match of the metric name and "value" is the named match for the matric value. A sample for extracting performance data from Nagios commands would be: (?&lt;key&gt;\S+)=(?&lt;value&gt;[^;\s]+)(?=[;\s]). "NAGIOS" may also be specified as a value, which will configure the external check to do Nagios parsing based on the nagios_regex module configuration parameter. "JSON" may be specified to instruct the output to be parsed as a JSON document using the same methodology as the HTTPTrap check.</para>
</listitem>
</varlistentry>
</variablelist>
Expand Down
37 changes: 28 additions & 9 deletions src/modules/external.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include "noit_check.h"
#include "noit_check_tools.h"
#include "noit_mtev_bridge.h"
#include "mtev_json.h"
#include "external_proc.h"

typedef enum {
Expand All @@ -75,6 +76,7 @@ struct check_info {
char **envs;
noit_check_t *check;
int exit_code;
external_special_t type;

int errortype;
int written;
Expand Down Expand Up @@ -163,13 +165,27 @@ static void external_log_results(noit_module_t *self, noit_check_t *check) {
}

/* Hack the output into metrics */
if(ci->output && ci->matcher) {
if(ci->output && ci->type == EXTERNAL_JSON_TYPE) {
int len, cnt;
len = strlen(ci->output);
cnt = noit_check_stats_from_json_str(check, ci->output, len);
if(cnt <= 0) {
noit_stats_set_state(check, NP_BAD);
noit_stats_set_status(check, "command produced invalid or empty JSON");
}
else {
char buf[64];
snprintf(buf, sizeof(buf), "%d stats", cnt);
noit_stats_set_status(check, buf);
}
}
else if(ci->output && ci->matcher) {
int rc, len, startoffset = 0;
int ovector[30];
char* output = ci->output;
len = strlen(output);
mtevL(data->nldeb, "going to match output at %d/%d\n", startoffset, len);
if (data->type == EXTERNAL_NAGIOS_TYPE) {
if (ci->type == EXTERNAL_NAGIOS_TYPE) {
pcre *matcher;
const char *error;
char* pch;
Expand Down Expand Up @@ -225,7 +241,7 @@ static void external_log_results(noit_module_t *self, noit_check_t *check) {
pcre_copy_named_substring(ci->matcher, output, ovector, rc,
"value", value, sizeof(value)) > 0) {
/* We're able to extract something... */
if (data->type == EXTERNAL_NAGIOS_TYPE) {
if (ci->type == EXTERNAL_NAGIOS_TYPE) {
/* We only care about metrics after the pipe - get check status from the
* pre-pipe data, then only match on post-pipe data */
char uom[128];
Expand All @@ -246,10 +262,10 @@ static void external_log_results(noit_module_t *self, noit_check_t *check) {
mtevL(data->nldeb, "going to match output at %d/%d\n", startoffset, len);
}
mtevL(data->nldeb, "match failed.... %d\n", rc);
if (ci->output)
noit_stats_set_status(check, ci->output);
}

if (ci->output)
noit_stats_set_status(check, ci->output);
noit_check_set_stats(check);

/* If we didn't exit normally, or we core, or we have stderr to report...
Expand Down Expand Up @@ -688,15 +704,18 @@ static int external_invoke(noit_module_t *self, noit_check_t *check,
&value) != 0) {
const char *error;
int erroffset;
if (!strcmp(value, "NAGIOS")) {
data->type = EXTERNAL_NAGIOS_TYPE;
if (!strcmp(value, "JSON")) {
ci->type = EXTERNAL_JSON_TYPE;
}
else if (!strcmp(value, "NAGIOS")) {
ci->type = EXTERNAL_NAGIOS_TYPE;
ci->matcher = pcre_compile(data->nagios_regex, 0, &error, &erroffset, NULL);
}
else {
data->type = EXTERNAL_DEFAULT_TYPE;
ci->type = EXTERNAL_DEFAULT_TYPE;
ci->matcher = pcre_compile(value, 0, &error, &erroffset, NULL);
}
if(!ci->matcher) {
if(ci->type != EXTERNAL_JSON_TYPE && !ci->matcher) {
mtevL(data->nlerr, "external pcre /%s/ failed @ %d: %s\n",
value, erroffset, error);
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/external.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
allowed=".+">These parameters allow the setting of environment variables for the command execution. The text following env_ is the key and the parameter value is the value of the environment variable to be set via execve.</parameter>
<parameter name="output_extract"
required="optional"
allowed=".+">This is a regular expression that is globally applied to the stdout of the command. Each match is turned into a metric. It is a requirement to used named capturing in the regular expression where "key" is the named match of the metric name and "value" is the named match for the matric value. A sample for extracting performance data from Nagios commands would be: <![CDATA[(?<key>\S+)=(?<value>[^;\s]+)(?=[;\s])]]>. "NAGIOS" may also be specified as a value, which will configure the external check to do Nagios parsing based on the nagios_regex module configuration parameter.</parameter>
allowed=".+">This is a regular expression that is globally applied to the stdout of the command. Each match is turned into a metric. It is a requirement to used named capturing in the regular expression where "key" is the named match of the metric name and "value" is the named match for the matric value. A sample for extracting performance data from Nagios commands would be: <![CDATA[(?<key>\S+)=(?<value>[^;\s]+)(?=[;\s])]]>. "NAGIOS" may also be specified as a value, which will configure the external check to do Nagios parsing based on the nagios_regex module configuration parameter. "JSON" may be specified to instruct the output to be parsed as a JSON document using the same methodology as the HTTPTrap check.</parameter>
</checkconfig>
<examples>
<example>
Expand Down
4 changes: 2 additions & 2 deletions src/modules/external_proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@

typedef enum {
EXTERNAL_DEFAULT_TYPE = 0,
EXTERNAL_NAGIOS_TYPE = 1
EXTERNAL_NAGIOS_TYPE = 1,
EXTERNAL_JSON_TYPE = 2
} external_special_t;

struct external_response {
Expand All @@ -62,7 +63,6 @@ typedef struct {
int pipe_e2n[2];
char* path;
char* nagios_regex;
external_special_t type;
eventer_jobq_t *jobq;
mtev_atomic64_t check_no_seq;
mtev_hash_table external_checks;
Expand Down

0 comments on commit cdee833

Please sign in to comment.