Merge pull request #51 Influxdb from Luca

This commit is contained in:
Peter Haag 2018-01-06 15:23:59 +01:00
parent 0ea114f8ce
commit 2b4cfc7e8a
9 changed files with 1085 additions and 14 deletions

View File

@ -1,3 +1,6 @@
2018-01-06
- Merge pull request #51 Influxdb from Luca. Thx for the patch
2018-01-01
- IPFIX time stamps - Fix elements #21,#22 offset calculation, but timestamps not yet evaluated. (#160)
- IPFIX add fwd status tag #89 compatible to v9 (1byte)

View File

@ -403,6 +403,17 @@ netflow data, even if sampling is configured. The number of bytes/packets in eac
netflow record is automatically multiplied by the sampling rate. The total number of
flows is not changed as this is not accurate enough. (Small flows versus large flows)
###InfluxDB
You can send nfprofile stats data to an influxdb database. The data are the same of rrd files.
For enable this option you need libcurl dev package installed, use --enable-influxdb for configure the project and the nfprofile command should be invoked with option: -i <influxurl> .
Example: -i http://localhost:8086/write?db=mydb&u=user&p=pass
The parameters for auth (&u=user&p=pass) are optional.
Then you get the stats data on influxdb mydb in the measurement nfsen_stats.
For put the stats of live profile you need to apply a patch to nfsen (in extra/nfsen) and add in nfsen.conf the option:
$influxdb_url="http://mydbhost.local:8086/write?db=nfsen";
as example I added a preconfigured grafana dashboard in extra/grafana/Nfsen_Stats.json .
---
For more information, see the GitHub Wiki

View File

