25#include <sys/socket.h>
26#include <netinet/in.h>
36#define INFLUX_MEAS(m) IF_TYPE_MEAS, (m)
37#define INFLUX_TAG(k, v) IF_TYPE_TAG, (k), (v)
38#define INFLUX_F_STR(k, v) IF_TYPE_FIELD_STRING, (k), (v)
39#define INFLUX_F_FLT(k, v, p) IF_TYPE_FIELD_FLOAT, (k), (double)(v), (int)(p)
40#define INFLUX_F_INT(k, v) IF_TYPE_FIELD_INTEGER, (k), (long long)(v)
41#define INFLUX_F_BOL(k, v) IF_TYPE_FIELD_BOOLEAN, (k), ((v) ? 1 : 0)
42#define INFLUX_TS(ts) IF_TYPE_TIMESTAMP, (long long)(ts)
43#define INFLUX_END IF_TYPE_ARG_END
83int format_line(
char** buf,
int* len,
size_t used, ...);
115#define IF_TYPE_ARG_END 0
116#define IF_TYPE_MEAS 1
118#define IF_TYPE_FIELD_STRING 3
119#define IF_TYPE_FIELD_FLOAT 4
120#define IF_TYPE_FIELD_INTEGER 5
121#define IF_TYPE_FIELD_BOOLEAN 6
122#define IF_TYPE_TIMESTAMP 7
124int _escaped_append(
char** dest,
size_t* len,
size_t* used,
const char* src,
const char* escape_seq);
152 int sock = -1, ret_code = 0, content_length = 0;
153 struct sockaddr_in addr;
157 iv[1].iov_base = buf;
160 if (!(iv[0].iov_base = (
char*)malloc(len = 0x800))) {
161 free(iv[1].iov_base);
167 snprintf((
char*)iv[0].iov_base, len,
168 "POST /write?db=%s&u=%s&p=%s HTTP/1.1\r\n"
170 "Accept: application/json\r\n"
171 "Content-type: text/plain\r\n"
172 "Authorization: Token %s\r\n"
173 "Content-Length: %zd\r\n"
176 if ((
int)iv[0].iov_len >= len && !(iv[0].iov_base = (
char*)realloc(iv[0].iov_base, len *= 2))) {
177 free(iv[1].iov_base);
178 free(iv[0].iov_base);
184 fprintf(stderr,
"influxdb-c::post_http: iv[0] = '%s'\n", (
char*)iv[0].iov_base);
185 fprintf(stderr,
"influxdb-c::post_http: iv[1] = '%s'\n", (
char*)iv[1].iov_base);
187 addr.sin_family = AF_INET;
188 addr.sin_port = htons(c->
port);
190 struct hostent* resolved_host = gethostbyname(c->
host);
191 if (!resolved_host) {
192 free(iv[1].iov_base);
193 free(iv[0].iov_base);
196 memcpy(&addr.sin_addr, resolved_host->h_addr_list[0], resolved_host->h_length);
205 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
206 free(iv[1].iov_base);
207 free(iv[0].iov_base);
211 if (connect(sock, (
struct sockaddr*)(&addr),
sizeof(addr)) < 0) {
216 if (writev(sock, iv, 2) < (
int)(iv[0].iov_len + iv[1].iov_len)) {
222#define _GET_NEXT_CHAR() \
223 (ch = (len >= (int)iv[0].iov_len && \
224 (iv[0].iov_len = recv(sock, iv[0].iov_base, iv[0].iov_len, len = 0)) == (size_t)(-1) \
226 : *((char*)iv[0].iov_base + len++)))
227#define _LOOP_NEXT(statement) \
229 if (!(_GET_NEXT_CHAR())) { \
235#define _UNTIL(c) _LOOP_NEXT(if (ch == c) break;)
236#define _GET_NUMBER(n) _LOOP_NEXT(if (ch >= '0' && ch <= '9') n = n * 10 + (ch - '0'); else break;)
238 if ((_GET_NEXT_CHAR()) != c) \
249 _(
'n')
_(
't')
_(
'-')
_(
'L')
_(
'e')
_(
'n')
_(
'g')
_(
't')
_(
'h')
_(
':')
_(
' ')
_GET_NUMBER(content_length)
break;
264 free(iv[0].iov_base);
265 free(iv[1].iov_base);
266 return ret_code / 100 == 2 ? 0 : ret_code;
277 int ret_code = 0, len = 0;
291 int sock = -1, ret = 0;
292 struct sockaddr_in addr;
294 addr.sin_family = AF_INET;
295 addr.sin_port = htons(c->
port);
296 if ((addr.sin_addr.s_addr = inet_addr(c->
host)) == INADDR_NONE) {
301 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
306 if (sendto(sock, line, len, 0, (
struct sockaddr*)&addr,
sizeof(addr)) < len)
344 curl_global_init(CURL_GLOBAL_ALL);
348 curl = curl_easy_init();
350 return CURLE_FAILED_INIT;
353 char* url_string = (
char*)malloc(len);
354 snprintf(url_string, len,
"http://%s:%d/api/v2/write?org=%s&bucket=%s&precision=%s", c->
host ? c->
host :
"localhost",
357 curl_easy_setopt(curl, CURLOPT_URL, url_string);
360 char token_string[120];
361 snprintf(token_string,
sizeof(token_string),
"Authorization: Token %s", c->
token);
363 struct curl_slist* list = NULL;
364 list = curl_slist_append(list, token_string);
365 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
367 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
368 curl_easy_setopt(curl, CURLOPT_USERAGENT,
"libcurl-agent/1.0");
371 res = curl_easy_perform(curl);
373 if (res != CURLE_OK) {
374 fprintf(stderr,
"curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
378 curl_easy_cleanup(curl);
379 curl_global_cleanup();
396 if (!(*buf = (
char*)malloc(len)))
408#define _APPEND(fmter...) \
410 if ((written = snprintf(*buf + used, len - used, ##fmter)) < 0) \
412 if (used + written >= len && !(*buf = (char*)realloc(*buf, len *= 2))) \
421 int written = 0, type = 0, last_type = 0;
422 unsigned long long i = 0;
430 type = va_arg(ap,
int);
460 d = va_arg(ap,
double);
465 i = va_arg(ap,
long long);
475 i = va_arg(ap,
long long);
482 type = va_arg(ap,
int);
496int _escaped_append(
char** dest,
size_t* len,
size_t* used,
const char* src,
const char* escape_seq) {
500 if ((i = strcspn(src, escape_seq)) > 0) {
501 if (*used + i > *len && !(*dest = (
char*)realloc(*dest, (*len) *= 2)))
503 strncpy(*dest + *used, src, i);
508 if (*used + 2 > *len && !(*dest = (
char*)realloc(*dest, (*len) *= 2)))
510 (*dest)[(*used)++] =
'\\';
511 (*dest)[(*used)++] = *src++;
int format_line(char **buf, int *len, size_t used,...)
Format a line for InfluxDB.
Definition influxdb.h:383
int send_udp(influx_client_t *c,...)
Send a line to InfluxDB via UDP.
Definition influxdb.h:316
int post_http_send_line(influx_client_t *c, char *buf, int len)
Post a line to InfluxDB via HTTP.
Definition influxdb.h:151
int send_udp_line(influx_client_t *c, char *line, int len)
Send a line to InfluxDB via UDP.
Definition influxdb.h:290
int post_curl(influx_v2_client_t *c,...)
Post a line to InfluxDB via HTTP.
Definition influxdb.h:333
int post_http(influx_client_t *c,...)
Post a line to InfluxDB via HTTP.
Definition influxdb.h:274
#define _APPEND(fmter...)
int _format_line2(char **buf, va_list ap, size_t *, size_t)
Definition influxdb.h:407
#define IF_TYPE_TAG
Definition influxdb.h:117
#define IF_TYPE_ARG_END
Definition influxdb.h:115
#define IF_TYPE_FIELD_STRING
Definition influxdb.h:118
#define IF_TYPE_FIELD_BOOLEAN
Definition influxdb.h:121
int _escaped_append(char **dest, size_t *len, size_t *used, const char *src, const char *escape_seq)
Definition influxdb.h:496
int _format_line(char **buf, va_list ap)
Definition influxdb.h:401
#define IF_TYPE_FIELD_INTEGER
Definition influxdb.h:120
#define IF_TYPE_TIMESTAMP
Definition influxdb.h:122
#define IF_TYPE_FIELD_FLOAT
Definition influxdb.h:119
#define IF_TYPE_MEAS
Definition influxdb.h:116
int _begin_line(char **buf)
Definition influxdb.h:394
InfluxDB client.
Definition influxdb.h:49
char * token
Definition influxdb.h:55
char * pwd
Definition influxdb.h:54
int port
Definition influxdb.h:51
char * host
Definition influxdb.h:50
char * db
Definition influxdb.h:52
char * usr
Definition influxdb.h:53
InfluxDB v2 client.
Definition influxdb.h:62
int port
Definition influxdb.h:64
char * pwd
Definition influxdb.h:69
char * token
Definition influxdb.h:70
char * usr
Definition influxdb.h:68
char * precision
Definition influxdb.h:67
char * bucket
Definition influxdb.h:66
char * host
Definition influxdb.h:63
char * org
Definition influxdb.h:65