Merge branch 'develop'
This commit is contained in:
commit
e1fafcc4b1
|
@ -118,6 +118,7 @@ system/netdata.service.*
|
|||
system/netdata.plist
|
||||
system/netdata-freebsd
|
||||
system/edit-config
|
||||
system/netdata.crontab
|
||||
|
||||
daemon/anonymous-statistics.sh
|
||||
daemon/get-kubernetes-labels.sh
|
||||
|
|
|
@ -783,6 +783,8 @@ set(MONGODB_BACKEND_FILES
|
|||
)
|
||||
|
||||
set(DAEMON_FILES
|
||||
daemon/buildinfo.c
|
||||
daemon/buildinfo.h
|
||||
daemon/common.c
|
||||
daemon/common.h
|
||||
daemon/daemon.c
|
||||
|
|
|
@ -618,6 +618,8 @@ MONGODB_BACKEND_FILES = \
|
|||
$(NULL)
|
||||
|
||||
DAEMON_FILES = \
|
||||
daemon/buildinfo.c \
|
||||
daemon/buildinfo.h \
|
||||
daemon/common.c \
|
||||
daemon/common.h \
|
||||
daemon/daemon.c \
|
||||
|
|
|
@ -104,8 +104,11 @@ static int aclk_handle_cloud_request_v2(struct aclk_request *cloud_to_agent, cha
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (unlikely(aclk_v2_payload_get_query(data, cloud_to_agent)))
|
||||
if (unlikely(aclk_v2_payload_get_query(data, cloud_to_agent))) {
|
||||
error("Could not extract payload from query");
|
||||
freez(data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (unlikely(!cloud_to_agent->callback_topic)) {
|
||||
error("Missing callback_topic");
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
-e 's#[@]pluginsdir_POST@#$(pluginsdir)#g' \
|
||||
-e 's#[@]configdir_POST@#$(configdir)#g' \
|
||||
-e 's#[@]libconfigdir_POST@#$(libconfigdir)#g' \
|
||||
-e 's#[@]pkglibexecdir_POST@#$(pkglibexecdir)#g' \
|
||||
-e 's#[@]cachedir_POST@#$(cachedir)#g' \
|
||||
-e 's#[@]registrydir_POST@#$(registrydir)#g' \
|
||||
-e 's#[@]varlibdir_POST@#$(varlibdir)#g' \
|
||||
|
|
16
configure.ac
16
configure.ac
|
@ -43,7 +43,6 @@ AC_PROG_INSTALL
|
|||
PKG_PROG_PKG_CONFIG
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# configurable options
|
||||
|
||||
|
@ -329,7 +328,6 @@ AC_CHECK_LIB(
|
|||
)
|
||||
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# zlib
|
||||
|
||||
|
@ -382,6 +380,9 @@ AC_CHECK_LIB(
|
|||
[ssl_host_validation="no"]
|
||||
)
|
||||
|
||||
test -z "${SSL_LIBS}" || \
|
||||
AC_DEFINE([HAVE_CRYPTO], [1], [libcrypto availability])
|
||||
|
||||
if test "${ssl_host_validation}" = "no"; then
|
||||
AC_DEFINE([HAVE_X509_VERIFY_PARAM_set1_host], [0], [ssl host validation])
|
||||
AC_MSG_WARN([DISABLING SSL HOSTNAME VALIDATION BECAUSE IT IS NOT AVAILABLE ON THIS SYSTEM.])
|
||||
|
@ -705,6 +706,7 @@ AM_CONDITIONAL([ENABLE_ACLK], [test "${enable_aclk}" = "yes"])
|
|||
|
||||
AC_MSG_CHECKING([if apps.plugin should be enabled])
|
||||
if test "${build_target}" != "macos"; then
|
||||
AC_DEFINE([ENABLE_APPS_PLUGIN], [1], [apps.plugin])
|
||||
enable_plugin_apps="yes"
|
||||
else
|
||||
enable_plugin_apps="no"
|
||||
|
@ -972,6 +974,7 @@ AC_CHECK_HEADER(
|
|||
|
||||
AC_MSG_CHECKING([if perf.plugin should be enabled])
|
||||
if test "${build_target}" == "linux" -a "${have_perf_event}" = "yes"; then
|
||||
AC_DEFINE([ENABLE_PERF_PLUGIN], [1], [perf.plugin])
|
||||
enable_plugin_perf="yes"
|
||||
else
|
||||
enable_plugin_perf="no"
|
||||
|
@ -1023,6 +1026,7 @@ AM_CONDITIONAL([ENABLE_PLUGIN_EBPF], [test "${enable_ebpf}" = "yes"])
|
|||
|
||||
AC_MSG_CHECKING([if slabinfo.plugin should be enabled])
|
||||
if test "${build_target}" == "linux"; then
|
||||
AC_DEFINE([ENABLE_SLABINFO], [1], [slabinfo plugin])
|
||||
enable_plugin_slabinfo="yes"
|
||||
else
|
||||
enable_plugin_slabinfo="no"
|
||||
|
@ -1459,6 +1463,14 @@ TEST_LIBS="${CMOCKA_LIBS}"
|
|||
AC_SUBST([TEST_CFLAGS])
|
||||
AC_SUBST([TEST_LIBS])
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# save configure options for build info
|
||||
AC_DEFINE_UNQUOTED(
|
||||
[CONFIGURE_COMMAND],
|
||||
["$ac_configure_args"],
|
||||
[options passed to configure script]
|
||||
)
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
netdata.spec
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <stdio.h>
|
||||
#include "./config.h"
|
||||
|
||||
// Optional features
|
||||
|
||||
#ifdef ENABLE_ACLK
|
||||
#define FEAT_CLOUD "YES"
|
||||
#else
|
||||
#ifdef DISABLE_CLOUD
|
||||
#define FEAT_CLOUD "NO (by user request e.g. '--disable-cloud')"
|
||||
#else
|
||||
#define FEAT_CLOUD "NO"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_DBENGINE
|
||||
#define FEAT_DBENGINE "YES"
|
||||
#else
|
||||
#define FEAT_DBENGINE "NO"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_X509_VERIFY_PARAM_set1_host) && HAVE_X509_VERIFY_PARAM_set1_host == 1
|
||||
#define FEAT_TLS_HOST_VERIFY "YES"
|
||||
#else
|
||||
#define FEAT_TLS_HOST_VERIFY "NO"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
#define FEAT_NATIVE_HTTPS "YES"
|
||||
#else
|
||||
#define FEAT_NATIVE_HTTPS "NO"
|
||||
#endif
|
||||
|
||||
// Optional libraries
|
||||
|
||||
#ifdef ENABLE_JSONC
|
||||
#define FEAT_JSONC "YES"
|
||||
#else
|
||||
#define FEAT_JSONC "NO"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_JEMALLOC
|
||||
#define FEAT_JEMALLOC "YES"
|
||||
#else
|
||||
#define FEAT_JEMALLOC "NO"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_TCMALLOC
|
||||
#define FEAT_TCMALLOC "YES"
|
||||
#else
|
||||
#define FEAT_TCMALLOC "NO"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CAPABILITY
|
||||
#define FEAT_LIBCAP "YES"
|
||||
#else
|
||||
#define FEAT_LIBCAP "NO"
|
||||
#endif
|
||||
|
||||
#ifdef ACLK_NO_LIBMOSQ
|
||||
#define FEAT_MOSQUITTO "NO"
|
||||
#else
|
||||
#define FEAT_MOSQUITTO "YES"
|
||||
#endif
|
||||
|
||||
#ifdef ACLK_NO_LWS
|
||||
#define FEAT_LWS "NO"
|
||||
#else
|
||||
#define FEAT_LWS "YES"
|
||||
#endif
|
||||
|
||||
#ifdef NETDATA_WITH_ZLIB
|
||||
#define FEAT_ZLIB "YES"
|
||||
#else
|
||||
#define FEAT_ZLIB "NO"
|
||||
#endif
|
||||
|
||||
#ifdef STORAGE_WITH_MATH
|
||||
#define FEAT_LIBM "YES"
|
||||
#else
|
||||
#define FEAT_LIBM "NO"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CRYPTO
|
||||
#define FEAT_CRYPTO "YES"
|
||||
#else
|
||||
#define FEAT_CRYPTO "NO"
|
||||
#endif
|
||||
|
||||
// Optional plugins
|
||||
|
||||
#ifdef ENABLE_APPS_PLUGIN
|
||||
#define FEAT_APPS_PLUGIN "YES"
|
||||
#else
|
||||
#define FEAT_APPS_PLUGIN "NO"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FREEIPMI
|
||||
#define FEAT_IPMI "YES"
|
||||
#else
|
||||
#define FEAT_IPMI "NO"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CUPS
|
||||
#define FEAT_CUPS "YES"
|
||||
#else
|
||||
#define FEAT_CUPS "NO"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBMNL
|
||||
#define FEAT_NFACCT "YES"
|
||||
#else
|
||||
#define FEAT_NFACCT "NO"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBXENSTAT
|
||||
#define FEAT_XEN "YES"
|
||||
#else
|
||||
#define FEAT_XEN "NO"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XENSTAT_VBD_ERROR
|
||||
#define FEAT_XEN_VBD_ERROR "YES"
|
||||
#else
|
||||
#define FEAT_XEN_VBD_ERROR "NO"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBBPF
|
||||
#define FEAT_EBPF "YES"
|
||||
#else
|
||||
#define FEAT_EBPF "NO"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETNS
|
||||
#define FEAT_CGROUP_NET "YES"
|
||||
#else
|
||||
#define FEAT_CGROUP_NET "NO"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_PERF_PLUGIN
|
||||
#define FEAT_PERF "YES"
|
||||
#else
|
||||
#define FEAT_PERF "NO"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SLABINFO
|
||||
#define FEAT_SLABINFO "YES"
|
||||
#else
|
||||
#define FEAT_SLABINFO "NO"
|
||||
#endif
|
||||
|
||||
// Optional Exporters
|
||||
|
||||
#ifdef HAVE_KINESIS
|
||||
#define FEAT_KINESIS "YES"
|
||||
#else
|
||||
#define FEAT_KINESIS "NO"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_EXPORTING_PUBSUB
|
||||
#define FEAT_PUBSUB "YES"
|
||||
#else
|
||||
#define FEAT_PUBSUB "NO"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MONGOC
|
||||
#define FEAT_MONGO "YES"
|
||||
#else
|
||||
#define FEAT_MONGO "NO"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_PROMETHEUS_REMOTE_WRITE
|
||||
#define FEAT_REMOTE_WRITE "YES"
|
||||
#else
|
||||
#define FEAT_REMOTE_WRITE "NO"
|
||||
#endif
|
||||
|
||||
|
||||
void print_build_info(void) {
|
||||
printf("Configure options: %s\n", CONFIGURE_COMMAND);
|
||||
|
||||
printf("Features:\n");
|
||||
printf(" dbengine: %s\n", FEAT_DBENGINE);
|
||||
printf(" Native HTTPS: %s\n", FEAT_NATIVE_HTTPS);
|
||||
printf(" Netdata Cloud: %s\n", FEAT_CLOUD);
|
||||
printf(" TLS Host Verification: %s\n", FEAT_TLS_HOST_VERIFY);
|
||||
|
||||
printf("Libraries:\n");
|
||||
printf(" jemalloc: %s\n", FEAT_JEMALLOC);
|
||||
printf(" JSON-C: %s\n", FEAT_JSONC);
|
||||
printf(" libcap: %s\n", FEAT_LIBCAP);
|
||||
printf(" libcrypto: %s\n", FEAT_CRYPTO);
|
||||
printf(" libm: %s\n", FEAT_LIBM);
|
||||
printf(" LWS: %s\n", FEAT_LWS);
|
||||
printf(" mosquitto: %s\n", FEAT_MOSQUITTO);
|
||||
printf(" tcalloc: %s\n", FEAT_TCMALLOC);
|
||||
printf(" zlib: %s\n", FEAT_ZLIB);
|
||||
|
||||
printf("Plugins:\n");
|
||||
printf(" apps: %s\n", FEAT_APPS_PLUGIN);
|
||||
printf(" cgroup Network Tracking: %s\n", FEAT_CGROUP_NET);
|
||||
printf(" CUPS: %s\n", FEAT_CUPS);
|
||||
printf(" EBPF: %s\n", FEAT_EBPF);
|
||||
printf(" IPMI: %s\n", FEAT_IPMI);
|
||||
printf(" NFACCT: %s\n", FEAT_NFACCT);
|
||||
printf(" perf: %s\n", FEAT_PERF);
|
||||
printf(" slabinfo: %s\n", FEAT_SLABINFO);
|
||||
printf(" Xen: %s\n", FEAT_XEN);
|
||||
printf(" Xen VBD Error Tracking: %s\n", FEAT_XEN_VBD_ERROR);
|
||||
|
||||
printf("Exporters:\n");
|
||||
printf(" AWS Kinesis: %s\n", FEAT_KINESIS);
|
||||
printf(" GCP PubSub: %s\n", FEAT_PUBSUB);
|
||||
printf(" MongoDB: %s\n", FEAT_MONGO);
|
||||
printf(" Prometheus Remote Write: %s\n", FEAT_REMOTE_WRITE);
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#ifndef NETDATA_BUILDINFO_H
|
||||
#define NETDATA_BUILDINFO_H 1
|
||||
|
||||
extern void print_build_info(void);
|
||||
|
||||
#endif // NETDATA_BUILDINFO_H
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "common.h"
|
||||
#include "buildinfo.h"
|
||||
|
||||
int netdata_zero_metrics_enabled;
|
||||
int netdata_anonymous_statistics_enabled;
|
||||
|
@ -1255,6 +1256,11 @@ int main(int argc, char **argv) {
|
|||
/* will trigger a claiming attempt when the agent is initialized */
|
||||
claiming_pending_arguments = optarg + strlen(claim_string);
|
||||
}
|
||||
else if(strcmp(optarg, "buildinfo") == 0) {
|
||||
printf("Version: %s %s\n", program_name, program_version);
|
||||
print_build_info();
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Unknown -W parameter '%s'\n", optarg);
|
||||
return help(1);
|
||||
|
|
|
@ -1673,7 +1673,7 @@ static int test_dbengine_check_rrdr(RRDSET *st[CHARTS], RRDDIM *rd[CHARTS][DIMS]
|
|||
update_every = REGION_UPDATE_EVERY[current_region];
|
||||
long points = (time_end - time_start) / update_every - 1;
|
||||
for (i = 0 ; i < CHARTS ; ++i) {
|
||||
RRDR *r = rrd2rrdr(st[i], points, time_start + update_every, time_end, RRDR_GROUPING_AVERAGE, 0, 0, NULL);
|
||||
RRDR *r = rrd2rrdr(st[i], points, time_start + update_every, time_end, RRDR_GROUPING_AVERAGE, 0, 0, NULL, NULL);
|
||||
if (!r) {
|
||||
fprintf(stderr, " DB-engine unittest %s: empty RRDR ### E R R O R ###\n", st[i]->name);
|
||||
return ++errors;
|
||||
|
@ -1792,7 +1792,7 @@ int test_dbengine(void)
|
|||
long points = (time_end[REGIONS - 1] - time_start[0]) / update_every - 1; // cover all time regions with RRDR
|
||||
long point_offset = (time_start[current_region] - time_start[0]) / update_every;
|
||||
for (i = 0 ; i < CHARTS ; ++i) {
|
||||
RRDR *r = rrd2rrdr(st[i], points, time_start[0] + update_every, time_end[REGIONS - 1], RRDR_GROUPING_AVERAGE, 0, 0, NULL);
|
||||
RRDR *r = rrd2rrdr(st[i], points, time_start[0] + update_every, time_end[REGIONS - 1], RRDR_GROUPING_AVERAGE, 0, 0, NULL, NULL);
|
||||
if (!r) {
|
||||
fprintf(stderr, " DB-engine unittest %s: empty RRDR ### E R R O R ###\n", st[i]->name);
|
||||
++errors;
|
||||
|
|
|
@ -376,7 +376,7 @@ static inline uint32_t *pginfo_to_points(struct rrdeng_page_info *page_info)
|
|||
* @return number of regions with different data collection intervals.
|
||||
*/
|
||||
unsigned rrdeng_variable_step_boundaries(RRDSET *st, time_t start_time, time_t end_time,
|
||||
struct rrdeng_region_info **region_info_arrayp, unsigned *max_intervalp)
|
||||
struct rrdeng_region_info **region_info_arrayp, unsigned *max_intervalp, RRDDIM *temp_rd)
|
||||
{
|
||||
struct pg_cache_page_index *page_index;
|
||||
struct rrdengine_instance *ctx;
|
||||
|
@ -397,7 +397,7 @@ unsigned rrdeng_variable_step_boundaries(RRDSET *st, time_t start_time, time_t e
|
|||
page_info_array = NULL;
|
||||
|
||||
rrdset_rdlock(st);
|
||||
for(rd_iter = st->dimensions, rd = NULL, min_time = (usec_t)-1 ; rd_iter ; rd_iter = rd_iter->next) {
|
||||
for(rd_iter = temp_rd?temp_rd:st->dimensions, rd = NULL, min_time = (usec_t)-1 ; rd_iter ; rd_iter = rd_iter->next) {
|
||||
/*
|
||||
* Choose oldest dimension as reference. This is not equivalent to the union of all dimensions
|
||||
* but it is a best effort approximation with a bias towards older metrics in a chart. It
|
||||
|
|
|
@ -43,7 +43,7 @@ extern void rrdeng_store_metric_next(RRDDIM *rd, usec_t point_in_time, storage_n
|
|||
extern int rrdeng_store_metric_finalize(RRDDIM *rd);
|
||||
extern unsigned
|
||||
rrdeng_variable_step_boundaries(RRDSET *st, time_t start_time, time_t end_time,
|
||||
struct rrdeng_region_info **region_info_arrayp, unsigned *max_intervalp);
|
||||
struct rrdeng_region_info **region_info_arrayp, unsigned *max_intervalp, RRDDIM *temp_rd);
|
||||
extern void rrdeng_load_metric_init(RRDDIM *rd, struct rrddim_query_handle *rrdimm_handle,
|
||||
time_t start_time, time_t end_time);
|
||||
extern storage_number rrdeng_load_metric_next(struct rrddim_query_handle *rrdimm_handle, time_t *current_time);
|
||||
|
|
|
@ -1053,6 +1053,19 @@ static inline time_t rrdset_first_entry_t(RRDSET *st) {
|
|||
}
|
||||
}
|
||||
|
||||
// get the timestamp of the last entry in the round robin database
|
||||
static inline time_t rrddim_last_entry_t(RRDDIM *rd) {
|
||||
if (rd->rrdset->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
|
||||
return rd->state->query_ops.latest_time(rd);
|
||||
return (time_t)rd->rrdset->last_updated.tv_sec;
|
||||
}
|
||||
|
||||
static inline time_t rrddim_first_entry_t(RRDDIM *rd) {
|
||||
if (rd->rrdset->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
|
||||
return rd->state->query_ops.oldest_time(rd);
|
||||
return (time_t)(rd->rrdset->last_updated.tv_sec - rrdset_duration(rd->rrdset));
|
||||
}
|
||||
|
||||
time_t rrdhost_last_entry_t(RRDHOST *h);
|
||||
|
||||
// get the last slot updated in the round robin database
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
#TODO: Temporary fix for the build-id error during go.d plugin set up
|
||||
%global _missing_build_ids_terminate_build 0
|
||||
|
||||
# XXX: We are using automatic `Requires:` generation for libraries
|
||||
# whenever possible, DO NOT LIST LIBRARY DEPENDENCIES UNLESS THE RESULTANT
|
||||
# PACKAGE IS BROKEN WITHOUT THEM.
|
||||
AutoReqProv: yes
|
||||
|
||||
%if "@HAVE_LIBBPF@" == "1"
|
||||
%global have_bpf 1
|
||||
%else
|
||||
|
@ -148,31 +153,10 @@ BuildRequires: json-c-devel
|
|||
# Runtime dependencies
|
||||
#
|
||||
Requires: python
|
||||
Requires: zlib
|
||||
%if 0%{?suse_version}
|
||||
# for libuv, Requires version >= 1
|
||||
Requires: libuv1
|
||||
Requires: libJudy1
|
||||
Requires: libjson-c4
|
||||
Requires: libuuid1
|
||||
%else
|
||||
# for libuv, Requires version >= 1
|
||||
Requires: libuv >= 1
|
||||
Requires: Judy
|
||||
Requires: json-c
|
||||
Requires: libuuid
|
||||
%endif
|
||||
Requires: openssl
|
||||
Requires: lz4
|
||||
|
||||
# Core requirements for the install to succeed
|
||||
Requires(pre): /usr/sbin/groupadd
|
||||
Requires(pre): /usr/sbin/useradd
|
||||
%if 0%{?suse_version} >= 1140
|
||||
Requires(post): libcap1
|
||||
%else
|
||||
Requires(post): libcap
|
||||
%endif
|
||||
|
||||
%{netdata_initd_requires}
|
||||
|
||||
|
@ -188,19 +172,6 @@ BuildRequires: libmnl-devel
|
|||
BuildRequires: libnetfilter_acct-devel
|
||||
%endif
|
||||
|
||||
%if 0%{?suse_version}
|
||||
Requires: libmnl0
|
||||
%else
|
||||
Requires: libmnl
|
||||
%endif
|
||||
|
||||
%if 0%{?fedora}
|
||||
Requires: libnetfilter_acct
|
||||
%else
|
||||
%if 0%{?suse_version} >= 1140
|
||||
Requires: libnetfilter_acct1
|
||||
%endif
|
||||
%endif
|
||||
# end nfacct plugin dependencies
|
||||
|
||||
# freeipmi plugin dependencies
|
||||
|
@ -221,16 +192,6 @@ BuildRequires: libprotobuf-c-devel
|
|||
%else
|
||||
BuildRequires: protobuf-c-devel
|
||||
%endif
|
||||
|
||||
%if 0%{?suse_version}
|
||||
Requires: libsnappy1
|
||||
Requires: protobuf-c
|
||||
Requires: libprotobuf15
|
||||
%else
|
||||
Requires: snappy
|
||||
Requires: protobuf-c
|
||||
Requires: protobuf
|
||||
%endif
|
||||
# end - prometheus remote write dependencies
|
||||
|
||||
# #####################################################################
|
||||
|
@ -559,6 +520,8 @@ are sensor monitoring, system event monitoring, power control, and serial-over-L
|
|||
%attr(4750,root,netdata) %{_libexecdir}/%{name}/plugins.d/freeipmi.plugin
|
||||
|
||||
%changelog
|
||||
* Wed Sep 16 2020 Austin Hemmelgarn <austin@netdata.cloud> 0.0.0-14
|
||||
- Convert to using 'AutoReq: yes' for library dependencies.
|
||||
* Thu Feb 13 2020 Austin Hemmelgarn <austin@netdata.cloud> 0.0.0-13
|
||||
- Add handling for custom libmosquitto fork
|
||||
* Wed Jan 01 2020 Austin Hemmelgarn <austin@netdata.cloud> 0.0.0-12
|
||||
|
|
|
@ -898,23 +898,22 @@ safe_sha256sum() {
|
|||
fi
|
||||
}
|
||||
|
||||
_get_crondir() {
|
||||
_get_scheduler_type() {
|
||||
if _get_intervaldir > /dev/null ; then
|
||||
echo 'interval'
|
||||
elif [ -d /etc/cron.d ] ; then
|
||||
echo 'crontab'
|
||||
else
|
||||
echo 'none'
|
||||
fi
|
||||
}
|
||||
|
||||
_get_intervaldir() {
|
||||
if [ -d /etc/cron.daily ]; then
|
||||
echo /etc/cron.daily
|
||||
elif [ -d /etc/periodic/daily ]; then
|
||||
echo /etc/periodic/daily
|
||||
else
|
||||
echo >&2 "Cannot figure out the cron directory to handle netdata-updater.sh activation/deactivation"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_check_crondir_permissions() {
|
||||
if [ "${UID}" -ne "0" ]; then
|
||||
# We cant touch cron if we are not running as root
|
||||
echo >&2 "You need to run the installer as root for auto-updating via cron"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
@ -945,49 +944,68 @@ cleanup_old_netdata_updater() {
|
|||
rm -f "${NETDATA_PREFIX}"/usr/libexec/netdata-updater.sh
|
||||
fi
|
||||
|
||||
crondir="$(_get_crondir)" || return 1
|
||||
_check_crondir_permissions "${crondir}" || return 1
|
||||
if [ -d /etc/cron.daily ]; then
|
||||
rm -f /etc/cron.daily/netdata-updater.sh
|
||||
rm -f /etc/cron.daily/netdata-updater
|
||||
fi
|
||||
|
||||
if [ -f "${crondir}/netdata-updater.sh" ]; then
|
||||
echo >&2 "Removing incorrect netdata-updater filename in cron"
|
||||
rm -f "${crondir}/netdata-updater.sh"
|
||||
if [ -d /etc/periodic/daily ]; then
|
||||
rm -f /etc/periodic/daily/netdata-updater.sh
|
||||
rm -f /etc/periodic/daily/netdata-updater
|
||||
fi
|
||||
|
||||
if [ -d /etc/cron.d ]; then
|
||||
rm -f /etc/cron.d/netdata-updater
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
enable_netdata_updater() {
|
||||
crondir="$(_get_crondir)" || return 1
|
||||
_check_crondir_permissions "${crondir}" || return 1
|
||||
case "$(_get_scheduler_type)" in
|
||||
"interval")
|
||||
ln -sf "${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh" "$(_get_interval_dir)/netdata-updater"
|
||||
|
||||
echo >&2 "Adding to cron"
|
||||
echo >&2 "Auto-updating has been enabled through cron, updater script linked to ${TPUT_RED}${TPUT_BOLD}$(_get_interval_dir)/netdata-updater${TPUT_RESET}"
|
||||
echo >&2
|
||||
echo >&2 "If the update process fails and you have email notifications set up correctly for cron on this system, you should receive an email notification of the failure."
|
||||
echo >&2 "Successful updates will not send an email."
|
||||
echo >&2
|
||||
;;
|
||||
"crontab")
|
||||
cat "${NETDATA_SOURCE_DIR}/system/netdata.crontab" > "/etc/cron.d/netdata-updater"
|
||||
|
||||
rm -f "${crondir}/netdata-updater"
|
||||
ln -sf "${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh" "${crondir}/netdata-updater"
|
||||
|
||||
echo >&2 "Auto-updating has been enabled. Updater script linked to: ${TPUT_RED}${TPUT_BOLD}${crondir}/netdata-updater${TPUT_RESET}"
|
||||
echo >&2
|
||||
echo >&2 "${TPUT_DIM}${TPUT_BOLD}netdata-updater.sh${TPUT_RESET}${TPUT_DIM} works from cron. It will trigger an email from cron"
|
||||
echo >&2 "only if it fails (it should not print anything when it can update netdata).${TPUT_RESET}"
|
||||
echo >&2
|
||||
echo >&2 "Auto-updating has been enabled through cron, using a crontab at ${TPUT_RED}${TPUT_BOLD}/etc/cron.d/netdata${TPUT_RESET}"
|
||||
echo >&2
|
||||
echo >&2 "If the update process fails and you have email notifications set up correctly for cron on this system, you should receive an email notification of the failure."
|
||||
echo >&2 "Successful updates will not send an email."
|
||||
echo >&2
|
||||
;;
|
||||
*)
|
||||
echo >&2 "Unable to determine what type of auto-update scheduling to use, not enabling auto-updates."
|
||||
echo >&2
|
||||
return 1
|
||||
esac
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
disable_netdata_updater() {
|
||||
crondir="$(_get_crondir)" || return 1
|
||||
_check_crondir_permissions "${crondir}" || return 1
|
||||
|
||||
echo >&2 "You chose *NOT* to enable auto-update, removing any links to the updater from cron (it may have happened if you are reinstalling)"
|
||||
echo >&2
|
||||
|
||||
if [ -f "${crondir}/netdata-updater" ]; then
|
||||
echo >&2 "Removing cron reference: ${crondir}/netdata-updater"
|
||||
echo >&2
|
||||
rm -f "${crondir}/netdata-updater"
|
||||
else
|
||||
echo >&2 "Did not find any cron entries to remove"
|
||||
echo >&2
|
||||
if [ -d /etc/cron.daily ]; then
|
||||
rm -f /etc/cron.daily/netdata-updater.sh
|
||||
rm -f /etc/cron.daily/netdata-updater
|
||||
fi
|
||||
|
||||
if [ -d /etc/periodic/daily ]; then
|
||||
rm -f /etc/periodic/daily/netdata-updater.sh
|
||||
rm -f /etc/periodic/daily/netdata-updater
|
||||
fi
|
||||
|
||||
if [ -d /etc/cron.d ]; then
|
||||
rm -f /etc/cron.d/netdata-updater
|
||||
fi
|
||||
|
||||
return 0
|
||||
|
|
|
@ -456,6 +456,8 @@ rm_file /usr/lib/systemd/system/netdata.service
|
|||
rm_file /etc/init.d/netdata
|
||||
rm_file /etc/periodic/daily/netdata-updater
|
||||
rm_file /etc/cron.daily/netdata-updater
|
||||
rm_file /etc/cron.d/netdata-updater
|
||||
|
||||
|
||||
if [ -n "${NETDATA_PREFIX}" ] && [ -d "${NETDATA_PREFIX}" ]; then
|
||||
rm_dir "${NETDATA_PREFIX}"
|
||||
|
|
|
@ -12,6 +12,7 @@ CLEANFILES = \
|
|||
netdata-lsb \
|
||||
netdata-freebsd \
|
||||
netdata.plist \
|
||||
netdata.crontab \
|
||||
$(NULL)
|
||||
|
||||
include $(top_srcdir)/build/subst.inc
|
||||
|
@ -34,6 +35,7 @@ nodist_noinst_DATA = \
|
|||
netdata-lsb \
|
||||
netdata-freebsd \
|
||||
netdata.plist \
|
||||
netdata.crontab \
|
||||
$(NULL)
|
||||
|
||||
dist_noinst_DATA = \
|
||||
|
@ -47,4 +49,5 @@ dist_noinst_DATA = \
|
|||
netdata-freebsd.in \
|
||||
netdata.plist.in \
|
||||
netdata.conf \
|
||||
netdata.crontab.in \
|
||||
$(NULL)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
2 57 * * * root @pkglibexecdir_POST@/netdata-updater.sh
|
|
@ -3,7 +3,7 @@
|
|||
#include "libnetdata/libnetdata.h"
|
||||
#include "csv.h"
|
||||
|
||||
void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, const char *startline, const char *separator, const char *endline, const char *betweenlines) {
|
||||
void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, const char *startline, const char *separator, const char *endline, const char *betweenlines, RRDDIM *temp_rd) {
|
||||
rrdset_check_rdlock(r->st);
|
||||
|
||||
//info("RRD2CSV(): %s: BEGIN", r->st->id);
|
||||
|
@ -11,7 +11,7 @@ void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, const
|
|||
RRDDIM *d;
|
||||
|
||||
// print the csv header
|
||||
for(c = 0, i = 0, d = r->st->dimensions; d && c < r->d ;c++, d = d->next) {
|
||||
for(c = 0, i = 0, d = temp_rd?temp_rd:r->st->dimensions; d && c < r->d ;c++, d = d->next) {
|
||||
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
||||
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
|
||||
|
||||
|
@ -31,7 +31,7 @@ void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, const
|
|||
|
||||
if(format == DATASOURCE_CSV_MARKDOWN) {
|
||||
// print the --- line after header
|
||||
for(c = 0, i = 0, d = r->st->dimensions; d && c < r->d ;c++, d = d->next) {
|
||||
for(c = 0, i = 0, d = temp_rd?temp_rd:r->st->dimensions; d && c < r->d ;c++, d = d->next) {
|
||||
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
||||
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
|
||||
|
||||
|
@ -89,7 +89,7 @@ void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, const
|
|||
int set_min_max = 0;
|
||||
if(unlikely(options & RRDR_OPTION_PERCENTAGE)) {
|
||||
total = 0;
|
||||
for(c = 0, d = r->st->dimensions; d && c < r->d ;c++, d = d->next) {
|
||||
for(c = 0, d = temp_rd?temp_rd:r->st->dimensions; d && c < r->d ;c++, d = d->next) {
|
||||
calculated_number n = cn[c];
|
||||
|
||||
if(likely((options & RRDR_OPTION_ABSOLUTE) && n < 0))
|
||||
|
@ -103,7 +103,7 @@ void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, const
|
|||
}
|
||||
|
||||
// for each dimension
|
||||
for(c = 0, d = r->st->dimensions; d && c < r->d ;c++, d = d->next) {
|
||||
for(c = 0, d = temp_rd?temp_rd:r->st->dimensions; d && c < r->d ;c++, d = d->next) {
|
||||
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
||||
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "web/api/queries/rrdr.h"
|
||||
|
||||
extern void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, const char *startline, const char *separator, const char *endline, const char *betweenlines);
|
||||
extern void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, const char *startline, const char *separator, const char *endline, const char *betweenlines, RRDDIM *temp_rd);
|
||||
|
||||
#include "../rrd2json.h"
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#define JSON_DATES_JS 1
|
||||
#define JSON_DATES_TIMESTAMP 2
|
||||
|
||||
void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable) {
|
||||
void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable, RRDDIM *temp_rd) {
|
||||
rrdset_check_rdlock(r->st);
|
||||
|
||||
//info("RRD2JSON(): %s: BEGIN", r->st->id);
|
||||
|
@ -94,12 +94,14 @@ void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable) {
|
|||
RRDDIM *rd;
|
||||
|
||||
// print the header lines
|
||||
for(c = 0, i = 0, rd = r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
for(c = 0, i = 0, rd = temp_rd?temp_rd:r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
||||
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
|
||||
|
||||
buffer_strcat(wb, pre_label);
|
||||
buffer_strcat(wb, rd->name);
|
||||
// buffer_strcat(wb, ".");
|
||||
// buffer_strcat(wb, rd->rrdset->name);
|
||||
buffer_strcat(wb, post_label);
|
||||
i++;
|
||||
}
|
||||
|
@ -154,7 +156,7 @@ void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable) {
|
|||
if(row_annotations) {
|
||||
// google supports one annotation per row
|
||||
int annotation_found = 0;
|
||||
for(c = 0, rd = r->st->dimensions; rd ;c++, rd = rd->next) {
|
||||
for(c = 0, rd = temp_rd?temp_rd:r->st->dimensions; rd ;c++, rd = rd->next) {
|
||||
if(unlikely(!(r->od[c] & RRDR_DIMENSION_SELECTED))) continue;
|
||||
|
||||
if(co[c] & RRDR_VALUE_RESET) {
|
||||
|
@ -185,7 +187,7 @@ void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable) {
|
|||
int set_min_max = 0;
|
||||
if(unlikely(options & RRDR_OPTION_PERCENTAGE)) {
|
||||
total = 0;
|
||||
for(c = 0, rd = r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
for(c = 0, rd = temp_rd?temp_rd:r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
calculated_number n = cn[c];
|
||||
|
||||
if(likely((options & RRDR_OPTION_ABSOLUTE) && n < 0))
|
||||
|
@ -199,7 +201,7 @@ void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable) {
|
|||
}
|
||||
|
||||
// for each dimension
|
||||
for(c = 0, rd = r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
for(c = 0, rd = temp_rd?temp_rd:r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
||||
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
|
||||
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
|
||||
#include "../rrd2json.h"
|
||||
|
||||
extern void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable);
|
||||
extern void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable, RRDDIM *temp_rd);
|
||||
|
||||
#endif //NETDATA_API_FORMATTER_JSON_H
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "json_wrapper.h"
|
||||
|
||||
void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, int string_value) {
|
||||
void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, int string_value, RRDDIM *temp_rd) {
|
||||
rrdset_check_rdlock(r->st);
|
||||
|
||||
long rows = rrdr_rows(r);
|
||||
|
@ -34,8 +34,8 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS
|
|||
" %safter%s: %u,\n"
|
||||
" %sdimension_names%s: ["
|
||||
, kq, kq
|
||||
, kq, kq, sq, r->st->id, sq
|
||||
, kq, kq, sq, r->st->name, sq
|
||||
, kq, kq, sq, temp_rd?r->st->context:r->st->id, sq
|
||||
, kq, kq, sq, temp_rd?r->st->context:r->st->name, sq
|
||||
, kq, kq, r->update_every
|
||||
, kq, kq, r->st->update_every
|
||||
, kq, kq, (uint32_t)rrdset_first_entry_t(r->st)
|
||||
|
@ -44,7 +44,7 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS
|
|||
, kq, kq, (uint32_t)r->after
|
||||
, kq, kq);
|
||||
|
||||
for(c = 0, i = 0, rd = r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
for(c = 0, i = 0, rd = temp_rd?temp_rd:r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
||||
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
|
||||
|
||||
|
@ -68,7 +68,7 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS
|
|||
" %sdimension_ids%s: ["
|
||||
, kq, kq);
|
||||
|
||||
for(c = 0, i = 0, rd = r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
for(c = 0, i = 0, rd = temp_rd?temp_rd:r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
||||
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
|
||||
|
||||
|
@ -85,11 +85,41 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS
|
|||
buffer_strcat(wb, sq);
|
||||
}
|
||||
|
||||
// Composite charts
|
||||
if (temp_rd) {
|
||||
buffer_sprintf(
|
||||
wb,
|
||||
"],\n"
|
||||
" %schart_ids%s: [",
|
||||
kq, kq);
|
||||
|
||||
for (c = 0, i = 0, rd = temp_rd ; rd && c < r->d; c++, rd = rd->next) {
|
||||
if (unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN))
|
||||
continue;
|
||||
if (unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO)))
|
||||
continue;
|
||||
|
||||
if (i)
|
||||
buffer_strcat(wb, ", ");
|
||||
buffer_strcat(wb, sq);
|
||||
buffer_strcat(wb, rd->rrdset->name);
|
||||
buffer_strcat(wb, sq);
|
||||
i++;
|
||||
}
|
||||
if (!i) {
|
||||
rows = 0;
|
||||
buffer_strcat(wb, sq);
|
||||
buffer_strcat(wb, "no data");
|
||||
buffer_strcat(wb, sq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buffer_sprintf(wb, "],\n"
|
||||
" %slatest_values%s: ["
|
||||
, kq, kq);
|
||||
|
||||
for(c = 0, i = 0, rd = r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
for(c = 0, i = 0, rd = temp_rd?temp_rd:r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
||||
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
|
||||
|
||||
|
@ -125,7 +155,7 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS
|
|||
|
||||
if(unlikely(options & RRDR_OPTION_PERCENTAGE)) {
|
||||
total = 0;
|
||||
for(c = 0, rd = r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
for(c = 0, rd = temp_rd?temp_rd:r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
calculated_number *cn = &r->v[ (rrdr_rows(r) - 1) * r->d ];
|
||||
calculated_number n = cn[c];
|
||||
|
||||
|
@ -138,7 +168,7 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS
|
|||
if(total == 0) total = 1;
|
||||
}
|
||||
|
||||
for(c = 0, i = 0, rd = r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
for(c = 0, i = 0, rd = temp_rd?temp_rd:r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
|
||||
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
||||
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "rrd2json.h"
|
||||
|
||||
extern void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, int string_value);
|
||||
extern void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, int string_value, RRDDIM *temp_rd);
|
||||
extern void rrdr_json_wrapper_end(RRDR *r, BUFFER *wb, uint32_t format, uint32_t options, int string_value);
|
||||
|
||||
#endif //NETDATA_API_FORMATTER_JSON_WRAPPER_H
|
||||
|
|
|
@ -2,6 +2,26 @@
|
|||
|
||||
#include "web/api/web_api_v1.h"
|
||||
|
||||
static inline void free_temp_rrddim(RRDDIM *temp_rd)
|
||||
{
|
||||
if (unlikely(!temp_rd))
|
||||
return;
|
||||
|
||||
RRDDIM *t;
|
||||
while (temp_rd) {
|
||||
t = temp_rd->next;
|
||||
freez((char *)temp_rd->id);
|
||||
freez((char *)temp_rd->name);
|
||||
#ifdef ENABLE_DBENGINE
|
||||
if (temp_rd->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
|
||||
freez(temp_rd->state->metric_uuid);
|
||||
#endif
|
||||
freez(temp_rd->state);
|
||||
freez(temp_rd);
|
||||
temp_rd = t;
|
||||
}
|
||||
}
|
||||
|
||||
void rrd_stats_api_v1_chart(RRDSET *st, BUFFER *wb) {
|
||||
rrdset2json(st, wb, NULL, NULL, 0);
|
||||
}
|
||||
|
@ -69,7 +89,10 @@ int rrdset2value_api_v1(
|
|||
, time_t *db_before
|
||||
, int *value_is_null
|
||||
) {
|
||||
RRDR *r = rrd2rrdr(st, points, after, before, group_method, group_time, options, dimensions);
|
||||
RRDDIM *temp_rd = NULL;
|
||||
|
||||
RRDR *r = rrd2rrdr(st, points, after, before, group_method, group_time, options, dimensions, temp_rd);
|
||||
|
||||
if(!r) {
|
||||
if(value_is_null) *value_is_null = 1;
|
||||
return HTTP_RESP_INTERNAL_SERVER_ERROR;
|
||||
|
@ -98,6 +121,8 @@ int rrdset2value_api_v1(
|
|||
long i = (!(options & RRDR_OPTION_REVERSED))?rrdr_rows(r) - 1:0;
|
||||
*n = rrdr2value(r, i, options, value_is_null);
|
||||
|
||||
free_temp_rrddim(temp_rd);
|
||||
|
||||
rrdr_free(r);
|
||||
return HTTP_RESP_OK;
|
||||
}
|
||||
|
@ -114,10 +139,47 @@ int rrdset2anything_api_v1(
|
|||
, long group_time
|
||||
, uint32_t options
|
||||
, time_t *latest_timestamp
|
||||
, char *context
|
||||
) {
|
||||
st->last_accessed_time = now_realtime_sec();
|
||||
time_t last_accessed_time = now_realtime_sec();
|
||||
st->last_accessed_time = last_accessed_time;
|
||||
|
||||
RRDR *r = rrd2rrdr(st, points, after, before, group_method, group_time, options, dimensions?buffer_tostring(dimensions):NULL);
|
||||
RRDDIM *temp_rd = NULL;
|
||||
|
||||
if (context) {
|
||||
rrdhost_rdlock(st->rrdhost);
|
||||
RRDSET *st1;
|
||||
rrdset_foreach_read(st1, st->rrdhost) {
|
||||
if (strcmp(st1->context, context) == 0) {
|
||||
// Loop the dimensions of the chart
|
||||
RRDDIM *rd1;
|
||||
rrdset_rdlock(st1);
|
||||
st1->last_accessed_time = last_accessed_time;
|
||||
rrddim_foreach_read(rd1, st1) {
|
||||
RRDDIM *rd = mallocz(rd1->memsize);
|
||||
memcpy(rd, rd1, rd1->memsize);
|
||||
rd->id = strdupz(rd1->id);
|
||||
rd->name = strdupz(rd1->name);
|
||||
rd->state = mallocz(sizeof(*rd->state));
|
||||
memcpy(rd->state, rd1->state, sizeof(*rd->state));
|
||||
memcpy(&rd->state->collect_ops, &rd1->state->collect_ops, sizeof(struct rrddim_collect_ops));
|
||||
memcpy(&rd->state->query_ops, &rd1->state->query_ops, sizeof(struct rrddim_query_ops));
|
||||
#ifdef ENABLE_DBENGINE
|
||||
if (rd->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) {
|
||||
rd->state->metric_uuid = mallocz(sizeof(uuid_t));
|
||||
uuid_copy(*rd->state->metric_uuid, *rd1->state->metric_uuid);
|
||||
}
|
||||
#endif
|
||||
rd->next = temp_rd;
|
||||
temp_rd = rd;
|
||||
}
|
||||
rrdset_unlock(st1);
|
||||
}
|
||||
}
|
||||
rrdhost_unlock(st->rrdhost);
|
||||
}
|
||||
|
||||
RRDR *r = rrd2rrdr(st, points, after, before, group_method, group_time, options, dimensions?buffer_tostring(dimensions):NULL, temp_rd);
|
||||
if(!r) {
|
||||
buffer_strcat(wb, "Cannot generate output with these parameters on this chart.");
|
||||
return HTTP_RESP_INTERNAL_SERVER_ERROR;
|
||||
|
@ -135,7 +197,7 @@ int rrdset2anything_api_v1(
|
|||
case DATASOURCE_SSV:
|
||||
if(options & RRDR_OPTION_JSON_WRAP) {
|
||||
wb->contenttype = CT_APPLICATION_JSON;
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 1);
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 1, temp_rd);
|
||||
rrdr2ssv(r, wb, options, "", " ", "");
|
||||
rrdr_json_wrapper_end(r, wb, format, options, 1);
|
||||
}
|
||||
|
@ -148,7 +210,7 @@ int rrdset2anything_api_v1(
|
|||
case DATASOURCE_SSV_COMMA:
|
||||
if(options & RRDR_OPTION_JSON_WRAP) {
|
||||
wb->contenttype = CT_APPLICATION_JSON;
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 1);
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 1, temp_rd);
|
||||
rrdr2ssv(r, wb, options, "", ",", "");
|
||||
rrdr_json_wrapper_end(r, wb, format, options, 1);
|
||||
}
|
||||
|
@ -161,7 +223,7 @@ int rrdset2anything_api_v1(
|
|||
case DATASOURCE_JS_ARRAY:
|
||||
if(options & RRDR_OPTION_JSON_WRAP) {
|
||||
wb->contenttype = CT_APPLICATION_JSON;
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 0);
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 0, temp_rd);
|
||||
rrdr2ssv(r, wb, options, "[", ",", "]");
|
||||
rrdr_json_wrapper_end(r, wb, format, options, 0);
|
||||
}
|
||||
|
@ -174,42 +236,42 @@ int rrdset2anything_api_v1(
|
|||
case DATASOURCE_CSV:
|
||||
if(options & RRDR_OPTION_JSON_WRAP) {
|
||||
wb->contenttype = CT_APPLICATION_JSON;
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 1);
|
||||
rrdr2csv(r, wb, format, options, "", ",", "\\n", "");
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 1, temp_rd);
|
||||
rrdr2csv(r, wb, format, options, "", ",", "\\n", "", temp_rd);
|
||||
rrdr_json_wrapper_end(r, wb, format, options, 1);
|
||||
}
|
||||
else {
|
||||
wb->contenttype = CT_TEXT_PLAIN;
|
||||
rrdr2csv(r, wb, format, options, "", ",", "\r\n", "");
|
||||
rrdr2csv(r, wb, format, options, "", ",", "\r\n", "", temp_rd);
|
||||
}
|
||||
break;
|
||||
|
||||
case DATASOURCE_CSV_MARKDOWN:
|
||||
if(options & RRDR_OPTION_JSON_WRAP) {
|
||||
wb->contenttype = CT_APPLICATION_JSON;
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 1);
|
||||
rrdr2csv(r, wb, format, options, "", "|", "\\n", "");
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 1, temp_rd);
|
||||
rrdr2csv(r, wb, format, options, "", "|", "\\n", "", temp_rd);
|
||||
rrdr_json_wrapper_end(r, wb, format, options, 1);
|
||||
}
|
||||
else {
|
||||
wb->contenttype = CT_TEXT_PLAIN;
|
||||
rrdr2csv(r, wb, format, options, "", "|", "\r\n", "");
|
||||
rrdr2csv(r, wb, format, options, "", "|", "\r\n", "", temp_rd);
|
||||
}
|
||||
break;
|
||||
|
||||
case DATASOURCE_CSV_JSON_ARRAY:
|
||||
wb->contenttype = CT_APPLICATION_JSON;
|
||||
if(options & RRDR_OPTION_JSON_WRAP) {
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 0);
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 0, temp_rd);
|
||||
buffer_strcat(wb, "[\n");
|
||||
rrdr2csv(r, wb, format, options + RRDR_OPTION_LABEL_QUOTES, "[", ",", "]", ",\n");
|
||||
rrdr2csv(r, wb, format, options + RRDR_OPTION_LABEL_QUOTES, "[", ",", "]", ",\n", temp_rd);
|
||||
buffer_strcat(wb, "\n]");
|
||||
rrdr_json_wrapper_end(r, wb, format, options, 0);
|
||||
}
|
||||
else {
|
||||
wb->contenttype = CT_APPLICATION_JSON;
|
||||
buffer_strcat(wb, "[\n");
|
||||
rrdr2csv(r, wb, format, options + RRDR_OPTION_LABEL_QUOTES, "[", ",", "]", ",\n");
|
||||
rrdr2csv(r, wb, format, options + RRDR_OPTION_LABEL_QUOTES, "[", ",", "]", ",\n", temp_rd);
|
||||
buffer_strcat(wb, "\n]");
|
||||
}
|
||||
break;
|
||||
|
@ -217,29 +279,29 @@ int rrdset2anything_api_v1(
|
|||
case DATASOURCE_TSV:
|
||||
if(options & RRDR_OPTION_JSON_WRAP) {
|
||||
wb->contenttype = CT_APPLICATION_JSON;
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 1);
|
||||
rrdr2csv(r, wb, format, options, "", "\t", "\\n", "");
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 1, temp_rd);
|
||||
rrdr2csv(r, wb, format, options, "", "\t", "\\n", "", temp_rd);
|
||||
rrdr_json_wrapper_end(r, wb, format, options, 1);
|
||||
}
|
||||
else {
|
||||
wb->contenttype = CT_TEXT_PLAIN;
|
||||
rrdr2csv(r, wb, format, options, "", "\t", "\r\n", "");
|
||||
rrdr2csv(r, wb, format, options, "", "\t", "\r\n", "", temp_rd);
|
||||
}
|
||||
break;
|
||||
|
||||
case DATASOURCE_HTML:
|
||||
if(options & RRDR_OPTION_JSON_WRAP) {
|
||||
wb->contenttype = CT_APPLICATION_JSON;
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 1);
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 1, temp_rd);
|
||||
buffer_strcat(wb, "<html>\\n<center>\\n<table border=\\\"0\\\" cellpadding=\\\"5\\\" cellspacing=\\\"5\\\">\\n");
|
||||
rrdr2csv(r, wb, format, options, "<tr><td>", "</td><td>", "</td></tr>\\n", "");
|
||||
rrdr2csv(r, wb, format, options, "<tr><td>", "</td><td>", "</td></tr>\\n", "", temp_rd);
|
||||
buffer_strcat(wb, "</table>\\n</center>\\n</html>\\n");
|
||||
rrdr_json_wrapper_end(r, wb, format, options, 1);
|
||||
}
|
||||
else {
|
||||
wb->contenttype = CT_TEXT_HTML;
|
||||
buffer_strcat(wb, "<html>\n<center>\n<table border=\"0\" cellpadding=\"5\" cellspacing=\"5\">\n");
|
||||
rrdr2csv(r, wb, format, options, "<tr><td>", "</td><td>", "</td></tr>\n", "");
|
||||
rrdr2csv(r, wb, format, options, "<tr><td>", "</td><td>", "</td></tr>\n", "", temp_rd);
|
||||
buffer_strcat(wb, "</table>\n</center>\n</html>\n");
|
||||
}
|
||||
break;
|
||||
|
@ -248,9 +310,9 @@ int rrdset2anything_api_v1(
|
|||
wb->contenttype = CT_APPLICATION_X_JAVASCRIPT;
|
||||
|
||||
if(options & RRDR_OPTION_JSON_WRAP)
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 0);
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 0, temp_rd);
|
||||
|
||||
rrdr2json(r, wb, options, 1);
|
||||
rrdr2json(r, wb, options, 1, temp_rd);
|
||||
|
||||
if(options & RRDR_OPTION_JSON_WRAP)
|
||||
rrdr_json_wrapper_end(r, wb, format, options, 0);
|
||||
|
@ -260,9 +322,9 @@ int rrdset2anything_api_v1(
|
|||
wb->contenttype = CT_APPLICATION_JSON;
|
||||
|
||||
if(options & RRDR_OPTION_JSON_WRAP)
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 0);
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 0, temp_rd);
|
||||
|
||||
rrdr2json(r, wb, options, 1);
|
||||
rrdr2json(r, wb, options, 1, temp_rd);
|
||||
|
||||
if(options & RRDR_OPTION_JSON_WRAP)
|
||||
rrdr_json_wrapper_end(r, wb, format, options, 0);
|
||||
|
@ -271,9 +333,9 @@ int rrdset2anything_api_v1(
|
|||
case DATASOURCE_JSONP:
|
||||
wb->contenttype = CT_APPLICATION_X_JAVASCRIPT;
|
||||
if(options & RRDR_OPTION_JSON_WRAP)
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 0);
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 0, temp_rd);
|
||||
|
||||
rrdr2json(r, wb, options, 0);
|
||||
rrdr2json(r, wb, options, 0, temp_rd);
|
||||
|
||||
if(options & RRDR_OPTION_JSON_WRAP)
|
||||
rrdr_json_wrapper_end(r, wb, format, options, 0);
|
||||
|
@ -284,15 +346,17 @@ int rrdset2anything_api_v1(
|
|||
wb->contenttype = CT_APPLICATION_JSON;
|
||||
|
||||
if(options & RRDR_OPTION_JSON_WRAP)
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 0);
|
||||
rrdr_json_wrapper_begin(r, wb, format, options, 0, temp_rd);
|
||||
|
||||
rrdr2json(r, wb, options, 0);
|
||||
rrdr2json(r, wb, options, 0, temp_rd);
|
||||
|
||||
if(options & RRDR_OPTION_JSON_WRAP)
|
||||
rrdr_json_wrapper_end(r, wb, format, options, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
free_temp_rrddim(temp_rd);
|
||||
|
||||
rrdr_free(r);
|
||||
return HTTP_RESP_OK;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ extern int rrdset2anything_api_v1(
|
|||
, long group_time
|
||||
, uint32_t options
|
||||
, time_t *latest_timestamp
|
||||
, char *context
|
||||
);
|
||||
|
||||
extern int rrdset2value_api_v1(
|
||||
|
|
|
@ -1091,6 +1091,35 @@
|
|||
"host2.example.com"
|
||||
]
|
||||
},
|
||||
"mirrored_hosts_status": {
|
||||
"type": "array",
|
||||
"description": "List of details of hosts mirrored to this served (including self). Indexes correspond to indexes in \"mirrored_hosts\".",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Host data",
|
||||
"properties": {
|
||||
"guid": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"nullable": false,
|
||||
"description": "Host unique GUID from `netdata.public.unique.id`.",
|
||||
"example": "245e4bff-3b34-47c1-a6e5-5c535a9abfb2"
|
||||
},
|
||||
"reachable": {
|
||||
"type": "boolean",
|
||||
"nullable": false,
|
||||
"description": "Current state of streaming. Always true for localhost/self."
|
||||
},
|
||||
"claim_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"nullable": true,
|
||||
"description": "Cloud GUID/identifier in case the host is claimed. If child status unknown or unclaimed this field is set to `null`",
|
||||
"example": "c3b2a66a-3052-498c-ac52-7fe9e8cccb0c"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"os_name": {
|
||||
"type": "string",
|
||||
"description": "Operating System Name.",
|
||||
|
|
|
@ -881,6 +881,33 @@ components:
|
|||
example:
|
||||
- host1.example.com
|
||||
- host2.example.com
|
||||
mirrored_hosts_status:
|
||||
type: array
|
||||
description: >-
|
||||
List of details of hosts mirrored to this served (including self).
|
||||
Indexes correspond to indexes in "mirrored_hosts".
|
||||
items:
|
||||
type: object
|
||||
description: Host data
|
||||
properties:
|
||||
guid:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: false
|
||||
description: Host unique GUID from `netdata.public.unique.id`.
|
||||
example: 245e4bff-3b34-47c1-a6e5-5c535a9abfb2
|
||||
reachable:
|
||||
type: boolean
|
||||
nullable: false
|
||||
description: Current state of streaming. Always true for localhost/self.
|
||||
claim_id:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
description: >-
|
||||
Cloud GUID/identifier in case the host is claimed.
|
||||
If child status unknown or unclaimed this field is set to `null`
|
||||
example: c3b2a66a-3052-498c-ac52-7fe9e8cccb0c
|
||||
os_name:
|
||||
type: string
|
||||
description: Operating System Name.
|
||||
|
|
|
@ -281,7 +281,7 @@ RRDR_GROUPING web_client_api_request_v1_data_group(const char *name, RRDR_GROUPI
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static void rrdr_disable_not_selected_dimensions(RRDR *r, RRDR_OPTIONS options, const char *dims) {
|
||||
static void rrdr_disable_not_selected_dimensions(RRDR *r, RRDR_OPTIONS options, const char *dims, RRDDIM *temp_rd) {
|
||||
rrdset_check_rdlock(r->st);
|
||||
|
||||
if(unlikely(!dims || !*dims || (dims[0] == '*' && dims[1] == '\0'))) return;
|
||||
|
@ -300,7 +300,7 @@ static void rrdr_disable_not_selected_dimensions(RRDR *r, RRDR_OPTIONS options,
|
|||
|
||||
RRDDIM *d;
|
||||
long c, dims_selected = 0, dims_not_hidden_not_zero = 0;
|
||||
for(c = 0, d = r->st->dimensions; d ;c++, d = d->next) {
|
||||
for(c = 0, d = temp_rd?temp_rd:r->st->dimensions; d ;c++, d = d->next) {
|
||||
if( (match_ids && simple_pattern_matches(pattern, d->id))
|
||||
|| (match_names && simple_pattern_matches(pattern, d->name))
|
||||
) {
|
||||
|
@ -332,7 +332,7 @@ static void rrdr_disable_not_selected_dimensions(RRDR *r, RRDR_OPTIONS options,
|
|||
// but they are all zero
|
||||
// enable the selected ones
|
||||
// to avoid returning an empty chart
|
||||
for(c = 0, d = r->st->dimensions; d ;c++, d = d->next)
|
||||
for(c = 0, d = temp_rd?temp_rd:r->st->dimensions; d ;c++, d = d->next)
|
||||
if(unlikely(r->od[c] & RRDR_DIMENSION_SELECTED))
|
||||
r->od[c] |= RRDR_DIMENSION_NONZERO;
|
||||
}
|
||||
|
@ -815,7 +815,8 @@ static RRDR *rrd2rrdr_fixedstep(
|
|||
, int update_every
|
||||
, time_t first_entry_t
|
||||
, time_t last_entry_t
|
||||
, int absolute_period_requested
|
||||
, int absolute_period_requested,
|
||||
RRDDIM *temp_rd
|
||||
) {
|
||||
int aligned = !(options & RRDR_OPTION_NOT_ALIGNED);
|
||||
|
||||
|
@ -824,7 +825,7 @@ static RRDR *rrd2rrdr_fixedstep(
|
|||
long available_points = duration / update_every;
|
||||
|
||||
if(duration <= 0 || available_points <= 0)
|
||||
return rrdr_create(st, 1);
|
||||
return rrdr_create(st, 1, temp_rd);
|
||||
|
||||
// check the number of wanted points in the result
|
||||
if(unlikely(points_requested < 0)) points_requested = -points_requested;
|
||||
|
@ -982,7 +983,7 @@ static RRDR *rrd2rrdr_fixedstep(
|
|||
// initialize our result set
|
||||
// this also locks the chart for us
|
||||
|
||||
RRDR *r = rrdr_create(st, points_wanted);
|
||||
RRDR *r = rrdr_create(st, points_wanted, temp_rd);
|
||||
if(unlikely(!r)) {
|
||||
#ifdef NETDATA_INTERNAL_CHECKS
|
||||
error("INTERNAL CHECK: Cannot create RRDR for %s, after=%u, before=%u, duration=%u, points=%ld", st->id, (uint32_t)after_wanted, (uint32_t)before_wanted, (uint32_t)duration, points_wanted);
|
||||
|
@ -1055,7 +1056,7 @@ static RRDR *rrd2rrdr_fixedstep(
|
|||
rrdset_check_rdlock(st);
|
||||
|
||||
if(dimensions)
|
||||
rrdr_disable_not_selected_dimensions(r, options, dimensions);
|
||||
rrdr_disable_not_selected_dimensions(r, options, dimensions, temp_rd);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -1066,7 +1067,7 @@ static RRDR *rrd2rrdr_fixedstep(
|
|||
|
||||
RRDDIM *rd;
|
||||
long c, dimensions_used = 0, dimensions_nonzero = 0;
|
||||
for(rd = st->dimensions, c = 0 ; rd && c < dimensions_count ; rd = rd->next, c++) {
|
||||
for(rd = temp_rd?temp_rd:st->dimensions, c = 0 ; rd && c < dimensions_count ; rd = rd->next, c++) {
|
||||
|
||||
// if we need a percentage, we need to calculate all dimensions
|
||||
if(unlikely(!(options & RRDR_OPTION_PERCENTAGE) && (r->od[c] & RRDR_DIMENSION_HIDDEN))) {
|
||||
|
@ -1159,7 +1160,7 @@ static RRDR *rrd2rrdr_fixedstep(
|
|||
if(unlikely(options & RRDR_OPTION_NONZERO && !dimensions_nonzero)) {
|
||||
// all the dimensions are zero
|
||||
// mark them as NONZERO to send them all
|
||||
for(rd = st->dimensions, c = 0 ; rd && c < dimensions_count ; rd = rd->next, c++) {
|
||||
for(rd = temp_rd?temp_rd:st->dimensions, c = 0 ; rd && c < dimensions_count ; rd = rd->next, c++) {
|
||||
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
||||
r->od[c] |= RRDR_DIMENSION_NONZERO;
|
||||
}
|
||||
|
@ -1184,6 +1185,7 @@ static RRDR *rrd2rrdr_variablestep(
|
|||
, time_t last_entry_t
|
||||
, int absolute_period_requested
|
||||
, struct rrdeng_region_info *region_info_array
|
||||
, RRDDIM *temp_rd
|
||||
) {
|
||||
int aligned = !(options & RRDR_OPTION_NOT_ALIGNED);
|
||||
|
||||
|
@ -1193,7 +1195,7 @@ static RRDR *rrd2rrdr_variablestep(
|
|||
|
||||
if(duration <= 0 || available_points <= 0) {
|
||||
freez(region_info_array);
|
||||
return rrdr_create(st, 1);
|
||||
return rrdr_create(st, 1, temp_rd);
|
||||
}
|
||||
|
||||
// check the number of wanted points in the result
|
||||
|
@ -1352,7 +1354,7 @@ static RRDR *rrd2rrdr_variablestep(
|
|||
// initialize our result set
|
||||
// this also locks the chart for us
|
||||
|
||||
RRDR *r = rrdr_create(st, points_wanted);
|
||||
RRDR *r = rrdr_create(st, points_wanted, temp_rd);
|
||||
if(unlikely(!r)) {
|
||||
#ifdef NETDATA_INTERNAL_CHECKS
|
||||
error("INTERNAL CHECK: Cannot create RRDR for %s, after=%u, before=%u, duration=%u, points=%ld", st->id, (uint32_t)after_wanted, (uint32_t)before_wanted, (uint32_t)duration, points_wanted);
|
||||
|
@ -1428,7 +1430,7 @@ static RRDR *rrd2rrdr_variablestep(
|
|||
rrdset_check_rdlock(st);
|
||||
|
||||
if(dimensions)
|
||||
rrdr_disable_not_selected_dimensions(r, options, dimensions);
|
||||
rrdr_disable_not_selected_dimensions(r, options, dimensions, temp_rd);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -1439,7 +1441,7 @@ static RRDR *rrd2rrdr_variablestep(
|
|||
|
||||
RRDDIM *rd;
|
||||
long c, dimensions_used = 0, dimensions_nonzero = 0;
|
||||
for(rd = st->dimensions, c = 0 ; rd && c < dimensions_count ; rd = rd->next, c++) {
|
||||
for(rd = temp_rd?temp_rd:st->dimensions, c = 0 ; rd && c < dimensions_count ; rd = rd->next, c++) {
|
||||
|
||||
// if we need a percentage, we need to calculate all dimensions
|
||||
if(unlikely(!(options & RRDR_OPTION_PERCENTAGE) && (r->od[c] & RRDR_DIMENSION_HIDDEN))) {
|
||||
|
@ -1533,7 +1535,7 @@ static RRDR *rrd2rrdr_variablestep(
|
|||
if(unlikely(options & RRDR_OPTION_NONZERO && !dimensions_nonzero)) {
|
||||
// all the dimensions are zero
|
||||
// mark them as NONZERO to send them all
|
||||
for(rd = st->dimensions, c = 0 ; rd && c < dimensions_count ; rd = rd->next, c++) {
|
||||
for(rd = temp_rd?temp_rd:st->dimensions, c = 0 ; rd && c < dimensions_count ; rd = rd->next, c++) {
|
||||
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
||||
r->od[c] |= RRDR_DIMENSION_NONZERO;
|
||||
}
|
||||
|
@ -1554,11 +1556,21 @@ RRDR *rrd2rrdr(
|
|||
, long resampling_time_requested
|
||||
, RRDR_OPTIONS options
|
||||
, const char *dimensions
|
||||
) {
|
||||
, RRDDIM *temp_rd
|
||||
)
|
||||
{
|
||||
int rrd_update_every;
|
||||
int absolute_period_requested;
|
||||
time_t first_entry_t = rrdset_first_entry_t(st);
|
||||
time_t last_entry_t = rrdset_last_entry_t(st);
|
||||
|
||||
time_t first_entry_t;
|
||||
time_t last_entry_t;
|
||||
if (temp_rd) {
|
||||
first_entry_t = rrddim_first_entry_t(temp_rd);
|
||||
last_entry_t = rrddim_last_entry_t(temp_rd);
|
||||
} else {
|
||||
first_entry_t = rrdset_first_entry_t(st);
|
||||
last_entry_t = rrdset_last_entry_t(st);
|
||||
}
|
||||
|
||||
rrd_update_every = st->update_every;
|
||||
absolute_period_requested = rrdr_convert_before_after_to_absolute(&after_requested, &before_requested,
|
||||
|
@ -1571,7 +1583,7 @@ RRDR *rrd2rrdr(
|
|||
|
||||
/* This call takes the chart read-lock */
|
||||
regions = rrdeng_variable_step_boundaries(st, after_requested, before_requested,
|
||||
®ion_info_array, &max_interval);
|
||||
®ion_info_array, &max_interval, temp_rd);
|
||||
if (1 == regions) {
|
||||
if (region_info_array) {
|
||||
if (rrd_update_every != region_info_array[0].update_every) {
|
||||
|
@ -1585,7 +1597,7 @@ RRDR *rrd2rrdr(
|
|||
}
|
||||
return rrd2rrdr_fixedstep(st, points_requested, after_requested, before_requested, group_method,
|
||||
resampling_time_requested, options, dimensions, rrd_update_every,
|
||||
first_entry_t, last_entry_t, absolute_period_requested);
|
||||
first_entry_t, last_entry_t, absolute_period_requested, temp_rd);
|
||||
} else {
|
||||
if (rrd_update_every != (uint16_t)max_interval) {
|
||||
rrd_update_every = (uint16_t) max_interval;
|
||||
|
@ -1596,11 +1608,11 @@ RRDR *rrd2rrdr(
|
|||
}
|
||||
return rrd2rrdr_variablestep(st, points_requested, after_requested, before_requested, group_method,
|
||||
resampling_time_requested, options, dimensions, rrd_update_every,
|
||||
first_entry_t, last_entry_t, absolute_period_requested, region_info_array);
|
||||
first_entry_t, last_entry_t, absolute_period_requested, region_info_array, temp_rd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return rrd2rrdr_fixedstep(st, points_requested, after_requested, before_requested, group_method,
|
||||
resampling_time_requested, options, dimensions,
|
||||
rrd_update_every, first_entry_t, last_entry_t, absolute_period_requested);
|
||||
rrd_update_every, first_entry_t, last_entry_t, absolute_period_requested, temp_rd);
|
||||
}
|
|
@ -98,7 +98,7 @@ inline void rrdr_free(RRDR *r)
|
|||
freez(r);
|
||||
}
|
||||
|
||||
RRDR *rrdr_create(RRDSET *st, long n)
|
||||
RRDR *rrdr_create(struct rrdset *st, long n, struct rrddim *temp_rd)
|
||||
{
|
||||
if(unlikely(!st)) {
|
||||
error("NULL value given!");
|
||||
|
@ -111,7 +111,14 @@ RRDR *rrdr_create(RRDSET *st, long n)
|
|||
rrdr_lock_rrdset(r);
|
||||
|
||||
RRDDIM *rd;
|
||||
rrddim_foreach_read(rd, st) r->d++;
|
||||
if (temp_rd) {
|
||||
RRDDIM *t = temp_rd;
|
||||
while (t) {
|
||||
r->d++;
|
||||
t = t->next;
|
||||
}
|
||||
} else
|
||||
rrddim_foreach_read(rd, st) r->d++;
|
||||
|
||||
r->n = n;
|
||||
|
||||
|
@ -122,7 +129,7 @@ RRDR *rrdr_create(RRDSET *st, long n)
|
|||
|
||||
// set the hidden flag on hidden dimensions
|
||||
int c;
|
||||
for(c = 0, rd = st->dimensions ; rd ; c++, rd = rd->next) {
|
||||
for(c = 0, rd = temp_rd?temp_rd:st->dimensions ; rd ; c++, rd = rd->next) {
|
||||
if(unlikely(rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN)))
|
||||
r->od[c] = RRDR_DIMENSION_HIDDEN;
|
||||
else
|
||||
|
|
|
@ -97,13 +97,14 @@ typedef struct rrdresult {
|
|||
|
||||
#define rrdr_rows(r) ((r)->rows)
|
||||
|
||||
#include "../../../database/rrd.h"
|
||||
extern void rrdr_free(RRDR *r);
|
||||
extern RRDR *rrdr_create(struct rrdset *st, long n);
|
||||
extern RRDR *rrdr_create(struct rrdset *st, long n, struct rrddim *id);
|
||||
|
||||
#include "../web_api_v1.h"
|
||||
#include "web/api/queries/query.h"
|
||||
|
||||
extern RRDR *rrd2rrdr(RRDSET *st, long points_requested, long long after_requested, long long before_requested, RRDR_GROUPING group_method, long resampling_time_requested, RRDR_OPTIONS options, const char *dimensions);
|
||||
extern RRDR *rrd2rrdr(RRDSET *st, long points_requested, long long after_requested, long long before_requested, RRDR_GROUPING group_method, long resampling_time_requested, RRDR_OPTIONS options, const char *dimensions, RRDDIM *temp_rd);
|
||||
|
||||
#include "query.h"
|
||||
|
||||
|
|
|
@ -397,7 +397,8 @@ inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c
|
|||
, *before_str = NULL
|
||||
, *after_str = NULL
|
||||
, *group_time_str = NULL
|
||||
, *points_str = NULL;
|
||||
, *points_str = NULL
|
||||
, *context = NULL;
|
||||
|
||||
int group = RRDR_GROUPING_AVERAGE;
|
||||
uint32_t format = DATASOURCE_JSON;
|
||||
|
@ -416,7 +417,8 @@ inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c
|
|||
// name and value are now the parameters
|
||||
// they are not null and not empty
|
||||
|
||||
if(!strcmp(name, "chart")) chart = value;
|
||||
if(!strcmp(name, "context")) context = value;
|
||||
else if(!strcmp(name, "chart")) chart = value;
|
||||
else if(!strcmp(name, "dimension") || !strcmp(name, "dim") || !strcmp(name, "dimensions") || !strcmp(name, "dims")) {
|
||||
if(!dimensions) dimensions = buffer_create(100);
|
||||
buffer_strcat(dimensions, "|");
|
||||
|
@ -482,18 +484,41 @@ inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c
|
|||
fix_google_param(responseHandler);
|
||||
fix_google_param(outFileName);
|
||||
|
||||
if(!chart || !*chart) {
|
||||
RRDSET *st = NULL;
|
||||
|
||||
if((!chart || !*chart) && (!context)) {
|
||||
buffer_sprintf(w->response.data, "No chart id is given at the request.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
RRDSET *st = rrdset_find(host, chart);
|
||||
if(!st) st = rrdset_find_byname(host, chart);
|
||||
if(!st) {
|
||||
buffer_strcat(w->response.data, "Chart is not found: ");
|
||||
buffer_strcat_htmlescape(w->response.data, chart);
|
||||
ret = HTTP_RESP_NOT_FOUND;
|
||||
goto cleanup;
|
||||
if (context) {
|
||||
st = NULL;
|
||||
// TODO: Scan all charts of host
|
||||
rrdhost_rdlock(localhost);
|
||||
RRDSET *st1;
|
||||
rrdset_foreach_read(st1, localhost) {
|
||||
if (strcmp(st1->context, context) == 0) {
|
||||
st = st1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rrdhost_unlock(localhost);
|
||||
}
|
||||
|
||||
if (!st) {
|
||||
if (!chart || !*chart) {
|
||||
buffer_sprintf(w->response.data, "No chart id is given at the request.");
|
||||
goto cleanup;
|
||||
}
|
||||
st = rrdset_find(host, chart);
|
||||
if (!st)
|
||||
st = rrdset_find_byname(host, chart);
|
||||
if (!st) {
|
||||
buffer_strcat(w->response.data, "Chart is not found: ");
|
||||
buffer_strcat_htmlescape(w->response.data, chart);
|
||||
ret = HTTP_RESP_NOT_FOUND;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
st->last_accessed_time = now_realtime_sec();
|
||||
|
||||
|
@ -540,7 +565,7 @@ inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c
|
|||
}
|
||||
|
||||
ret = rrdset2anything_api_v1(st, w->response.data, dimensions, format, points, after, before, group, group_time
|
||||
, options, &last_timestamp_in_data);
|
||||
, options, &last_timestamp_in_data, context);
|
||||
|
||||
if(format == DATASOURCE_DATATABLE_JSONP) {
|
||||
if(google_timestamp < last_timestamp_in_data)
|
||||
|
|
Loading…
Reference in New Issue