Merge pull request #51 Influxdb from Luca
This commit is contained in:
parent
0ea114f8ce
commit
2b4cfc7e8a
@ -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)
|
||||
|
11
README.md
11
README.md
@ -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
|
||||
|
@ -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);
|
||||
|
100
bin/profile.c
100
bin/profile.c
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
20
configure.ac
20
configure.ac
@ -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],
|
||||
[
|
||||
|
661
extra/grafana/Nfsen_Stats.json
Normal file
661
extra/grafana/Nfsen_Stats.json
Normal 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
|
||||
}
|
131
extra/nfsen/nfsen-1.6-stats-influxdb.patch
Normal file
131
extra/nfsen/nfsen-1.6-stats-influxdb.patch
Normal 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) ) {
|
141
extra/nfsen/nfsen-trunk-stats-influxdb.patch
Normal file
141
extra/nfsen/nfsen-trunk-stats-influxdb.patch
Normal 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
|
Loading…
x
Reference in New Issue
Block a user