@ -1,8 +1,6 @@
/*
* Copyright (c) 2017, Peter Haag
* Copyright (c) 2014, Peter Haag
* Copyright (c) 2009, Peter Haag
* Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
* Copyright (c) 2009 - 2018, Peter Haag
* Copyright (c) 2004 - 2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -81,6 +79,10 @@ extension_map_list_t *extension_map_list;
uint32_t is_anonymized;
char Ident[IDENTLEN];
#ifdef HAVE_INFLUXDB
char influxdb_url[1024]="";
#endif
/* Function Prototypes */
static void usage(char *name);
@ -88,7 +90,6 @@ static profile_param_info_t *ParseParams (char *profile_datadir);
static void process_data(profile_channel_info_t *channels, unsigned int num_channels, time_t tslot);
/* Functions */
#include "nfdump_inline.c"
@ -108,6 +109,9 @@ static void usage(char *name) {
"-Z\t\tCheck filter syntax and exit.\n"
"-S subdir\tSub directory format. see nfcapd(1) for format\n"
"-z\t\tCompress flows in output file.\n"
#ifdef HAVE_INFLUXDB
"-i <influxurl>\tInfluxdb url for stats (example: http://localhost:8086/write?db=mydb&u=pippo&p=paperino)\n"
#endif
"-t <time>\ttime for RRD update\n", name);
} /* usage */
@ -540,7 +544,7 @@ time_t tslot;
// default file names
ffile = "filter.txt";
rfile = NULL;
while ((c = getopt(argc, argv, "D:HIL:p:P:hf:J;r:n:M:S:t:VzZ")) != EOF) {
while ((c = getopt(argc, argv, "D:HIL:p:P:hif:J;r:n:M:S:t:VzZ")) != EOF) {
switch (c) {
case 'h':
usage(argv[0]);
@ -608,6 +612,12 @@ time_t tslot;
}
compress = LZO_COMPRESSED;
break;
#ifdef HAVE_INFLUXDB
case 'i':
strncpy(influxdb_url, optarg, 1024);
influxdb_url[1023] = '\0';
break;
#endif
default:
usage(argv[0]);
exit(0);

View File

@ -1,8 +1,6 @@
/*
* Copyright (c) 2017, Peter Haag
* Copyright (c) 2014, Peter Haag
* Copyright (c) 2009, Peter Haag
* Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
* Copyright (c) 2009 - 2018, Peter Haag
* Copyright (c) 2004 - 2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -62,6 +60,12 @@
#include "nftree.h"
#include "profile.h"
#ifdef HAVE_INFLUXDB
#include <curl/curl.h>
extern char influxdb_url[1024];
static char influxdb_measurement[]="nfsen_stats";
#endif
/* imported vars */
extern char yyerror_buff[256];
extern uint32_t is_anonymized;
@ -378,6 +382,10 @@ unsigned int num;
}
if ( ((profile_channels[num].type & 0x8) == 0) && tslot > 0 ) {
UpdateRRD(tslot, &profile_channels[num]);
#ifdef HAVE_INFLUXDB
if(strlen(influxdb_url) > 0)
UpdateInfluxDB(tslot, &profile_channels[num]);
#endif
}
}
@ -447,3 +455,87 @@ stat_record_t stat_record = channel->stat_record;
}
} // End of UpdateRRD
#ifdef HAVE_INFLUXDB
static void influxdb_client_post(char *body) {
CURLcode c;
CURL *handle = curl_easy_init();
//curl -i -XPOST 'http://nbox-demo:8086/write?db=lucatest' --data-binary 'test,host=server01,region=us-west valueA=0.64 valueB=0.64 1434055562000000000'
curl_easy_setopt(handle, CURLOPT_URL, influxdb_url);
curl_easy_setopt(handle, CURLOPT_TIMEOUT, 5L);
curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, 3L);
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, body);
c = curl_easy_perform(handle);
if (c == CURLE_OK) {
long status_code = 0;
if (curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status_code) == CURLE_OK){
c = status_code;
if (status_code != 204){
LogError("INFLUXDB: %s Insert Error: HTTP %d\n", influxdb_url, status_code);
}
}
} else{
LogError("INFLUXDB: %s Curl Error: %s\n", influxdb_url, curl_easy_strerror(c));
}
curl_easy_cleanup(handle);
}
void UpdateInfluxDB( time_t tslot, profile_channel_info_t *channel ) {
char buff[2048], *s;
int len, buffsize;
stat_record_t stat_record = channel->stat_record;
char *groupname = strcmp(channel->group, ".")==0?"ROOT":channel->group;
buffsize = sizeof(buff);
s = buff;
len = snprintf(s, buffsize , "%s,channel=%s,profilegroup=%s,profile=%s ", influxdb_measurement, channel->channel, groupname, channel->profile);
buffsize -= len; s += len;
len = snprintf(s, buffsize , "flows=%llu", (long long unsigned)stat_record.numflows);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",flows_tcp=%llu", (long long unsigned)stat_record.numflows_tcp);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",flows_udp=%llu", (long long unsigned)stat_record.numflows_udp);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",flows_icmp=%llu", (long long unsigned)stat_record.numflows_icmp);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",flows_other=%llu", (long long unsigned)stat_record.numflows_other);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",packets=%llu", (long long unsigned)stat_record.numpackets);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",packets_tcp=%llu", (long long unsigned)stat_record.numpackets_tcp);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",packets_udp=%llu", (long long unsigned)stat_record.numpackets_udp);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",packets_icmp=%llu", (long long unsigned)stat_record.numpackets_icmp);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",packets_other=%llu", (long long unsigned)stat_record.numpackets_other);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",traffic=%llu", (long long unsigned)stat_record.numbytes);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",traffic_tcp=%llu", (long long unsigned)stat_record.numbytes_tcp);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",traffic_udp=%llu", (long long unsigned)stat_record.numbytes_udp);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",traffic_icmp=%llu", (long long unsigned)stat_record.numbytes_icmp);
buffsize -= len; s += len;
len = snprintf(s, buffsize , ",traffic_other=%llu", (long long unsigned)stat_record.numbytes_other);
buffsize -= len; s += len;
// timestamp in nanoseconds
len = snprintf(s, buffsize , " %llu000000000", (long long unsigned)tslot);
buffsize -= len; s += len;
influxdb_client_post(buff);
//DATA: test,host=server01,region=us-west valueA=0.64,valueB=0.64 1434055562000000000'
} // End of UpdateInfluxDB
#endif /* HAVE_INFLUXDB */

View File

@ -1,8 +1,6 @@
/*
* Copyright (c) 2017, Peter Haag
* Copyright (c) 2014, Peter Haag
* Copyright (c) 2009, Peter Haag
* Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
* Copyright (c) 2009 - 2018, Peter Haag
* Copyright (c) 2004 - 2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -73,4 +71,8 @@ void CloseChannels (time_t tslot, int compress);
void UpdateRRD( time_t tslot, profile_channel_info_t *channel );
#ifdef HAVE_INFLUXDB
void UpdateInfluxDB( time_t tslot, profile_channel_info_t *channel );
#endif
#endif //_PROFILE_H

View File

@ -172,6 +172,26 @@ AC_SUBST(RRD_LIBS)
AM_CONDITIONAL(NFPROFILE, false)
)
AC_ARG_ENABLE(influxdb, [AS_HELP_STRING([--enable-influxdb], [enable stats to influxdb (default is no)])], [
influxdb=${enableval} ], [influxdb=no])
AS_IF([test "x$influxdb" = xyes], [
PKG_CHECK_MODULES([curl], [libcurl],,
[AC_MSG_ERROR([No pkg-config for libcurl])])
AC_SUBST(CURL_CFLAGS)
AC_SUBST(CURL_LIBS)
#CFLAGS="${CFLAGS} ${CURL_CFLAGS}"
#LIBS="${LIBS} ${LIBS_CFLAGS}"
AC_CHECK_LIB([curl], [curl_easy_init],,[AC_MSG_ERROR([libcurl required!])])
AC_CHECK_LIB([curl], [curl_easy_escape],,[AC_MSG_ERROR([libcurl required!])])
AC_CHECK_LIB([curl], [curl_easy_setopt],,[AC_MSG_ERROR([libcurl required!])])
AC_CHECK_LIB([curl], [curl_easy_cleanup],,[AC_MSG_ERROR([libcurl required!])])
AC_CHECK_LIB([curl], [curl_free],,[AC_MSG_ERROR([libcurl required!])])
AC_DEFINE_UNQUOTED(HAVE_INFLUXDB, 1, [enable stats to influxdb])
], [
])
AC_ARG_ENABLE(nftrack,
[ --enable-nftrack Build nftrack used by PortTracker; default is NO],
[

View File

@ -0,0 +1,661 @@
{
"__inputs": [
{
"name": "DS_NFSEN",
"label": "nfsen",
"description": "",
"type": "datasource",
"pluginId": "influxdb",
"pluginName": "InfluxDB"
}
],
"__requires": [
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "4.1.1"
},
{
"type": "panel",
"id": "graph",
"name": "Graph",
"version": ""
},
{
"type": "datasource",
"id": "influxdb",
"name": "InfluxDB",
"version": "1.0.0"
},
{
"type": "panel",
"id": "table",
"name": "Table",
"version": ""
}
],
"annotations": {
"list": []
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"hideControls": false,
"id": null,
"links": [
{
"icon": "external link",
"includeVars": true,
"keepTime": true,
"tags": [],
"targetBlank": true,
"title": "NFSen",
"tooltip": "",
"type": "link",
"url": "http://localhost/nfsen/nfsen.php"
},
{
"icon": "external link",
"includeVars": true,
"keepTime": true,
"tags": [],
"targetBlank": true,
"title": "g2nfsen",
"type": "link",
"url": "http://localhost/nfsen/grafana2nfsen.php"
}
],
"refresh": false,
"rows": [
{
"collapse": false,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_NFSEN}",
"editable": true,
"error": false,
"fill": 4,
"grid": {},
"id": 1,
"legend": {
"alignAsTable": true,
"avg": true,
"current": false,
"max": true,
"min": true,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": true,
"steppedLine": false,
"targets": [
{
"dsType": "influxdb",
"groupBy": [
{
"params": [
"$interval"
],
"type": "time"
},
{
"params": [
"channel"
],
"type": "tag"
},
{
"params": [
"profile"
],
"type": "tag"
},
{
"params": [
"null"
],
"type": "fill"
}
],
"measurement": "nfsen_stats",
"policy": "default",
"query": "SELECT mean(\"$counter\")/300 FROM \"nfsen_stats\" WHERE \"profile\" =~ /^$profile$/ AND \"channel\" =~ /^$channel$/ AND \"profilegroup\" =~ /^$group$/ AND $timeFilter GROUP BY time($interval), \"channel\", \"profile\" fill(null)",
"rawQuery": true,
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"$counter"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": [
{
"key": "profile",
"operator": "=~",
"value": "/^$profile$/"
},
{
"condition": "AND",
"key": "channel",
"operator": "=~",
"value": "/^$channel$/"
},
{
"condition": "AND",
"key": "profilegroup",
"operator": "=~",
"value": "/^$group$/"
}
]
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "RATE $counter on channel $channel profile $profile",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "bps",
"label": "",
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_NFSEN}",
"editable": true,
"error": false,
"fill": 4,
"grid": {},
"id": 2,
"legend": {
"alignAsTable": true,
"avg": true,
"current": false,
"max": true,
"min": true,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": true,
"steppedLine": false,
"targets": [
{
"dsType": "influxdb",
"groupBy": [
{
"params": [
"$interval"
],
"type": "time"
},
{
"params": [
"channel"
],
"type": "tag"
},
{
"params": [
"profile"
],
"type": "tag"
},
{
"params": [
"null"
],
"type": "fill"
}
],
"measurement": "nfsen_stats",
"policy": "default",
"query": "SELECT sum(\"$counter\") FROM \"nfsen_stats\" WHERE \"profile\" =~ /^$profile$/ AND \"channel\" =~ /^$channel$/ AND \"profilegroup\" =~ /^$group$/ AND $timeFilter GROUP BY time($interval), \"channel\", \"profile\" fill(null)",
"rawQuery": true,
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"$counter"
],
"type": "field"
},
{
"params": [],
"type": "sum"
}
]
],
"tags": [
{
"key": "profile",
"operator": "=~",
"value": "/^$profile$/"
},
{
"condition": "AND",
"key": "channel",
"operator": "=~",
"value": "/^$channel$/"
},
{
"condition": "AND",
"key": "profilegroup",
"operator": "=~",
"value": "/^$group$/"
}
]
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "SUM $counter on channel $channel profile $profile",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "bits",
"label": "",
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"repeat": null,
"repeatIteration": null,
"repeatRowId": null,
"showTitle": false,
"title": "Row",
"titleSize": "h6"
},
{
"collapse": false,
"height": "250px",
"panels": [
{
"columns": [],
"datasource": "${DS_NFSEN}",
"editable": true,
"error": false,
"fontSize": "100%",
"id": 3,
"interval": ">5m",
"links": [],
"pageSize": null,
"scroll": true,
"showHeader": true,
"sort": {
"col": 0,
"desc": true
},
"span": 12,
"styles": [
{
"dateFormat": "YYYY-MM-DD HH:mm:ss",
"pattern": "Time",
"type": "hidden"
},
{
"colorMode": null,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"decimals": 2,
"pattern": "/.*/",
"thresholds": [],
"type": "number",
"unit": "bytes"
}
],
"targets": [
{
"alias": "",
"dsType": "influxdb",
"groupBy": [
{
"params": [
"profile"
],
"type": "tag"
},
{
"params": [
"channel"
],
"type": "tag"
}
],
"measurement": "nfsen_stats",
"policy": "default",
"query": "SELECT mean(\"$counter\"), max(\"$counter\") FROM \"nfsen_stats\" WHERE \"profile\" =~ /^$profile$/ AND \"channel\" =~ /^$channel$/ AND \"profilegroup\" =~ /^$group$/ AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false,
"refId": "A",
"resultFormat": "table",
"select": [
[
{
"params": [
"traffic"
],
"type": "field"
},
{
"params": [],
"type": "sum"
},
{
"params": [
"traffic"
],
"type": "alias"
}
],
[
{
"params": [
"traffic_icmp"
],
"type": "field"
},
{
"params": [],
"type": "sum"
},
{
"params": [
"icmp"
],
"type": "alias"
}
],
[
{
"params": [
"traffic_tcp"
],
"type": "field"
},
{
"params": [],
"type": "sum"
},
{
"params": [
"tcp"
],
"type": "alias"
}
],
[
{
"params": [
"traffic_udp"
],
"type": "field"
},
{
"params": [],
"type": "sum"
},
{
"params": [
"udp"
],
"type": "alias"
}
],
[
{
"params": [
"traffic_other"
],
"type": "field"
},
{
"params": [],
"type": "sum"
},
{
"params": [
"other"
],
"type": "alias"
}
]
],
"tags": [
{
"key": "profile",
"operator": "=~",
"value": "/^$profile$/"
},
{
"condition": "AND",
"key": "channel",
"operator": "=~",
"value": "/^$channel$/"
}
]
}
],
"title": "$counter on channel $channel profile $profile",
"transform": "table",
"type": "table"
}
],
"repeat": null,
"repeatIteration": null,
"repeatRowId": null,
"showTitle": false,
"title": "New row",
"titleSize": "h6"
}
],
"schemaVersion": 14,
"style": "dark",
"tags": [],
"templating": {
"list": [
{
"allValue": ".*",
"current": {},
"datasource": "${DS_NFSEN}",
"hide": 0,
"includeAll": true,
"label": "Group",
"multi": true,
"name": "group",
"options": [],
"query": "SHOW TAG VALUES FROM \"nfsen_stats\" WITH KEY = \"profilegroup\"",
"refresh": 1,
"regex": "",
"sort": 0,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"allValue": ".*",
"current": {},
"datasource": "${DS_NFSEN}",
"hide": 0,
"includeAll": true,
"label": "Profile",
"multi": true,
"name": "profile",
"options": [],
"query": "SHOW TAG VALUES FROM \"nfsen_stats\" WITH KEY = \"profile\"",
"refresh": 1,
"regex": "",
"sort": 0,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"allValue": null,
"current": {},
"datasource": "${DS_NFSEN}",
"hide": 0,
"includeAll": true,
"label": "Channel",
"multi": true,
"name": "channel",
"options": [],
"query": "SHOW TAG VALUES FROM \"nfsen_stats\" WITH KEY = \"channel\" WHERE profile =~ /$profile/",
"refresh": 1,
"regex": "",
"sort": 0,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"allValue": null,
"current": {},
"datasource": "${DS_NFSEN}",
"hide": 0,
"includeAll": false,
"label": "Counter",
"multi": false,
"name": "counter",
"options": [],
"query": "SHOW FIELD KEYS FROM \"nfsen_stats\"",
"refresh": 1,
"regex": "",
"sort": 0,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
}
]
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "browser",
"title": "Nfsen Stats",
"version": 22
}

View File

@ -0,0 +1,131 @@
Index: bin/nfsend
===================================================================
--- bin/nfsend (revision 27)
+++ bin/nfsend (working copy)
@@ -66,6 +66,61 @@
my $VERSION = '$Id$';
my $nfsen_version = "1.3";
+
+########## TODO INFLUXDB #########
+use LWP::UserAgent;
+my $ua;
+my $influxdb_url;
+my $influxdb_measurement;
+
+sub UpdateInflux {
+ my $timeslot = shift;
+ my $channel= shift;
+ my $profilegroup= shift;
+ my $profilename= shift;
+ my $statinfo= shift;
+
+ if ($profilegroup eq "."){
+ $profilegroup="ROOT";
+ }
+
+ my $post_data = "$influxdb_measurement,channel=$channel,profilegroup=$profilegroup,profile=$profilename v=1";
+
+ #foreach my $ds ( @NfSen::RRD::RRD_DS ) {
+ foreach my $ds ( @NfSenRRD::RRD_DS ) {
+ if ( !defined $$statinfo{$ds} || $$statinfo{$ds} == - 1 ) {
+ $post_data.=",$ds=0";
+ } else {
+ $post_data.=",$ds=$$statinfo{$ds}";
+ }
+ }
+
+ $post_data .= " $timeslot";
+ $post_data .= "000000000";
+
+ syslog("debug","$influxdb_url $post_data");
+
+ my $req = HTTP::Request->new(POST => $influxdb_url);
+ $req->content($post_data);
+
+ my $resp = $ua->request($req);
+ my $response = $resp->as_string();
+
+ syslog("debug"," $response ");
+
+ if ( $resp->is_success ) {
+
+ } else {
+ syslog("err","Error $response");
+ }
+
+ if ( $resp->code != 204 ) {
+ syslog("err","Unable to post data to influxdb $influxdb_url: $response ".$resp->code);
+ }
+}
+
+############################################################
+
my $forever = 1;
my $reload = 0;
@@ -373,7 +428,7 @@
$profileinfo{'updated'} = $timeslot;
if ( $profilegroup eq '.' && $profilename eq 'live' ) {
- # update live RRD database - other profiles were already updated by nfpofile
+ # update live RRD database - other profiles were already updated by nfprofile
foreach my $channel ( NfProfile::ProfileChannels(\%profileinfo) ) {
my ($statinfo, $exit_code, $err ) = NfProfile::ReadStatInfo(\%profileinfo, $channel, $subdirs, $t_iso, undef);
@@ -395,6 +450,12 @@
if ( $Log::ERROR ) {
syslog('err', "ERROR Update RRD time: '$t_iso', db: '$channel', profile: '$profilename' group '$profilegroup' : $Log::ERROR");
}
+
+ ########## TODO INFLUX #########
+ if( $influxdb_url ) {
+ UpdateInflux($timeslot,$channel,$profilegroup,$profilename, $statinfo);
+ }
+ #################################
}
}
@@ -699,6 +760,17 @@
Log::LogInit();
syslog("info", "Startup. Version: $nfsen_version $VERSION");
+########## TODO INFLUXDB #########
+$influxdb_url = "$NfConf::influxdb_url";
+$influxdb_measurement = "$NfConf::influxdb_measurement";
+
+if($influxdb_url) {
+ $ua = LWP::UserAgent->new;
+ $ua->timeout( 10 );
+ syslog("info","Enabled INFLUXDB on $influxdb_url");
+}
+###################################
+
my $arg = shift @ARGV;
$arg = '' unless defined $arg;
die "Unknow argument '$arg'" if $arg ne '' && $arg ne 'once';
Index: libexec/NfConf.pm
===================================================================
--- libexec/NfConf.pm (revision 27)
+++ libexec/NfConf.pm (working copy)
@@ -73,6 +73,9 @@
our $BACKEND_PLUGINDIR;
our $PICDIR;
+#INFLUXDB
+our $influxdb_url;
+our $influxdb_measurement;
# Alerting email vars
our $MAIL_FROM;
@@ -137,6 +140,10 @@
$ZIPprofiles = 0;
$LogSocket = $^O eq "solaris" ? 'stream' : 'unix';
+
+ #INFLUXDB
+ $influxdb_url = undef;
+ $influxdb_measurement = "nfsen_stats";
# Read Configuration
if ( ! open( TMP, $CONFFILE) ) {

View File

@ -0,0 +1,141 @@
Index: bin/nfsend
===================================================================
--- bin/nfsend (revision 27)
+++ bin/nfsend (working copy)
@@ -55,6 +55,60 @@
use NfSen::Comm;
use NfSen::Log;
+########## TODO INFLUXDB #########
+use LWP::UserAgent;
+my $ua;
+my $influxdb_url;
+my $influxdb_measurement;
+
+sub UpdateInflux {
+ my $timeslot = shift;
+ my $channel= shift;
+ my $profilegroup= shift;
+ my $profilename= shift;
+ my $statinfo= shift;
+
+ if ($profilegroup eq "."){
+ $profilegroup="ROOT";
+ }
+
+ my $post_data = "$influxdb_measurement,channel=$channel,profilegroup=$profilegroup,profile=$profilename v=1";
+
+ #foreach my $ds ( @NfSen::RRD::RRD_DS ) {
+ foreach my $ds ( @NfSenRRD::RRD_DS ) {
+ if ( !defined $$statinfo{$ds} || $$statinfo{$ds} == - 1 ) {
+ $post_data.=",$ds=0";
+ } else {
+ $post_data.=",$ds=$$statinfo{$ds}";
+ }
+ }
+
+ $post_data .= " $timeslot";
+ $post_data .= "000000000";
+
+ log_debug("$influxdb_url $post_data");
+
+ my $req = HTTP::Request->new(POST => $influxdb_url);
+ $req->content($post_data);
+
+ my $resp = $ua->request($req);
+ my $response = $resp->as_string();
+
+ log_debug(" $response ");
+
+ if ( $resp->is_success ) {
+
+ } else {
+ log_error("Error $response");
+ }
+
+ if ( $resp->code != 204 ) {
+ log_error("Unable to post data to influxdb $influxdb_url: $response ".$resp->code);
+ }
+}
+
+############################################################
+
my $forever = 1;
my $reload = 0;
@@ -279,7 +333,11 @@
my $arg = "-I -t $timeslot -p $pSpooldir -P $pDatadir $subdirlayout $compress";
my $flist = "-M $pSpooldir/live/$channellist -r nfcapd.$t_iso";
-
+########## TODO INFLUXDB #########
+ if ( $influxdb_url ){
+ $arg = "$arg -i $influxdb_url";
+ }
+##################################
if ( open NFPROFILE, "| nfprofile $arg $flist 2>&1" ) {
local $SIG{PIPE} = sub { log_error("Pipe broke for nfprofile"); };
foreach my $profileopts ( @ProfileOptList ) {
@@ -390,6 +448,13 @@
if ( $err ) {
log_error("ERROR Update RRD time: '$t_iso', db: '$channel', profile: '$profilename' group '$profilegroup'.");
}
+
+
+ ########## TODO INFLUX #########
+ if( $influxdb_url ) {
+ UpdateInflux($timeslot,$channel,$profilegroup,$profilename, $statinfo);
+ }
+ #################################
}
}
@@ -699,6 +764,20 @@
NfSen::Log::handle_stderr(3,4);
log_notice("Startup nfsend. Version: $NfSen::VERSION");
+########## TODO INFLUXDB #########
+$influxdb_url = NfSen::Conf::database('influxdb_url');
+$influxdb_measurement = NfSen::Conf::database('influxdb_measurement');
+if($influxdb_url) {
+ if (!$influxdb_measurement){
+ $influxdb_measurement = "nfsen_stats";
+ }
+ $ua = LWP::UserAgent->new;
+ $ua->timeout( 10 );
+
+ log_notice("Enabled INFLUXDB on $influxdb_url to $influxdb_measurement");
+}
+###################################
+
my $arg = shift @ARGV;
$arg = '' unless defined $arg;
die "Unknow argument '$arg'" if $arg ne '' && $arg ne 'once';
Index: etc/backend.conf-dist
===================================================================
--- etc/backend.conf-dist (revision 27)
+++ etc/backend.conf-dist (working copy)
@@ -101,6 +101,11 @@
[database]
###############
+# INFLUX
+#influxdb_url = http://<hostname>:8086/write?db=<dbname>
+#influxdb_measurement = nfsen_stats
+
+###############
# Type of DB (manager) to use.
# Supported types are: mysql, csv, sqlite, postgresql
#
Index: .
===================================================================
--- . (revision 27)
+++ . (working copy)
Property changes on: .
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,3 ##
+.project
+
+.includepath