/Makefile
/build-aux
-/collectyd
-/collecty-graph
/config.h*
/libtool
/man/*.[0-9]
/man/*.html
/missing
-/src/collecty/__version__.py
-/src/systemd/collecty.service
+/src/systemd/telemetryd.service
+/telemetryd
+/telemetry-graph
/tmp
*.py[co]
/*.pdf
###############################################################################
# #
-# collecty - The IPFire statictics collection daemon #
-# Copyright (C) 2015 collecty development team #
+# telemetryd - The IPFire Telemetry Collection Service #
+# Copyright (C) 2015-2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# ------------------------------------------------------------------------------
bin_PROGRAMS += \
- collectyd
+ telemetryd
-dist_collectyd_SOURCES = \
+dist_telemetryd_SOURCES = \
src/daemon/args.c \
src/daemon/args.h \
src/daemon/buffer.c \
src/daemon/util.c \
src/daemon/util.h
-collectyd_CPPFLAGS = \
+telemetryd_CPPFLAGS = \
$(AM_CPPFLAGS)
-collectyd_CFLAGS = \
+telemetryd_CFLAGS = \
$(AM_CFLAGS) \
$(RRD_CFLAGS) \
$(SYSTEMD_CFLAGS)
-collectyd_LDFLAGS = \
+telemetryd_LDFLAGS = \
$(AM_LDFLAGS) \
$(RRD_LDFLAGS) \
$(SYSTEMD_LDFLAGS)
-collectyd_LDADD = \
+telemetryd_LDADD = \
$(RRD_LIBS) \
$(SYSTEMD_LIBS)
# ------------------------------------------------------------------------------
bin_PROGRAMS += \
- collecty-graph
+ telemetry-graph
-dist_collecty_graph_SOURCES = \
+dist_telemetry_graph_SOURCES = \
src/client/main.c
-collecty_graph_CPPFLAGS = \
+telemetry_graph_CPPFLAGS = \
$(AM_CPPFLAGS)
-collecty_graph_CFLAGS = \
+telemetry_graph_CFLAGS = \
$(AM_CFLAGS) \
$(SYSTEMD_CFLAGS)
-collecty_graph_LDFLAGS = \
+telemetry_graph_LDFLAGS = \
$(AM_LDFLAGS) \
$(SYSTEMD_LDFLAGS)
-collecty_graph_LDADD = \
+telemetry_graph_LDADD = \
$(SYSTEMD_LIBS)
# ------------------------------------------------------------------------------
dist_dbuspolicy_DATA = \
- src/dbus/org.ipfire.collecty1.conf
+ src/dbus/org.ipfire.telemetry1.conf
dist_dbussystemservice_DATA = \
- src/dbus/org.ipfire.collecty1.service
+ src/dbus/org.ipfire.telemetry1.service
systemdsystemunit_DATA = \
- src/systemd/collecty.service
+ src/systemd/telemetryd.service
dist_systemdsystemunit_DATA = \
- src/systemd/org.ipfire.collecty1.busname
+ src/systemd/org.ipfire.telemetry1.busname
EXTRA_DIST += \
- src/systemd/collecty.service.in
+ src/systemd/telemetryd.service.in
CLEANFILES += \
- src/systemd/collecty.service
+ src/systemd/telemetryd.service
# ------------------------------------------------------------------------------
if ENABLE_MANPAGES
MANPAGES = \
- man/collectyd.1
+ man/telemetryd.1
MANPAGES_XML = $(patsubst %.1,%.xml,$(patsubst %.5,%.xml,$(MANPAGES)))
MANPAGES_HTML = $(patsubst %.xml,%.html,$(MANPAGES_XML))
-Collecty (by the IPFire Project)
-
-Collecty is a small daemon written in python that collects
-system information data and stores it into RRDs.
-
-It is written to replace collectd in IPFire 3.x.
-
-
-Links:
- * http://oss.oetiker.ch/rrdtool/
+IPFire Telemetry (telemetryd)
+This server collects system information and stores it in RRD files.
###############################################################################
# #
-# collecty - The IPFire statictics collection daemon #
-# Copyright (C) 2015 collecty development team #
+# telemetryd - The IPFire Telemetry Collection Service #
+# Copyright (C) 2015-2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
AC_PREREQ([2.64])
-AC_INIT([collecty],
+AC_INIT([telemetry],
[004],
[info@ipfire.org],
- [collecty],
- [http://git.ipfire.org/?p=oddments/collecty.git;a=summary])
+ [telemetry],
+ [http://git.ipfire.org/?p=telemetry.git;a=summary])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
# ------------------------------------------------------------------------------
-AC_DEFINE_UNQUOTED([DATABASE_PATH], ["/var/lib/collecty"],
+AC_DEFINE_UNQUOTED([DATABASE_PATH], ["/var/lib/telemetry"],
[The path where the RRD databases are being stored])
# ------------------------------------------------------------------------------
+++ /dev/null
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2025-10-08 16:23+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-msgid "Connection Tracking Table"
-msgstr ""
-
-msgid "Entries"
-msgstr ""
-
-msgid "Current"
-msgstr ""
-
-msgid "Average"
-msgstr ""
-
-msgid "Minimum"
-msgstr ""
-
-msgid "Maximum"
-msgstr ""
-
-msgid "Limit"
-msgstr ""
-
-msgid "Context Switches"
-msgstr ""
-
-msgid "Context Switches/s"
-msgstr ""
-
-msgid "Load Average"
-msgstr ""
-
-msgid "15 Minutes"
-msgstr ""
-
-msgid "5 Minutes"
-msgstr ""
-
-msgid "1 Minute"
-msgstr ""
-
-msgid "Processor Usage"
-msgstr ""
-
-msgid "Percent"
-msgstr ""
-
-msgid "Total"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "Nice"
-msgstr ""
-
-msgid "Sys"
-msgstr ""
-
-msgid "Wait"
-msgstr ""
-
-msgid "Interrupt"
-msgstr ""
-
-msgid "Soft Interrupt"
-msgstr ""
-
-msgid "Steal"
-msgstr ""
-
-msgid "Guest"
-msgstr ""
-
-msgid "Guest Nice"
-msgstr ""
-
-msgid "Uptime"
-msgstr ""
-
-msgid "Days"
-msgstr ""
-/*#############################################################################
+/*##############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
const char* argp_program_version = PACKAGE_VERSION;
-static const char* doc = "The collecty client that can draw graphs";
+static const char* doc = "The telemetry client that can draw graphs";
-typedef struct collecty_client_ctx {
+typedef struct td_client_ctx {
enum {
// Enables debugging output
DEBUG = (1 << 0),
uint64_t h;
uint64_t w;
} dimensions;
-} collecty_client_ctx;
+} td_client_ctx;
enum {
OPT_FORMAT = 1,
};
static error_t parse(int key, char* arg, struct argp_state* state) {
- collecty_client_ctx* ctx = state->input;
+ td_client_ctx* ctx = state->input;
char* p = NULL;
switch (key) {
return 0;
}
-static int render(collecty_client_ctx* ctx) {
+static int render(td_client_ctx* ctx) {
sd_bus_message* reply = NULL;
const void* buffer = NULL;
sd_bus_message* m = NULL;
int r;
// Format the path
- r = snprintf(path, sizeof(path), "/org/ipfire/collecty1/graph/%s", ctx->graph);
+ r = snprintf(path, sizeof(path), "/org/ipfire/telemetry1/graph/%s", ctx->graph);
if (r < 0)
goto ERROR;
// Prepare to call the render function
r = sd_bus_message_new_method_call(ctx->bus, &m,
- "org.ipfire.collecty1", path, "org.ipfire.collecty1.Graph", "Render");
+ "org.ipfire.telemetry1", path, "org.ipfire.telemetry1.Graph", "Render");
if (r < 0)
goto ERROR;
int r;
// Allocate a new context
- collecty_client_ctx ctx = {
+ td_client_ctx ctx = {
.f = stdout,
};
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "args.h"
#include "ctx.h"
-struct collecty_args {
- collecty_ctx* ctx;
+struct td_args {
+ td_ctx* ctx;
int nrefs;
// Arguments
int argc;
};
-static void collecty_args_free(collecty_args* self) {
+static void td_args_free(td_args* self) {
if (self->argv) {
for (int i = 0; i < self->argc; i++)
free(self->argv[i]);
free(self->argv);
}
if (self->ctx)
- collecty_ctx_unref(self->ctx);
+ td_ctx_unref(self->ctx);
free(self);
}
-int collecty_args_create(collecty_args** args, collecty_ctx* ctx) {
- collecty_args* self = NULL;
+int td_args_create(td_args** args, td_ctx* ctx) {
+ td_args* self = NULL;
// Allocate some memory
self = calloc(1, sizeof(*self));
self->nrefs = 1;
// Keep a reference to the context
- self->ctx = collecty_ctx_ref(ctx);
+ self->ctx = td_ctx_ref(ctx);
// Return pointer
*args = self;
return 0;
}
-collecty_args* collecty_args_ref(collecty_args* self) {
+td_args* td_args_ref(td_args* self) {
++self->nrefs;
return self;
}
-collecty_args* collecty_args_unref(collecty_args* self) {
+td_args* td_args_unref(td_args* self) {
if (--self->nrefs > 0)
return self;
- collecty_args_free(self);
+ td_args_free(self);
return NULL;
}
-const char** collecty_args_argv(collecty_args* self) {
+const char** td_args_argv(td_args* self) {
return (const char**)self->argv;
}
-int collecty_args_argc(collecty_args* self) {
+int td_args_argc(td_args* self) {
return self->argc;
}
-int collecty_args_push(collecty_args* self, const char* format, ...) {
+int td_args_push(td_args* self, const char* format, ...) {
char** argv = NULL;
char* arg = NULL;
va_list args;
return -errno;
}
-int collecty_args_pushv(collecty_args* self, const char* args[]) {
+int td_args_pushv(td_args* self, const char* args[]) {
int r;
// Check inputs
return -EINVAL;
for (unsigned int i = 0; args[i]; i++) {
- r = collecty_args_push(self, "%s", args[i]);
+ r = td_args_push(self, "%s", args[i]);
if (r < 0)
return r;
}
return 0;
}
-int collecty_args_dump(collecty_args* self) {
+int td_args_dump(td_args* self) {
for (int i = 0; i < self->argc; i++) {
DEBUG(self->ctx, "argv[%d]: %s\n", i, self->argv[i]);
}
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_ARGS_H
-#define COLLECTY_ARGS_H
+#ifndef TELEMETRY_ARGS_H
+#define TELEMETRY_ARGS_H
-typedef struct collecty_args collecty_args;
+typedef struct td_args td_args;
#include "ctx.h"
-int collecty_args_create(collecty_args** args, collecty_ctx* ctx);
+int td_args_create(td_args** args, td_ctx* ctx);
-collecty_args* collecty_args_ref(collecty_args* self);
-collecty_args* collecty_args_unref(collecty_args* self);
+td_args* td_args_ref(td_args* self);
+td_args* td_args_unref(td_args* self);
-const char** collecty_args_argv(collecty_args* self);
-int collecty_args_argc(collecty_args* self);
+const char** td_args_argv(td_args* self);
+int td_args_argc(td_args* self);
-int collecty_args_push(collecty_args* self, const char* format, ...)
+int td_args_push(td_args* self, const char* format, ...)
__attribute__((format(printf, 2, 3)));
-int collecty_args_pushv(collecty_args* self, const char* args[]);
+int td_args_pushv(td_args* self, const char* args[]);
-int collecty_args_dump(collecty_args* self);
+int td_args_dump(td_args* self);
-#endif /* COLLECTY_ARGS_H */
+#endif /* TELEMETRY_ARGS_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "ctx.h"
#include "buffer.h"
-struct collecty_buffer {
- collecty_ctx* ctx;
+struct td_buffer {
+ td_ctx* ctx;
int nrefs;
// File Handle
// Flags
enum {
- COLLECTY_BUFFER_LOCKED = (1 << 0),
+ TELEMETRY_BUFFER_LOCKED = (1 << 0),
} flags;
// Data & Length
off_t p;
};
-static void collecty_buffer_free(collecty_buffer* self) {
+static void td_buffer_free(td_buffer* self) {
if (self->f)
fclose(self->f);
if (self->data)
free(self->data);
if (self->ctx)
- collecty_ctx_unref(self->ctx);
+ td_ctx_unref(self->ctx);
free(self);
}
-int collecty_buffer_create(collecty_buffer** buffer, collecty_ctx* ctx) {
- collecty_buffer* self = NULL;
+int td_buffer_create(td_buffer** buffer, td_ctx* ctx) {
+ td_buffer* self = NULL;
// Allocate some memory
self = calloc(1, sizeof(*self));
self->nrefs = 1;
// Store a reference to the context
- self->ctx = collecty_ctx_ref(ctx);
+ self->ctx = td_ctx_ref(ctx);
// Return pointer
*buffer = self;
return 0;
}
-collecty_buffer* collecty_buffer_ref(collecty_buffer* self) {
+td_buffer* td_buffer_ref(td_buffer* self) {
++self->nrefs;
return self;
}
-collecty_buffer* collecty_buffer_unref(collecty_buffer* self) {
+td_buffer* td_buffer_unref(td_buffer* self) {
if (--self->nrefs > 0)
return self;
- collecty_buffer_free(self);
+ td_buffer_free(self);
return NULL;
}
-static int collecty_buffer_has_flag(collecty_buffer* self, int flag) {
+static int td_buffer_has_flag(td_buffer* self, int flag) {
return self->flags & flag;
}
-static void collecty_buffer_lock(collecty_buffer* self) {
- self->flags |= COLLECTY_BUFFER_LOCKED;
+static void td_buffer_lock(td_buffer* self) {
+ self->flags |= TELEMETRY_BUFFER_LOCKED;
}
-static ssize_t __collecty_buffer_read(void* cookie, char* buffer, size_t length) {
- collecty_buffer* self = cookie;
+static ssize_t __td_buffer_read(void* cookie, char* buffer, size_t length) {
+ td_buffer* self = cookie;
// Determine how much data is left
size_t bytes_left = self->length - self->p;
return length;
}
-static int __collecty_buffer_seek(void* cookie, off_t* offset, int whence) {
- collecty_buffer* self = cookie;
+static int __td_buffer_seek(void* cookie, off_t* offset, int whence) {
+ td_buffer* self = cookie;
// Update p
switch (whence) {
return 0;
}
-static int __collecty_buffer_close(void* cookie) {
- collecty_buffer* self = cookie;
+static int __td_buffer_close(void* cookie) {
+ td_buffer* self = cookie;
// Drop the reference to the buffer
- collecty_buffer_unref(self);
+ td_buffer_unref(self);
return 0;
}
-cookie_io_functions_t collecty_buffer_io_funcs = {
- .read = __collecty_buffer_read,
- .seek = __collecty_buffer_seek,
- .close = __collecty_buffer_close,
+cookie_io_functions_t td_buffer_io_funcs = {
+ .read = __td_buffer_read,
+ .seek = __td_buffer_seek,
+ .close = __td_buffer_close,
};
-FILE* collecty_buffer_fopen(collecty_buffer* self, const char* mode) {
+FILE* td_buffer_fopen(td_buffer* self, const char* mode) {
// Check if mode was passed
if (!mode) {
errno = EINVAL;
}
// Lock the buffer
- collecty_buffer_lock(self);
+ td_buffer_lock(self);
// Reset p
self->p = 0;
// Return a file handle
- return fopencookie(collecty_buffer_ref(self), mode, collecty_buffer_io_funcs);
+ return fopencookie(td_buffer_ref(self), mode, td_buffer_io_funcs);
}
-int collecty_buffer_write(collecty_buffer* self, const char* chunk, size_t length) {
+int td_buffer_write(td_buffer* self, const char* chunk, size_t length) {
char* data = NULL;
int r;
// Cannot write if the buffer is locked
- if (collecty_buffer_has_flag(self, COLLECTY_BUFFER_LOCKED))
+ if (td_buffer_has_flag(self, TELEMETRY_BUFFER_LOCKED))
return -ENOTSUP;
// Increase the size of the buffer
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_BUFFER_H
-#define COLLECTY_BUFFER_H
+#ifndef TELEMETRY_BUFFER_H
+#define TELEMETRY_BUFFER_H
#include <stdio.h>
-typedef struct collecty_buffer collecty_buffer;
+typedef struct td_buffer td_buffer;
#include "ctx.h"
-int collecty_buffer_create(collecty_buffer** buffer, collecty_ctx* ctx);
+int td_buffer_create(td_buffer** buffer, td_ctx* ctx);
-collecty_buffer* collecty_buffer_ref(collecty_buffer* self);
-collecty_buffer* collecty_buffer_unref(collecty_buffer* self);
+td_buffer* td_buffer_ref(td_buffer* self);
+td_buffer* td_buffer_unref(td_buffer* self);
-FILE* collecty_buffer_fopen(collecty_buffer* self, const char* mode);
+FILE* td_buffer_fopen(td_buffer* self, const char* mode);
-int collecty_buffer_write(collecty_buffer* self, const char* chunk, size_t length);
+int td_buffer_write(td_buffer* self, const char* chunk, size_t length);
-#endif /* COLLECTY_BUFFER_H */
+#endif /* TELEMETRY_BUFFER_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#define DEFAULT_SYSTEM_BUS_ADDRESS "unix:path=/run/dbus/system_bus_socket"
-static int collecty_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) {
- collecty_ctx* ctx = data;
+static int td_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) {
+ td_ctx* ctx = data;
// Log action
DEBUG(ctx, "Connected to D-Bus\n");
return 0;
}
-static int collecty_bus_register_implementation(collecty_ctx* ctx,
- sd_bus* bus, const struct collecty_bus_implementation* impl, void* data) {
+static int td_bus_register_implementation(td_ctx* ctx,
+ sd_bus* bus, const struct td_bus_implementation* impl, void* data) {
int r;
DEBUG(ctx, "Registering bus object implementation for path=%s iface=%s\n",
}
// Register fallback vtables
- for (const struct collecty_bus_vtable_pair* p = impl->fallback_vtables; p && p->vtable; p++) {
+ for (const struct td_bus_vtable_pair* p = impl->fallback_vtables; p && p->vtable; p++) {
r = sd_bus_add_fallback_vtable(bus, NULL, impl->path, impl->interface,
p->vtable, p->object_find, data);
if (r < 0) {
// Register any child implementations
for (int i = 0; impl->children && impl->children[i]; i++) {
- r = collecty_bus_register_implementation(ctx, bus, impl->children[i], data);
+ r = td_bus_register_implementation(ctx, bus, impl->children[i], data);
if (r)
return r;
}
return 0;
}
-int collecty_bus_connect(collecty_ctx* ctx, sd_bus** bus, sd_event* loop, collecty_daemon* daemon) {
+int td_bus_connect(td_ctx* ctx, sd_bus** bus, sd_event* loop, td_daemon* daemon) {
const char* address = NULL;
sd_bus* b = NULL;
int r;
}
// Set description
- r = sd_bus_set_description(b, "collectyd");
+ r = sd_bus_set_description(b, "telemetryd");
if (r < 0) {
ERROR(ctx, "Could not set bus description: %s\n", strerror(-r));
goto ERROR;
}
// Register the implementation
- r = collecty_bus_register_implementation(ctx, b, &daemon_bus_impl, daemon);
+ r = td_bus_register_implementation(ctx, b, &daemon_bus_impl, daemon);
if (r < 0)
goto ERROR;
// Request interface name
- r = sd_bus_request_name_async(b, NULL, "org.ipfire.collecty1", 0, NULL, NULL);
+ r = sd_bus_request_name_async(b, NULL, "org.ipfire.telemetry1", 0, NULL, NULL);
if (r < 0) {
ERROR(ctx, "Could not request bus name: %s\n", strerror(-r));
goto ERROR;
// Request receiving a connect signal
r = sd_bus_match_signal_async(b, NULL, "org.freedesktop.DBus.Local", NULL,
- "org.freedesktop.DBus.Local", "Connected", collecty_bus_on_connect, NULL, ctx);
+ "org.freedesktop.DBus.Local", "Connected", td_bus_on_connect, NULL, ctx);
if (r < 0) {
ERROR(ctx, "Could not request match on Connected signal: %s\n", strerror(-r));
goto ERROR;
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_BUS_H
-#define COLLECTY_BUS_H
+#ifndef TELEMETRY_BUS_H
+#define TELEMETRY_BUS_H
#include <systemd/sd-bus.h>
#include <systemd/sd-event.h>
-struct collecty_bus_vtable_pair {
+struct td_bus_vtable_pair {
const sd_bus_vtable* vtable;
sd_bus_object_find_t object_find;
};
-typedef struct collecty_bus_implementation {
+typedef struct td_bus_implementation {
const char* path;
const char* interface;
const sd_bus_vtable** vtables;
- const struct collecty_bus_vtable_pair* fallback_vtables;
+ const struct td_bus_vtable_pair* fallback_vtables;
sd_bus_node_enumerator_t node_enumerator;
- const struct collecty_bus_implementation** children;
-} collecty_bus_implementation;
+ const struct td_bus_implementation** children;
+} td_bus_implementation;
#include "ctx.h"
#include "daemon.h"
-#define BUS_FALLBACK_VTABLES(...) ((const struct collecty_bus_vtable_pair[]) { __VA_ARGS__, {} })
-#define BUS_IMPLEMENTATIONS(...) ((const collecty_bus_implementation* []) { __VA_ARGS__, NULL })
+#define BUS_FALLBACK_VTABLES(...) ((const struct td_bus_vtable_pair[]) { __VA_ARGS__, {} })
+#define BUS_IMPLEMENTATIONS(...) ((const td_bus_implementation* []) { __VA_ARGS__, NULL })
#define BUS_VTABLES(...) ((const sd_bus_vtable* []){ __VA_ARGS__, NULL })
-int collecty_bus_connect(collecty_ctx* ctx,
- sd_bus** bus, sd_event* loop, collecty_daemon* daemon);
+int td_bus_connect(td_ctx* ctx,
+ sd_bus** bus, sd_event* loop, td_daemon* daemon);
-#endif /* COLLECTY_BUS_H */
+#endif /* TELEMETRY_BUS_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_COLORS_H
-#define COLLECTY_COLORS_H
+#ifndef TELEMETRY_COLORS_H
+#define TELEMETRY_COLORS_H
#define BLACK "#000000"
#define WHITE "#ffffff"
// Fill areas very lightly
#define OPACITY_AREA OPACITY_25P
-#endif /* COLLECTY_COLORS_H */
+#endif /* TELEMETRY_COLORS_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
// By default, commands are being killed after 30 seconds
#define DEFAULT_TIMEOUT SEC_TO_USEC(30)
-typedef struct collecty_command_output {
+typedef struct td_command_output {
// Pipes
int pipes[2];
// Buffer
- collecty_buffer* buffer;
-} collecty_command_output;
+ td_buffer* buffer;
+} td_command_output;
-struct collecty_command {
- collecty_ctx* ctx;
+struct td_command {
+ td_ctx* ctx;
int nrefs;
// Daemon
- collecty_daemon* daemon;
+ td_daemon* daemon;
// Loop
sd_event* loop;
int pidfd;
// Standard Output/Error
- collecty_command_output stdout;
- collecty_command_output stderr;
+ td_command_output stdout;
+ td_command_output stderr;
// Callbacks
struct {
// On success
- collecty_command_success_callback on_success;
+ td_command_success_callback on_success;
void* on_success_data;
} callbacks;
return syscall(SYS_pidfd_send_signal, pidfd, sig, info, flags);
}
-static void collecty_command_close_pipe(int fds[2]) {
+static void td_command_close_pipe(int fds[2]) {
for (unsigned int i = 0; i < 2; i++) {
if (fds[i] >= 0) {
close(fds[i]);
}
}
-static void collecty_command_free(collecty_command* self) {
+static void td_command_free(td_command* self) {
// Close pipes
- collecty_command_close_pipe(self->stdout.pipes);
- collecty_command_close_pipe(self->stderr.pipes);
+ td_command_close_pipe(self->stdout.pipes);
+ td_command_close_pipe(self->stderr.pipes);
// Close pidfd
if (self->pidfd >= 0)
// Free buffers
if (self->stdout.buffer)
- collecty_buffer_unref(self->stdout.buffer);
+ td_buffer_unref(self->stdout.buffer);
if (self->stderr.buffer)
- collecty_buffer_unref(self->stderr.buffer);
+ td_buffer_unref(self->stderr.buffer);
// Free events
if (self->events.timeout)
if (self->loop)
sd_event_unref(self->loop);
if (self->daemon)
- collecty_daemon_unref(self->daemon);
+ td_daemon_unref(self->daemon);
if (self->ctx)
- collecty_ctx_unref(self->ctx);
+ td_ctx_unref(self->ctx);
free(self);
}
-static int collecty_command_init_output(collecty_command* self, collecty_command_output* output) {
+static int td_command_init_output(td_command* self, td_command_output* output) {
int r;
// Create pipes
}
// Create a buffer to write any data to
- r = collecty_buffer_create(&output->buffer, self->ctx);
+ r = td_buffer_create(&output->buffer, self->ctx);
if (r < 0) {
ERROR(self->ctx, "Failed to create output buffer: %s\n", strerror(-r));
return r;
return 0;
}
-int collecty_command_create(collecty_command** command,
- collecty_ctx* ctx, collecty_daemon* daemon) {
- collecty_command* self = NULL;
+int td_command_create(td_command** command,
+ td_ctx* ctx, td_daemon* daemon) {
+ td_command* self = NULL;
int r;
// Allocate some memory
self->nrefs = 1;
// Keep a reference to the context
- self->ctx = collecty_ctx_ref(ctx);
+ self->ctx = td_ctx_ref(ctx);
// Store a reference to the daemon
- self->daemon = collecty_daemon_ref(daemon);
+ self->daemon = td_daemon_ref(daemon);
// Fetch a reference to the event loop
- self->loop = collecty_daemon_loop(daemon);
+ self->loop = td_daemon_loop(daemon);
// Set default timeout
self->timeout = DEFAULT_TIMEOUT;
self->pidfd = -EBADF;
// Initialize stdout
- r = collecty_command_init_output(self, &self->stdout);
+ r = td_command_init_output(self, &self->stdout);
if (r < 0)
goto ERROR;
// Initialize stderr
- r = collecty_command_init_output(self, &self->stderr);
+ r = td_command_init_output(self, &self->stderr);
if (r < 0)
goto ERROR;
ERROR:
if (self)
- collecty_command_unref(self);
+ td_command_unref(self);
return r;
}
-collecty_command* collecty_command_ref(collecty_command* self) {
+td_command* td_command_ref(td_command* self) {
++self->nrefs;
return self;
}
-collecty_command* collecty_command_unref(collecty_command* self) {
+td_command* td_command_unref(td_command* self) {
if (--self->nrefs > 0)
return self;
- collecty_command_free(self);
+ td_command_free(self);
return NULL;
}
-void collecty_command_set_timeout(collecty_command* self, uint64_t timeout) {
+void td_command_set_timeout(td_command* self, uint64_t timeout) {
self->timeout = timeout;
}
-void collecty_command_on_success(collecty_command* self,
- collecty_command_success_callback callback, void* data) {
+void td_command_on_success(td_command* self,
+ td_command_success_callback callback, void* data) {
self->callbacks.on_success = callback;
self->callbacks.on_success_data = data;
}
-static int collecty_command_write(collecty_command* self,
- int fd, unsigned int events, collecty_command_output* output) {
+static int td_command_write(td_command* self,
+ int fd, unsigned int events, td_command_output* output) {
ssize_t bytes_read = 0;
char buffer[4096];
int r;
return 0;
// Write to the buffer
- r = collecty_buffer_write(output->buffer, buffer, bytes_read);
+ r = td_buffer_write(output->buffer, buffer, bytes_read);
if (r < 0)
return r;
return 0;
}
-static int collecty_command_stdout(sd_event_source* source, int fd, unsigned int events, void* data) {
- collecty_command* self = data;
+static int td_command_stdout(sd_event_source* source, int fd, unsigned int events, void* data) {
+ td_command* self = data;
- return collecty_command_write(self, fd, events, &self->stdout);
+ return td_command_write(self, fd, events, &self->stdout);
}
-static int collecty_command_stderr(sd_event_source* source, int fd, unsigned int events, void* data) {
- collecty_command* self = data;
+static int td_command_stderr(sd_event_source* source, int fd, unsigned int events, void* data) {
+ td_command* self = data;
- return collecty_command_write(self, fd, events, &self->stderr);
+ return td_command_write(self, fd, events, &self->stderr);
}
-static int collecty_command_get_pipe_to_read(collecty_command* self, int (*fds)[2]) {
+static int td_command_get_pipe_to_read(td_command* self, int (*fds)[2]) {
// Give the variables easier names to avoid confusion
int* fd_read = &(*fds)[0];
int* fd_write = &(*fds)[1];
return -EBADF;
}
-static int collecty_command_log_stderr(collecty_ctx* ctx, collecty_file* file,
+static int td_command_log_stderr(td_ctx* ctx, td_file* file,
unsigned long lineno, char* line, size_t length, void* data) {
- collecty_command* self = data;
+ td_command* self = data;
// Send the line to the logger
ERROR(self->ctx, " stderr: %s\n", line);
return 0;
}
-static int collecty_command_exited(sd_event_source* source, const siginfo_t* si, void* data) {
- collecty_command* self = data;
- collecty_file* stdout = NULL;
- collecty_file* stderr = NULL;
+static int td_command_exited(sd_event_source* source, const siginfo_t* si, void* data) {
+ td_command* self = data;
+ td_file* stdout = NULL;
+ td_file* stderr = NULL;
int rc = 0;
int r = 0;
// Drain standard output
if (self->stdout.pipes[0] >= 0) {
- r = collecty_command_stdout(source, self->stdout.pipes[0], EPOLLIN, data);
+ r = td_command_stdout(source, self->stdout.pipes[0], EPOLLIN, data);
if (r < 0) {
ERROR(self->ctx, "Failed to drain stdout: %s\n", strerror(-r));
return r;
// Drain standard error
if (self->stderr.pipes[0] >= 0) {
- r = collecty_command_stderr(source, self->stderr.pipes[0], EPOLLIN, data);
+ r = td_command_stderr(source, self->stderr.pipes[0], EPOLLIN, data);
if (r < 0) {
ERROR(self->ctx, "Failed to drain stderr: %s\n", strerror(-r));
return r;
// Log stderr
if (rc) {
// Open a file handle
- r = collecty_file_open_buffer(&stderr, self->ctx, self->stderr.buffer);
+ r = td_file_open_buffer(&stderr, self->ctx, self->stderr.buffer);
if (r < 0)
goto ERROR;
// Log all lines
- r = collecty_file_walk(stderr, collecty_command_log_stderr, self);
+ r = td_file_walk(stderr, td_command_log_stderr, self);
if (r < 0)
goto ERROR;
}
// Call the callback
if (self->callbacks.on_success) {
// Open stdout as a file
- r = collecty_file_open_buffer(&stdout, self->ctx, self->stdout.buffer);
+ r = td_file_open_buffer(&stdout, self->ctx, self->stdout.buffer);
if (r < 0)
goto ERROR;
ERROR:
if (stderr)
- collecty_file_unref(stderr);
+ td_file_unref(stderr);
if (stdout)
- collecty_file_unref(stdout);
+ td_file_unref(stdout);
// Drop the extra reference
- collecty_command_unref(self);
+ td_command_unref(self);
return r;
}
-static int collecty_command_timeout(sd_event_source* source, uint64_t usec, void* data) {
- collecty_command* self = data;
+static int td_command_timeout(sd_event_source* source, uint64_t usec, void* data) {
+ td_command* self = data;
int r;
// Log action
return 0;
}
-static int collecty_command_parent(collecty_command* self) {
+static int td_command_parent(td_command* self) {
int fd = -EBADF;
int r;
// Register the PID file descriptor
r = sd_event_add_child_pidfd(self->loop, &self->events.exit, self->pidfd, WEXITED,
- collecty_command_exited, collecty_command_ref(self));
+ td_command_exited, td_command_ref(self));
if (r < 0) {
DEBUG(self->ctx, "Failed to register the child process with the event loop: %s\n", strerror(-r));
return r;
}
// Prepare standard output for reading
- fd = collecty_command_get_pipe_to_read(self, &self->stdout.pipes);
+ fd = td_command_get_pipe_to_read(self, &self->stdout.pipes);
if (fd >= 0) {
// Add the file descriptor to the event loop
r = sd_event_add_io(self->loop, &self->events.stdout,
- fd, EPOLLIN|EPOLLHUP|EPOLLET, collecty_command_stdout, self);
+ fd, EPOLLIN|EPOLLHUP|EPOLLET, td_command_stdout, self);
if (r < 0) {
ERROR(self->ctx, "Failed to register stdout for reading: %s\n", strerror(-r));
return r;
}
// Prepare standard error for reading
- fd = collecty_command_get_pipe_to_read(self, &self->stderr.pipes);
+ fd = td_command_get_pipe_to_read(self, &self->stderr.pipes);
if (fd >= 0) {
// Add the file descriptor to the event loop
r = sd_event_add_io(self->loop, &self->events.stderr,
- fd, EPOLLIN|EPOLLHUP|EPOLLET, collecty_command_stderr, self);
+ fd, EPOLLIN|EPOLLHUP|EPOLLET, td_command_stderr, self);
if (r < 0) {
ERROR(self->ctx, "Failed to register stderr for reading: %s\n", strerror(-r));
return r;
// Set the timeout
if (self->timeout) {
r = sd_event_add_time_relative(self->loop, &self->events.timeout,
- CLOCK_MONOTONIC, self->timeout, 0, collecty_command_timeout, self);
+ CLOCK_MONOTONIC, self->timeout, 0, td_command_timeout, self);
if (r < 0) {
ERROR(self->ctx, "Failed to setup timer: %s\n", strerror(-r));
return r;
return r;
}
-static int collecty_command_child(collecty_command* self, const char** argv) {
+static int td_command_child(td_command* self, const char** argv) {
int fd = -EBADF;
int r;
}
// Close all pipes
- collecty_command_close_pipe(self->stdout.pipes);
- collecty_command_close_pipe(self->stderr.pipes);
+ td_command_close_pipe(self->stdout.pipes);
+ td_command_close_pipe(self->stderr.pipes);
// Execute the command
abort();
}
-int collecty_command_execute(collecty_command* self, const char** argv) {
+int td_command_execute(td_command* self, const char** argv) {
struct clone_args args = {
.flags = CLONE_PIDFD,
.exit_signal = SIGCHLD,
// Child process
if (pid == 0) {
- r = collecty_command_child(self, argv);
+ r = td_command_child(self, argv);
_exit(r);
}
// Parent process
- return collecty_command_parent(self);
+ return td_command_parent(self);
}
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_COMMAND_H
-#define COLLECTY_COMMAND_H
+#ifndef TELEMETRY_COMMAND_H
+#define TELEMETRY_COMMAND_H
-typedef struct collecty_command collecty_command;
+typedef struct td_command td_command;
#include "ctx.h"
#include "file.h"
#include "daemon.h"
-int collecty_command_create(collecty_command** command,
- collecty_ctx* ctx, collecty_daemon* daemon);
+int td_command_create(td_command** command,
+ td_ctx* ctx, td_daemon* daemon);
-collecty_command* collecty_command_ref(collecty_command* self);
-collecty_command* collecty_command_unref(collecty_command* self);
+td_command* td_command_ref(td_command* self);
+td_command* td_command_unref(td_command* self);
// Timeout
-void collecty_command_set_timeout(collecty_command* self, uint64_t timeout);
+void td_command_set_timeout(td_command* self, uint64_t timeout);
-typedef int (*collecty_command_success_callback)
- (collecty_ctx* ctx, int rc, collecty_file* stdout, void* data);
+typedef int (*td_command_success_callback)
+ (td_ctx* ctx, int rc, td_file* stdout, void* data);
// Called if the command has exited successfully
-void collecty_command_on_success(collecty_command* self,
- collecty_command_success_callback callback, void* data);
+void td_command_on_success(td_command* self,
+ td_command_success_callback callback, void* data);
-int collecty_command_execute(collecty_command* self, const char** argv);
+int td_command_execute(td_command* self, const char** argv);
-#endif /* COLLECTY_COMMAND_H */
+#endif /* TELEMETRY_COMMAND_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "ctx.h"
#include "logging.h"
-struct collecty_ctx {
+struct td_ctx {
int nrefs;
// Logging
int level;
// Callback
- collecty_log_callback callback;
+ td_log_callback callback;
void* data;
} log;
};
-static int collecty_ctx_setup_logging(collecty_ctx* ctx) {
+static int td_ctx_setup_logging(td_ctx* ctx) {
// Log informational messages
ctx->log.level = LOG_INFO;
// Setup a logging callback
- ctx->log.callback = collecty_log_syslog;
+ ctx->log.callback = td_log_syslog;
return 0;
}
-static void collecty_ctx_free(collecty_ctx* ctx) {
+static void td_ctx_free(td_ctx* ctx) {
free(ctx);
}
-int collecty_ctx_create(collecty_ctx** ctx) {
- struct collecty_ctx* self = NULL;
+int td_ctx_create(td_ctx** ctx) {
+ struct td_ctx* self = NULL;
int r;
// Allocate some memory
self->nrefs = 1;
// Setup logging
- r = collecty_ctx_setup_logging(self);
+ r = td_ctx_setup_logging(self);
if (r < 0)
goto ERROR;
ERROR:
if (self)
- collecty_ctx_unref(self);
+ td_ctx_unref(self);
return r;
}
-collecty_ctx* collecty_ctx_ref(collecty_ctx* ctx) {
+td_ctx* td_ctx_ref(td_ctx* ctx) {
++ctx->nrefs;
return ctx;
}
-collecty_ctx* collecty_ctx_unref(collecty_ctx* ctx) {
+td_ctx* td_ctx_unref(td_ctx* ctx) {
if (--ctx->nrefs > 0)
return ctx;
- collecty_ctx_free(ctx);
+ td_ctx_free(ctx);
return NULL;
}
Logging
*/
-int collecty_ctx_get_log_level(collecty_ctx* ctx) {
+int td_ctx_get_log_level(td_ctx* ctx) {
return ctx->log.level;
}
-void collecty_ctx_set_log_level(collecty_ctx* ctx, int level) {
+void td_ctx_set_log_level(td_ctx* ctx, int level) {
ctx->log.level = level;
}
-void collecty_ctx_set_log_callback(collecty_ctx* ctx,
- collecty_log_callback callback, void* data) {
+void td_ctx_set_log_callback(td_ctx* ctx,
+ td_log_callback callback, void* data) {
ctx->log.callback = callback;
ctx->log.data = data;
}
-void collecty_ctx_log(collecty_ctx* self, int level,
+void td_ctx_log(td_ctx* self, int level,
const char* file, int line, const char* fn, const char* format, ...) {
va_list args;
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_CTX_H
-#define COLLECTY_CTX_H
+#ifndef TELEMETRY_CTX_H
+#define TELEMETRY_CTX_H
-typedef struct collecty_ctx collecty_ctx;
+typedef struct td_ctx td_ctx;
-int collecty_ctx_create(collecty_ctx** ctx);
+int td_ctx_create(td_ctx** ctx);
-collecty_ctx* collecty_ctx_ref(collecty_ctx* ctx);
-collecty_ctx* collecty_ctx_unref(collecty_ctx* ctx);
+td_ctx* td_ctx_ref(td_ctx* ctx);
+td_ctx* td_ctx_unref(td_ctx* ctx);
// Logging
#include "logging.h"
-int collecty_ctx_get_log_level(collecty_ctx* ctx);
-void collecty_ctx_set_log_level(collecty_ctx* ctx, int level);
+int td_ctx_get_log_level(td_ctx* ctx);
+void td_ctx_set_log_level(td_ctx* ctx, int level);
-void collecty_ctx_set_log_callback(collecty_ctx* ctx,
- collecty_log_callback callback, void* data);
+void td_ctx_set_log_callback(td_ctx* ctx,
+ td_log_callback callback, void* data);
-void collecty_ctx_log(collecty_ctx* self, int level,
+void td_ctx_log(td_ctx* self, int level,
const char* file, int line, const char* fn, const char* format, ...);
-#endif /* COLLECTY_CTX_H */
+#endif /* TELEMETRY_CTX_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "source.h"
#include "sources.h"
-struct collecty_daemon {
- collecty_ctx* ctx;
+struct td_daemon {
+ td_ctx* ctx;
int nrefs;
// Event Loop
sd_bus* bus;
// Queue
- collecty_queue* queue;
+ td_queue* queue;
// Sources
- collecty_sources* sources;
+ td_sources* sources;
// Graphs
- collecty_graphs* graphs;
+ td_graphs* graphs;
};
-static int collecty_daemon_init(sd_event_source* source, void* data) {
- collecty_daemon* self = data;
+static int td_daemon_init(sd_event_source* source, void* data) {
+ td_daemon* self = data;
int r;
DEBUG(self->ctx, "Initializing daemon...\n");
// Initialize all sources
- r = collecty_sources_create(&self->sources, self->ctx, self);
+ r = td_sources_create(&self->sources, self->ctx, self);
if (r < 0)
return r;
// Initialize all graphs
- r = collecty_graphs_create(&self->graphs, self->ctx, self);
+ r = td_graphs_create(&self->graphs, self->ctx, self);
if (r < 0)
return r;
return 0;
}
-static int collecty_daemon_exit(sd_event_source* source, void* data) {
- collecty_daemon* self = data;
+static int td_daemon_exit(sd_event_source* source, void* data) {
+ td_daemon* self = data;
DEBUG(self->ctx, "Cleaning up daemon...\n");
// Free all graphs
if (self->graphs) {
- collecty_graphs_unref(self->graphs);
+ td_graphs_unref(self->graphs);
self->graphs = NULL;
}
// Free all sources
if (self->sources) {
- collecty_sources_unref(self->sources);
+ td_sources_unref(self->sources);
self->sources = NULL;
}
return 0;
}
-static int collecty_daemon_terminate(sd_event_source* source,
+static int td_daemon_terminate(sd_event_source* source,
const struct signalfd_siginfo* si, void* data) {
- collecty_daemon* self = data;
+ td_daemon* self = data;
INFO(self->ctx, "Received signal to terminate...\n");
return sd_event_exit(sd_event_source_get_event(source), 0);
}
-static int collecty_daemon_SIGHUP(sd_event_source* source,
+static int td_daemon_SIGHUP(sd_event_source* source,
const struct signalfd_siginfo* si, void* data) {
- collecty_daemon* self = data;
+ td_daemon* self = data;
// Flush the queue
- return collecty_queue_flush(self->queue);
+ return td_queue_flush(self->queue);
}
-static int collecty_daemon_SIGCHLD(sd_event_source* source,
+static int td_daemon_SIGCHLD(sd_event_source* source,
const struct signalfd_siginfo* si, void* data) {
return 0;
}
-static int collecty_daemon_setup_loop(collecty_daemon* self) {
+static int td_daemon_setup_loop(td_daemon* self) {
int r;
// Create a new loop
// Listen for SIGTERM
r = sd_event_add_signal(self->loop, &self->events.sigterm,
- SIGTERM|SD_EVENT_SIGNAL_PROCMASK, collecty_daemon_terminate, self);
+ SIGTERM|SD_EVENT_SIGNAL_PROCMASK, td_daemon_terminate, self);
if (r < 0) {
ERROR(self->ctx, "Could not register handling SIGTERM: %s\n", strerror(-r));
return r;
// Listen for SIGINT
r = sd_event_add_signal(self->loop, &self->events.sigint,
- SIGINT|SD_EVENT_SIGNAL_PROCMASK, collecty_daemon_terminate, self);
+ SIGINT|SD_EVENT_SIGNAL_PROCMASK, td_daemon_terminate, self);
if (r < 0) {
ERROR(self->ctx, "Could not register handling SIGINT: %s\n", strerror(-r));
return r;
// Listen for SIGHUP
r = sd_event_add_signal(self->loop, &self->events.sighup,
- SIGHUP|SD_EVENT_SIGNAL_PROCMASK, collecty_daemon_SIGHUP, self);
+ SIGHUP|SD_EVENT_SIGNAL_PROCMASK, td_daemon_SIGHUP, self);
if (r < 0) {
ERROR(self->ctx, "Could not register handling SIGHUP: %s\n", strerror(-r));
return r;
// Listen for SIGCHLD
r = sd_event_add_signal(self->loop, &self->events.sighup,
- SIGCHLD|SD_EVENT_SIGNAL_PROCMASK, collecty_daemon_SIGCHLD, self);
+ SIGCHLD|SD_EVENT_SIGNAL_PROCMASK, td_daemon_SIGCHLD, self);
if (r < 0) {
ERROR(self->ctx, "Could not register handling SIGCHLD: %s\n", strerror(-r));
return r;
// Initialize the daemon when the loop starts
r = sd_event_add_defer(self->loop, &self->events.init,
- collecty_daemon_init, self);
+ td_daemon_init, self);
if (r < 0) {
ERROR(self->ctx, "Failed to register daemon init: %s\n", strerror(-r));
return r;
// Cleanup when the event loop exits
r = sd_event_add_exit(self->loop, &self->events.exit,
- collecty_daemon_exit, self);
+ td_daemon_exit, self);
if (r < 0) {
ERROR(self->ctx, "Failed to register daemon exit: %s\n", strerror(-r));
return r;
return 0;
}
-static void collecty_daemon_free(collecty_daemon* self) {
+static void td_daemon_free(td_daemon* self) {
if (self->events.sigchld)
sd_event_source_unref(self->events.sigchld);
if (self->events.sigterm)
if (self->events.exit)
sd_event_source_unref(self->events.exit);
if (self->sources)
- collecty_sources_unref(self->sources);
+ td_sources_unref(self->sources);
if (self->graphs)
- collecty_graphs_unref(self->graphs);
+ td_graphs_unref(self->graphs);
if (self->queue)
- collecty_queue_unref(self->queue);
+ td_queue_unref(self->queue);
if (self->ctx)
- collecty_ctx_unref(self->ctx);
+ td_ctx_unref(self->ctx);
if (self->loop)
sd_event_unref(self->loop);
if (self->bus)
free(self);
}
-int collecty_daemon_create(collecty_daemon** daemon, collecty_ctx* ctx) {
- collecty_daemon* self = NULL;
+int td_daemon_create(td_daemon** daemon, td_ctx* ctx) {
+ td_daemon* self = NULL;
int r;
// Allocate some memory
self->nrefs = 1;
// Store a reference to the context
- self->ctx = collecty_ctx_ref(ctx);
+ self->ctx = td_ctx_ref(ctx);
// Setup the event loop
- r = collecty_daemon_setup_loop(self);
+ r = td_daemon_setup_loop(self);
if (r < 0)
goto ERROR;
// Connect to the bus
- r = collecty_bus_connect(self->ctx, &self->bus, self->loop, self);
+ r = td_bus_connect(self->ctx, &self->bus, self->loop, self);
if (r < 0)
goto ERROR;
// Setup the write queue
- r = collecty_queue_create(&self->queue, self->ctx, self);
+ r = td_queue_create(&self->queue, self->ctx, self);
if (r < 0)
goto ERROR;
ERROR:
if (self)
- collecty_daemon_unref(self);
+ td_daemon_unref(self);
return r;
}
-collecty_daemon* collecty_daemon_ref(collecty_daemon* daemon) {
+td_daemon* td_daemon_ref(td_daemon* daemon) {
++daemon->nrefs;
return daemon;
}
-collecty_daemon* collecty_daemon_unref(collecty_daemon* daemon) {
+td_daemon* td_daemon_unref(td_daemon* daemon) {
if (--daemon->nrefs > 0)
return daemon;
- collecty_daemon_free(daemon);
+ td_daemon_free(daemon);
return NULL;
}
-sd_event* collecty_daemon_loop(collecty_daemon* self) {
+sd_event* td_daemon_loop(td_daemon* self) {
return sd_event_ref(self->loop);
}
-collecty_sources* collecty_daemon_get_sources(collecty_daemon* self) {
+td_sources* td_daemon_get_sources(td_daemon* self) {
if (self->sources)
- return collecty_sources_ref(self->sources);
+ return td_sources_ref(self->sources);
return NULL;
}
-collecty_graphs* collecty_daemon_get_graphs(collecty_daemon* self) {
+td_graphs* td_daemon_get_graphs(td_daemon* self) {
if (self->graphs)
- return collecty_graphs_ref(self->graphs);
+ return td_graphs_ref(self->graphs);
return NULL;
}
-int collecty_daemon_run(collecty_daemon* self) {
+int td_daemon_run(td_daemon* self) {
int r;
// We are now ready
return 1;
}
-int collecty_daemon_submit(collecty_daemon* self,
- collecty_source* source, const char* object, const char* value) {
+int td_daemon_submit(td_daemon* self,
+ td_source* source, const char* object, const char* value) {
// Log action
DEBUG(self->ctx, "%s(%s) submitted: %s\n",
- collecty_source_name(source), (object) ? object : "", value);
+ td_source_name(source), (object) ? object : "", value);
- return collecty_queue_submit(self->queue, source, object, value);
+ return td_queue_submit(self->queue, source, object, value);
}
-int collecty_daemon_flush_source(
- collecty_daemon* self, collecty_source* source, const char* object) {
- return collecty_queue_flush_source(self->queue, source, object);
+int td_daemon_flush_source(
+ td_daemon* self, td_source* source, const char* object) {
+ return td_queue_flush_source(self->queue, source, object);
}
-static int collecty_daemon_bus_version(sd_bus* bus, const char* path, const char* interface,
+static int td_daemon_bus_version(sd_bus* bus, const char* path, const char* interface,
const char* property, sd_bus_message* reply, void* data, sd_bus_error* error) {
return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
}
SD_BUS_VTABLE_START(0),
// Version
- SD_BUS_PROPERTY("Version", "s", collecty_daemon_bus_version,
+ SD_BUS_PROPERTY("Version", "s", td_daemon_bus_version,
0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_VTABLE_END,
};
-const collecty_bus_implementation daemon_bus_impl = {
- .path = "/org/ipfire/collecty1",
- .interface = "org.ipfire.collecty1",
+const td_bus_implementation daemon_bus_impl = {
+ .path = "/org/ipfire/telemetry1",
+ .interface = "org.ipfire.telemetry1",
.vtables = BUS_VTABLES(daemon_vtable),
- .children = BUS_IMPLEMENTATIONS(&collecty_graph_bus_impl),
+ .children = BUS_IMPLEMENTATIONS(&td_graph_bus_impl),
};
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_DAEMON_H
-#define COLLECTY_DAEMON_H
+#ifndef TELEMETRY_DAEMON_H
+#define TELEMETRY_DAEMON_H
#include <systemd/sd-event.h>
-typedef struct collecty_daemon collecty_daemon;
+typedef struct td_daemon td_daemon;
#include "bus.h"
#include "ctx.h"
#include "source.h"
#include "sources.h"
-int collecty_daemon_create(collecty_daemon** daemon, collecty_ctx* ctx);
+int td_daemon_create(td_daemon** daemon, td_ctx* ctx);
-collecty_daemon* collecty_daemon_ref(collecty_daemon* daemon);
-collecty_daemon* collecty_daemon_unref(collecty_daemon* daemon);
+td_daemon* td_daemon_ref(td_daemon* daemon);
+td_daemon* td_daemon_unref(td_daemon* daemon);
-sd_event* collecty_daemon_loop(collecty_daemon* self);
-collecty_sources* collecty_daemon_get_sources(collecty_daemon* self);
-collecty_graphs* collecty_daemon_get_graphs(collecty_daemon* self);
+sd_event* td_daemon_loop(td_daemon* self);
+td_sources* td_daemon_get_sources(td_daemon* self);
+td_graphs* td_daemon_get_graphs(td_daemon* self);
-int collecty_daemon_run(collecty_daemon* self);
+int td_daemon_run(td_daemon* self);
-int collecty_daemon_submit(collecty_daemon* self,
- collecty_source* source, const char* object, const char* value);
+int td_daemon_submit(td_daemon* self,
+ td_source* source, const char* object, const char* value);
-int collecty_daemon_flush_source(
- collecty_daemon* self, collecty_source* source, const char* object);
+int td_daemon_flush_source(
+ td_daemon* self, td_source* source, const char* object);
// Bus
-extern const collecty_bus_implementation daemon_bus_impl;
+extern const td_bus_implementation daemon_bus_impl;
-#endif /* COLLECTY_DAEMON_H */
+#endif /* TELEMETRY_DAEMON_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "file.h"
#include "string.h"
-struct collecty_file {
- collecty_ctx* ctx;
+struct td_file {
+ td_ctx* ctx;
int nrefs;
// File Handle
FILE* f;
};
-static void collecty_file_free(collecty_file* self) {
+static void td_file_free(td_file* self) {
if (self->f)
fclose(self->f);
if (self->ctx)
- collecty_ctx_unref(self->ctx);
+ td_ctx_unref(self->ctx);
free(self);
}
-static int collecty_file_create(collecty_file** file, collecty_ctx* ctx) {
- collecty_file* self = NULL;
+static int td_file_create(td_file** file, td_ctx* ctx) {
+ td_file* self = NULL;
// Allocate some memory
self = calloc(1, sizeof(*self));
self->nrefs = 1;
// Store a reference to the context
- self->ctx = collecty_ctx_ref(ctx);
+ self->ctx = td_ctx_ref(ctx);
// Return the pointer
*file = self;
return 0;
}
-int collecty_file_open_path(collecty_file** file, collecty_ctx* ctx, const char* path) {
- collecty_file* self = NULL;
+int td_file_open_path(td_file** file, td_ctx* ctx, const char* path) {
+ td_file* self = NULL;
int r;
// Create a new object
- r = collecty_file_create(&self, ctx);
+ r = td_file_create(&self, ctx);
if (r < 0)
goto ERROR;
ERROR:
if (self)
- collecty_file_unref(self);
+ td_file_unref(self);
// Reset file
*file = NULL;
return r;
}
-int collecty_file_open_buffer(collecty_file** file, collecty_ctx* ctx, collecty_buffer* buffer) {
- collecty_file* self = NULL;
+int td_file_open_buffer(td_file** file, td_ctx* ctx, td_buffer* buffer) {
+ td_file* self = NULL;
int r;
// Create a new object
- r = collecty_file_create(&self, ctx);
+ r = td_file_create(&self, ctx);
if (r < 0)
goto ERROR;
assert(self);
// Open the buffer as a file
- self->f = collecty_buffer_fopen(buffer, "r");
+ self->f = td_buffer_fopen(buffer, "r");
if (!self->f) {
r = -errno;
goto ERROR;
ERROR:
if (self)
- collecty_file_unref(self);
+ td_file_unref(self);
// Reset file
*file = NULL;
return r;
}
-collecty_file* collecty_file_ref(collecty_file* self) {
+td_file* td_file_ref(td_file* self) {
++self->nrefs;
return self;
}
-collecty_file* collecty_file_unref(collecty_file* self) {
+td_file* td_file_unref(td_file* self) {
if (--self->nrefs > 0)
return self;
- collecty_file_free(self);
+ td_file_free(self);
return NULL;
}
-int collecty_file_read_uint64(collecty_file* self, uint64_t* number) {
+int td_file_read_uint64(td_file* self, uint64_t* number) {
int r;
// Read the number
return 0;
}
-int collecty_file_walk(collecty_file* self,
- collecty_file_walk_callback callback, void* data) {
+int td_file_walk(td_file* self,
+ td_file_walk_callback callback, void* data) {
unsigned long lineno = 0;
char* line = NULL;
size_t length = 0;
}
// Remove the trailing newline
- collecty_string_rstrip(line);
+ td_string_rstrip(line);
// Determine the length of the line
l = strlen(line);
return r;
}
-static unsigned int collecty_file_check_pattern(collecty_file* self, const char* s) {
+static unsigned int td_file_check_pattern(td_file* self, const char* s) {
const char* p = s;
unsigned int counter = 0;
return counter;
}
-static int collecty_file_check_parser(collecty_file* self, collecty_file_parser* parser) {
+static int td_file_check_parser(td_file* self, td_file_parser* parser) {
unsigned int patterns = 0;
// Check all elements
- for (collecty_file_parser* p = parser; p->s; p++) {
+ for (td_file_parser* p = parser; p->s; p++) {
// Count all patterns
- patterns = collecty_file_check_pattern(self, p->s);
+ patterns = td_file_check_pattern(self, p->s);
// Fail if we don't have enough patterns
if (p->n != patterns) {
return 0;
}
-static int __collecty_file_parse(collecty_ctx* ctx, collecty_file* self,
+static int __td_file_parse(td_ctx* ctx, td_file* self,
unsigned long lineno, char* line, size_t length, void* data) {
- collecty_file_parser* parser = data;
+ td_file_parser* parser = data;
int r;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
// Run the parser
- for (collecty_file_parser* p = parser; p->s; p++) {
+ for (td_file_parser* p = parser; p->s; p++) {
r = sscanf(line, p->s, p->v1, p->v2, p->v3, p->v4);
if (r < 0)
return -errno;
return 0;
}
-int collecty_file_parse(collecty_file* self, collecty_file_parser* parser) {
+int td_file_parse(td_file* self, td_file_parser* parser) {
int r;
// Check the parser
- r = collecty_file_check_parser(self, parser);
+ r = td_file_check_parser(self, parser);
if (r < 0)
return r;
// Run the parser
- return collecty_file_walk(self, __collecty_file_parse, parser);
+ return td_file_walk(self, __td_file_parse, parser);
}
-int collecty_read_uint64(collecty_ctx* ctx, const char* path, uint64_t* number) {
- collecty_file* file = NULL;
+int td_read_uint64(td_ctx* ctx, const char* path, uint64_t* number) {
+ td_file* file = NULL;
int r;
// Open the file
- r = collecty_file_open_path(&file, ctx, path);
+ r = td_file_open_path(&file, ctx, path);
if (r < 0)
goto ERROR;
// Read the number
- r = collecty_file_read_uint64(file, number);
+ r = td_file_read_uint64(file, number);
if (r < 0)
goto ERROR;
ERROR:
if (file)
- collecty_file_unref(file);
+ td_file_unref(file);
return r;
}
-int collecty_parse(collecty_ctx* ctx, const char* path, collecty_file_parser* parser) {
- collecty_file* file = NULL;
+int td_parse(td_ctx* ctx, const char* path, td_file_parser* parser) {
+ td_file* file = NULL;
int r;
// Open the file
- r = collecty_file_open_path(&file, ctx, path);
+ r = td_file_open_path(&file, ctx, path);
if (r < 0)
goto ERROR;
// Run the parser
- r = collecty_file_parse(file, parser);
+ r = td_file_parse(file, parser);
if (r < 0)
goto ERROR;
ERROR:
if (file)
- collecty_file_unref(file);
+ td_file_unref(file);
return r;
}
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_FILE_H
-#define COLLECTY_FILE_H
+#ifndef TELEMETRY_FILE_H
+#define TELEMETRY_FILE_H
#include <stdint.h>
-typedef struct collecty_file collecty_file;
+typedef struct td_file td_file;
#include "buffer.h"
#include "ctx.h"
-int collecty_file_open_path(collecty_file** file, collecty_ctx* ctx, const char* path);
-int collecty_file_open_buffer(collecty_file** file, collecty_ctx* ctx, collecty_buffer* buffer);
+int td_file_open_path(td_file** file, td_ctx* ctx, const char* path);
+int td_file_open_buffer(td_file** file, td_ctx* ctx, td_buffer* buffer);
-collecty_file* collecty_file_ref(collecty_file* self);
-collecty_file* collecty_file_unref(collecty_file* self);
+td_file* td_file_ref(td_file* self);
+td_file* td_file_unref(td_file* self);
-int collecty_file_read_uint64(collecty_file* self, uint64_t* number);
+int td_file_read_uint64(td_file* self, uint64_t* number);
-typedef int (*collecty_file_walk_callback)(collecty_ctx* ctx,
- collecty_file* file, unsigned long lineno, char* line, size_t length, void* data);
+typedef int (*td_file_walk_callback)(td_ctx* ctx,
+ td_file* file, unsigned long lineno, char* line, size_t length, void* data);
-int collecty_file_walk(collecty_file* self,
- collecty_file_walk_callback callback, void* data);
+int td_file_walk(td_file* self,
+ td_file_walk_callback callback, void* data);
// Parser
-typedef struct collecty_file_parser {
+typedef struct td_file_parser {
// Pattern
const char* s;
void* v2;
void* v3;
void* v4;
-} collecty_file_parser;
+} td_file_parser;
#define PARSE1(_s, _v1) \
{ .s = _s, .n = 1, .v1 = _v1 }
#define PARSE4(_s, _v1, _v2, _v3, _v4) \
{ .s = _s, .n = 4, .v1 = _v1, .v2 = _v2, .v3 = _v3, .v4 = _v4 }
-int collecty_file_parse(collecty_file* self, collecty_file_parser* parser);
+int td_file_parse(td_file* self, td_file_parser* parser);
// Shorthands
-int collecty_read_uint64(collecty_ctx* ctx, const char* path, uint64_t* number);
-int collecty_parse(collecty_ctx* ctx, const char* path, collecty_file_parser* parser);
+int td_read_uint64(td_ctx* ctx, const char* path, uint64_t* number);
+int td_parse(td_ctx* ctx, const char* path, td_file_parser* parser);
-#endif /* COLLECTY_FILE_H */
+#endif /* TELEMETRY_FILE_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "graph-bus.h"
#include "string.h"
-static int collecty_graph_node_enumerator(sd_bus* bus,
+static int td_graph_node_enumerator(sd_bus* bus,
const char* path, void* data, char*** nodes, sd_bus_error* error) {
- collecty_daemon* daemon = data;
- collecty_graphs* graphs = NULL;
+ td_daemon* daemon = data;
+ td_graphs* graphs = NULL;
int r = 1;
// Fetch all graphs
- graphs = collecty_daemon_get_graphs(daemon);
+ graphs = td_daemon_get_graphs(daemon);
if (!graphs)
goto ERROR;
// Fetch the bus paths
- *nodes = collecty_graphs_get_bus_paths(graphs);
+ *nodes = td_graphs_get_bus_paths(graphs);
if (*nodes)
goto ERROR;
ERROR:
if (graphs)
- collecty_graphs_unref(graphs);
+ td_graphs_unref(graphs);
return r;
}
-static int collecty_graph_object_find(sd_bus* bus, const char* path,
+static int td_graph_object_find(sd_bus* bus, const char* path,
const char* interface, void* data, void** found, sd_bus_error* error) {
- collecty_daemon* daemon = data;
- collecty_graphs* graphs = NULL;
- collecty_graph* graph = NULL;
+ td_daemon* daemon = data;
+ td_graphs* graphs = NULL;
+ td_graph* graph = NULL;
char* name = NULL;
int r;
// Decode the path of the requested object
- r = sd_bus_path_decode(path, "/org/ipfire/collecty1/graph", &name);
+ r = sd_bus_path_decode(path, "/org/ipfire/telemetry1/graph", &name);
if (r <= 0) {
r = 0;
goto ERROR;
}
// Fetch all graphs
- graphs = collecty_daemon_get_graphs(daemon);
+ graphs = td_daemon_get_graphs(daemon);
if (!graphs) {
r = 0;
goto ERROR;
}
// Find the graph
- graph = collecty_graphs_get_by_name(graphs, name);
+ graph = td_graphs_get_by_name(graphs, name);
if (!graph) {
r = 0;
goto ERROR;
ERROR:
if (graphs)
- collecty_graphs_unref(graphs);
+ td_graphs_unref(graphs);
if (graph)
- collecty_graph_unref(graph);
+ td_graph_unref(graph);
return r;
}
-static int collecty_graph_bus_render(sd_bus_message* m, void* data, sd_bus_error* error) {
- collecty_graph_render_options options = {};
- collecty_graph* graph = data;
+static int td_graph_bus_render(sd_bus_message* m, void* data, sd_bus_error* error) {
+ td_graph_render_options options = {};
+ td_graph* graph = data;
sd_bus_message* reply = NULL;
const char* object = NULL;
const char* key = NULL;
goto ERROR;
// Parse "format"
- if (collecty_string_equals(key, "format")) {
+ if (td_string_equals(key, "format")) {
r = sd_bus_message_read(m, "v", "s", &options.format);
if (r < 0)
goto ERROR;
// Parse "height"
- } else if (collecty_string_equals(key, "height")) {
+ } else if (td_string_equals(key, "height")) {
r = sd_bus_message_read(m, "v", "t", &options.dimensions.h);
if (r < 0)
goto ERROR;
// Parse "width"
- } else if (collecty_string_equals(key, "width")) {
+ } else if (td_string_equals(key, "width")) {
r = sd_bus_message_read(m, "v", "t", &options.dimensions.w);
if (r < 0)
goto ERROR;
goto ERROR;
// Render the graph
- r = collecty_graph_render(graph, object, &options, &buffer, &length);
+ r = td_graph_render(graph, object, &options, &buffer, &length);
if (r < 0)
goto ERROR;
}
-static const sd_bus_vtable collecty_graph_vtable[] = {
+static const sd_bus_vtable td_graph_vtable[] = {
SD_BUS_VTABLE_START(0),
// Operations
SD_BUS_METHOD_WITH_ARGS("Render", SD_BUS_ARGS("s", graph, "a{sv}", options), SD_BUS_RESULT("ay", graph),
- collecty_graph_bus_render, SD_BUS_VTABLE_UNPRIVILEGED),
+ td_graph_bus_render, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
-const collecty_bus_implementation collecty_graph_bus_impl = {
- "/org/ipfire/collecty1/graph",
- "org.ipfire.collecty1.Graph",
- .fallback_vtables = BUS_FALLBACK_VTABLES({collecty_graph_vtable, collecty_graph_object_find}),
- .node_enumerator = collecty_graph_node_enumerator,
+const td_bus_implementation td_graph_bus_impl = {
+ "/org/ipfire/telemetry1/graph",
+ "org.ipfire.telemetry1.Graph",
+ .fallback_vtables = BUS_FALLBACK_VTABLES({td_graph_vtable, td_graph_object_find}),
+ .node_enumerator = td_graph_node_enumerator,
};
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_GRAPH_BUS_H
-#define COLLECTY_GRAPH_BUS_H
+#ifndef TELEMETRY_GRAPH_BUS_H
+#define TELEMETRY_GRAPH_BUS_H
#include "bus.h"
-extern const collecty_bus_implementation collecty_graph_bus_impl;
+extern const td_bus_implementation td_graph_bus_impl;
-#endif /* COLLECTY_GRAPH_BUS_H */
+#endif /* TELEMETRY_GRAPH_BUS_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#define TITLE_MAX 128
#define VLABEL_MAX 64
-struct collecty_graph {
- collecty_ctx* ctx;
+struct td_graph {
+ td_ctx* ctx;
int nrefs;
// Daemon
- collecty_daemon* daemon;
+ td_daemon* daemon;
// Implementation
- const collecty_graph_impl* impl;
+ const td_graph_impl* impl;
};
const char* DEFAULT_RENDER_ARGS[] = {
const unsigned int DEFAULT_HEIGHT = 480;
const unsigned int DEFAULT_WIDTH = 960;
-static int collecty_graph_check(collecty_graph* self) {
+static int td_graph_check(td_graph* self) {
// Check if upper and lower limits are set (at least one must be set)
if (!self->impl->lower_limit && !self->impl->upper_limit) {
ERROR(self->ctx, "lower_limit and upper_limit are not set\n");
return 0;
}
-static void collecty_graph_free(collecty_graph* self) {
+static void td_graph_free(td_graph* self) {
if (self->daemon)
- collecty_daemon_unref(self->daemon);
+ td_daemon_unref(self->daemon);
if (self->ctx)
- collecty_ctx_unref(self->ctx);
+ td_ctx_unref(self->ctx);
free(self);
}
-int collecty_graph_create(collecty_graph** graph,
- collecty_ctx* ctx, collecty_daemon* daemon, const collecty_graph_impl* impl) {
- collecty_graph* self = NULL;
+int td_graph_create(td_graph** graph,
+ td_ctx* ctx, td_daemon* daemon, const td_graph_impl* impl) {
+ td_graph* self = NULL;
int r;
// Allocate some memory
self->nrefs = 1;
// Store a reference to the context
- self->ctx = collecty_ctx_ref(ctx);
+ self->ctx = td_ctx_ref(ctx);
// Store a reference to the daemon
- self->daemon = collecty_daemon_ref(daemon);
+ self->daemon = td_daemon_ref(daemon);
// Store the implementation
self->impl = impl;
// Perform some basic checks
- r = collecty_graph_check(self);
+ r = td_graph_check(self);
if (r < 0)
goto ERROR;
ERROR:
if (self)
- collecty_graph_unref(self);
+ td_graph_unref(self);
return r;
}
-collecty_graph* collecty_graph_ref(collecty_graph* self) {
+td_graph* td_graph_ref(td_graph* self) {
++self->nrefs;
return self;
}
-collecty_graph* collecty_graph_unref(collecty_graph* self) {
+td_graph* td_graph_unref(td_graph* self) {
if (--self->nrefs > 0)
return self;
- collecty_graph_free(self);
+ td_graph_free(self);
return NULL;
}
-const char* collecty_graph_get_name(collecty_graph* self) {
+const char* td_graph_get_name(td_graph* self) {
return self->impl->name;
}
-char* collecty_graph_get_bus_path(collecty_graph* self) {
+char* td_graph_get_bus_path(td_graph* self) {
const char* name = NULL;
char* path = NULL;
int r;
// Fetch the name
- name = collecty_graph_get_name(self);
+ name = td_graph_get_name(self);
if (!name)
return NULL;
// Format the bus path
- r = sd_bus_path_encode("/org/ipfire/collecty1/graph", name, &path);
+ r = sd_bus_path_encode("/org/ipfire/telemetry1/graph", name, &path);
if (r < 0)
return NULL;
return path;
}
-int collecty_graph_require_source(collecty_graph* self,
- collecty_args* args, const char* name, const char* object) {
- collecty_sources* sources = NULL;
- collecty_source* source = NULL;
+int td_graph_require_source(td_graph* self,
+ td_args* args, const char* name, const char* object) {
+ td_sources* sources = NULL;
+ td_source* source = NULL;
int r;
// Fetch all sources
- sources = collecty_daemon_get_sources(self->daemon);
+ sources = td_daemon_get_sources(self->daemon);
if (!sources) {
r = -ENOTSUP;
goto ERROR;
}
// Fetch the source by its name
- source = collecty_sources_get_by_name(sources, name);
+ source = td_sources_get_by_name(sources, name);
if (!source) {
ERROR(self->ctx, "Could not find source '%s'\n", name);
r = -ENOENT;
}
// Add the data of the source
- r = collecty_source_render(source, args, object);
+ r = td_source_render(source, args, object);
if (r < 0)
goto ERROR;
ERROR:
if (sources)
- collecty_sources_unref(sources);
+ td_sources_unref(sources);
if (source)
- collecty_source_unref(source);
+ td_source_unref(source);
return r;
}
-int collecty_graph_render(collecty_graph* self, const char* object,
- const collecty_graph_render_options* options, char** buffer, size_t* length) {
- collecty_args* args = NULL;
+int td_graph_render(td_graph* self, const char* object,
+ const td_graph_render_options* options, char** buffer, size_t* length) {
+ td_args* args = NULL;
char vlabel[VLABEL_MAX] = "";
char title[TITLE_MAX] = "";
char** data = NULL;
clock_t t_end = 0;
// Log action
- DEBUG(self->ctx, "Rendering %s...\n", collecty_graph_get_name(self));
+ DEBUG(self->ctx, "Rendering %s...\n", td_graph_get_name(self));
// Fail if we don't have a render function
if (!self->impl->render)
}
// Allocate a new argument list
- r = collecty_args_create(&args, self->ctx);
+ r = td_args_create(&args, self->ctx);
if (r < 0)
goto ERROR;
// Push the default arguments
- r = collecty_args_pushv(args, DEFAULT_RENDER_ARGS);
+ r = td_args_pushv(args, DEFAULT_RENDER_ARGS);
if (r < 0)
goto ERROR;
// Select the output format
if (options->format) {
- r = collecty_args_push(args, "--imgformat=%s", options->format);
+ r = td_args_push(args, "--imgformat=%s", options->format);
if (r < 0)
goto ERROR;
}
// Configure the desired output height
- r = collecty_args_push(args, "--height=%u",
+ r = td_args_push(args, "--height=%u",
(options->dimensions.h) ? options->dimensions.h : DEFAULT_HEIGHT);
if (r < 0)
goto ERROR;
// Configure the desired output width
- r = collecty_args_push(args, "--width=%u",
+ r = td_args_push(args, "--width=%u",
(options->dimensions.w) ? options->dimensions.w : DEFAULT_WIDTH);
if (r < 0)
goto ERROR;
// Set lower limit
if (self->impl->lower_limit > -LONG_MAX) {
- r = collecty_args_push(args, "--lower-limit=%ld", self->impl->lower_limit);
+ r = td_args_push(args, "--lower-limit=%ld", self->impl->lower_limit);
if (r < 0)
goto ERROR;
}
// Set upper limit
if (self->impl->upper_limit < LONG_MAX) {
- r = collecty_args_push(args, "--upper-limit=%ld", self->impl->upper_limit);
+ r = td_args_push(args, "--upper-limit=%ld", self->impl->upper_limit);
if (r < 0)
goto ERROR;
}
// Add the title to the command line
if (*title) {
- r = collecty_args_push(args, "--title=%s", title);
+ r = td_args_push(args, "--title=%s", title);
if (r < 0)
goto ERROR;
}
// Add the vertical label to the command line
if (*vlabel) {
- r = collecty_args_push(args, "--vertical-label=%s", vlabel);
+ r = td_args_push(args, "--vertical-label=%s", vlabel);
if (r < 0)
goto ERROR;
}
// Invert the legend?
// This way, we can draw graphs from back to front
// to be able to user overlay and transparency.
- if (self->impl->flags & COLLECTY_GRAPH_REVERSE) {
- r = collecty_args_push(args, "--legend-direction=bottomup");
+ if (self->impl->flags & TELEMETRY_GRAPH_REVERSE) {
+ r = td_args_push(args, "--legend-direction=bottomup");
if (r < 0)
goto ERROR;
}
// Write the graph to the output stream
- r = collecty_args_push(args, "-");
+ r = td_args_push(args, "-");
if (r < 0)
goto ERROR;
goto ERROR;
// Dump the command
- r = collecty_args_dump(args);
+ r = td_args_dump(args);
if (r < 0)
goto ERROR;
// Render the graph
// We are casting the argument array to (void*) to silence a compiler
// warning since rrdtool >= 1.9 has constified their input arguments.
- r = rrd_graph(collecty_args_argc(args), (void*)collecty_args_argv(args),
+ r = rrd_graph(td_args_argc(args), (void*)td_args_argv(args),
&data, &w, &h, f, &ymin, &ymax);
if (r < 0) {
ERROR(self->ctx, "Failed to generate the graph: %s\n", rrd_get_error());
}
// Log action
- DEBUG(self->ctx, "Rendered graph %s in %.2fms:\n", collecty_graph_get_name(self),
+ DEBUG(self->ctx, "Rendered graph %s in %.2fms:\n", td_graph_get_name(self),
USEC_TO_MSEC((double)(t_end - t_start) / CLOCKS_PER_SEC));
DEBUG(self->ctx, " size : %d byte(s)\n", ftell(f));
DEBUG(self->ctx, " width : %d\n", w);
free(data);
}
if (args)
- collecty_args_unref(args);
+ td_args_unref(args);
if (f)
fclose(f);
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_GRAPH_H
-#define COLLECTY_GRAPH_H
+#ifndef TELEMETRY_GRAPH_H
+#define TELEMETRY_GRAPH_H
-typedef struct collecty_graph collecty_graph;
+typedef struct td_graph td_graph;
#include "args.h"
#include "ctx.h"
#include "daemon.h"
#include "graph.h"
-typedef struct collecty_graph_impl {
+typedef struct td_graph_impl {
// Name
const char* name;
// Flags
enum {
- COLLECTY_GRAPH_REVERSE = (1 << 0),
+ TELEMETRY_GRAPH_REVERSE = (1 << 0),
} flags;
// Limits
long upper_limit;
// Available
- int (*available)(collecty_ctx* ctx, collecty_daemon* daemon);
+ int (*available)(td_ctx* ctx, td_daemon* daemon);
// Render!
- int (*render)(collecty_ctx* ctx, collecty_graph* graph,
- collecty_args* args, const char* object);
+ int (*render)(td_ctx* ctx, td_graph* graph,
+ td_args* args, const char* object);
// Title
- int (*title)(collecty_ctx* ctx, collecty_graph* graph,
+ int (*title)(td_ctx* ctx, td_graph* graph,
const char* object, char* title, size_t length);
// Vertical Label
- int (*vlabel)(collecty_ctx* ctx, collecty_graph* graph,
+ int (*vlabel)(td_ctx* ctx, td_graph* graph,
const char* object, char* vlabel, size_t length);
-} collecty_graph_impl;
+} td_graph_impl;
-int collecty_graph_create(collecty_graph** graph,
- collecty_ctx* ctx, collecty_daemon* daemon, const collecty_graph_impl* impl);
+int td_graph_create(td_graph** graph,
+ td_ctx* ctx, td_daemon* daemon, const td_graph_impl* impl);
-collecty_graph* collecty_graph_ref(collecty_graph* self);
-collecty_graph* collecty_graph_unref(collecty_graph* self);
+td_graph* td_graph_ref(td_graph* self);
+td_graph* td_graph_unref(td_graph* self);
-const char* collecty_graph_get_name(collecty_graph* self);
-char* collecty_graph_get_bus_path(collecty_graph* self);
+const char* td_graph_get_name(td_graph* self);
+char* td_graph_get_bus_path(td_graph* self);
-int collecty_graph_require_source(collecty_graph* self,
- collecty_args* args, const char* name, const char* object);
+int td_graph_require_source(td_graph* self,
+ td_args* args, const char* name, const char* object);
-typedef struct collecty_graph_render_options {
+typedef struct td_graph_render_options {
// Output Format
const char* format;
unsigned int h;
unsigned int w;
} dimensions;
-} collecty_graph_render_options;
+} td_graph_render_options;
-int collecty_graph_render(collecty_graph* self, const char* object,
- const collecty_graph_render_options* options, char** buffer, size_t* length);
+int td_graph_render(td_graph* self, const char* object,
+ const td_graph_render_options* options, char** buffer, size_t* length);
-#endif /* COLLECTY_GRAPH_H */
+#endif /* TELEMETRY_GRAPH_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "graphs/uptime.h"
// Register all graphs
-static const collecty_graph_impl* graph_impls[] = {
+static const td_graph_impl* graph_impls[] = {
&conntrack_graph,
&contextswitches_graph,
&loadavg_graph,
NULL,
};
-struct collecty_graphs {
- collecty_ctx* ctx;
+struct td_graphs {
+ td_ctx* ctx;
int nrefs;
// Daemon
- collecty_daemon* daemon;
+ td_daemon* daemon;
// Graphs
- collecty_graph** graphs;
+ td_graph** graphs;
unsigned int num_graphs;
};
-static int collecty_graphs_init(collecty_graphs* self) {
- collecty_graph** graphs = NULL;
- collecty_graph* graph = NULL;
+static int td_graphs_init(td_graphs* self) {
+ td_graph** graphs = NULL;
+ td_graph* graph = NULL;
int r;
// Initialize all graphs
- for (const collecty_graph_impl** impl = graph_impls; *impl; impl++) {
- r = collecty_graph_create(&graph, self->ctx, self->daemon, *impl);
+ for (const td_graph_impl** impl = graph_impls; *impl; impl++) {
+ r = td_graph_create(&graph, self->ctx, self->daemon, *impl);
if (r < 0)
return r;
}
// Store a reference to the graph in the array
- graphs[self->num_graphs++] = collecty_graph_ref(graph);
+ graphs[self->num_graphs++] = td_graph_ref(graph);
// Replace the array
self->graphs = graphs;
// Unref the graph
- collecty_graph_unref(graph);
+ td_graph_unref(graph);
graph = NULL;
}
ERROR:
if (graph)
- collecty_graph_unref(graph);
+ td_graph_unref(graph);
return r;
}
-static void collecty_graphs_free(collecty_graphs* self) {
+static void td_graphs_free(td_graphs* self) {
if (self->graphs) {
for (unsigned int i = 0; i < self->num_graphs; i++)
- collecty_graph_unref(self->graphs[i]);
+ td_graph_unref(self->graphs[i]);
free(self->graphs);
}
if (self->daemon)
- collecty_daemon_unref(self->daemon);
+ td_daemon_unref(self->daemon);
if (self->ctx)
- collecty_ctx_unref(self->ctx);
+ td_ctx_unref(self->ctx);
free(self);
}
-int collecty_graphs_create(collecty_graphs** graphs,
- collecty_ctx* ctx, collecty_daemon* daemon) {
- collecty_graphs* self = NULL;
+int td_graphs_create(td_graphs** graphs,
+ td_ctx* ctx, td_daemon* daemon) {
+ td_graphs* self = NULL;
int r;
// Allocate some memory
self->nrefs = 1;
// Store a reference to the context
- self->ctx = collecty_ctx_ref(ctx);
+ self->ctx = td_ctx_ref(ctx);
// Store a reference to the daemon
- self->daemon = collecty_daemon_ref(daemon);
+ self->daemon = td_daemon_ref(daemon);
// Setup all graphs
- r = collecty_graphs_init(self);
+ r = td_graphs_init(self);
if (r < 0)
goto ERROR;
ERROR:
if (self)
- collecty_graphs_unref(self);
+ td_graphs_unref(self);
return r;
}
-collecty_graphs* collecty_graphs_ref(collecty_graphs* self) {
+td_graphs* td_graphs_ref(td_graphs* self) {
++self->nrefs;
return self;
}
-collecty_graphs* collecty_graphs_unref(collecty_graphs* self) {
+td_graphs* td_graphs_unref(td_graphs* self) {
if (--self->nrefs > 0)
return self;
- collecty_graphs_free(self);
+ td_graphs_free(self);
return NULL;
}
-collecty_graph* collecty_graphs_get_by_name(collecty_graphs* self, const char* name) {
+td_graph* td_graphs_get_by_name(td_graphs* self, const char* name) {
const char* n = NULL;
// Iterate over all graphs to find a match
for (unsigned int i = 0; i < self->num_graphs; i++) {
// Fetch the name
- n = collecty_graph_get_name(self->graphs[i]);
+ n = td_graph_get_name(self->graphs[i]);
if (!n)
continue;
// Return the object if the name matches
- if (collecty_string_equals(name, n))
- return collecty_graph_ref(self->graphs[i]);
+ if (td_string_equals(name, n))
+ return td_graph_ref(self->graphs[i]);
}
return NULL;
}
-char** collecty_graphs_get_bus_paths(collecty_graphs* self) {
+char** td_graphs_get_bus_paths(td_graphs* self) {
char** paths = NULL;
char* path = NULL;
// Add all paths for all graphs
for (unsigned int i = 0; i < self->num_graphs; i++) {
// Fetch the bus path
- path = collecty_graph_get_bus_path(self->graphs[i]);
+ path = td_graph_get_bus_path(self->graphs[i]);
if (!path)
continue;
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_GRAPHS_H
-#define COLLECTY_GRAPHS_H
+#ifndef TELEMETRY_GRAPHS_H
+#define TELEMETRY_GRAPHS_H
-typedef struct collecty_graphs collecty_graphs;
+typedef struct td_graphs td_graphs;
#include "ctx.h"
#include "daemon.h"
#include "graph.h"
-int collecty_graphs_create(collecty_graphs** graphs, collecty_ctx* ctx, collecty_daemon* daemon);
+int td_graphs_create(td_graphs** graphs, td_ctx* ctx, td_daemon* daemon);
-collecty_graphs* collecty_graphs_ref(collecty_graphs* self);
-collecty_graphs* collecty_graphs_unref(collecty_graphs* self);
+td_graphs* td_graphs_ref(td_graphs* self);
+td_graphs* td_graphs_unref(td_graphs* self);
-collecty_graph* collecty_graphs_get_by_name(collecty_graphs* self, const char* name);
-char** collecty_graphs_get_bus_paths(collecty_graphs* self);
+td_graph* td_graphs_get_by_name(td_graphs* self, const char* name);
+char** td_graphs_get_bus_paths(td_graphs* self);
-#endif /* COLLECTY_GRAPHS_H */
+#endif /* TELEMETRY_GRAPHS_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "graph.h"
#include "conntrack.h"
-static int conntrack_title(collecty_ctx* ctx,
- collecty_graph* graph, const char* object, char* title, size_t length) {
- return __collecty_string_set(title, length, _("Connection Tracking Table"));
+static int conntrack_title(td_ctx* ctx,
+ td_graph* graph, const char* object, char* title, size_t length) {
+ return __td_string_set(title, length, _("Connection Tracking Table"));
}
-static int conntrack_vlabel(collecty_ctx* ctx,
- collecty_graph* graph, const char* object, char* vlabel, size_t length) {
- return __collecty_string_set(vlabel, length, _("Entries"));
+static int conntrack_vlabel(td_ctx* ctx,
+ td_graph* graph, const char* object, char* vlabel, size_t length) {
+ return __td_string_set(vlabel, length, _("Entries"));
}
-static int conntrack_render(collecty_ctx* ctx,
- collecty_graph* graph, collecty_args* args, const char* object) {
+static int conntrack_render(td_ctx* ctx,
+ td_graph* graph, td_args* args, const char* object) {
int r;
// This requires the conntrack source
- r = collecty_graph_require_source(graph, args, "conntrack", object);
+ r = td_graph_require_source(graph, args, "conntrack", object);
if (r < 0)
return r;
return 0;
}
-const collecty_graph_impl conntrack_graph = {
+const td_graph_impl conntrack_graph = {
.name = "Conntrack",
.render = conntrack_render,
.title = conntrack_title,
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_GRAPH_CONNTRACK_H
-#define COLLECTY_GRAPH_CONNTRACK_H
+#ifndef TELEMETRY_GRAPH_CONNTRACK_H
+#define TELEMETRY_GRAPH_CONNTRACK_H
#include "../graph.h"
-extern const collecty_graph_impl conntrack_graph;
+extern const td_graph_impl conntrack_graph;
-#endif /* COLLECTY_GRAPH_CONNTRACK_H */
+#endif /* TELEMETRY_GRAPH_CONNTRACK_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "graph.h"
#include "contextswitches.h"
-static int contextswitches_title(collecty_ctx* ctx,
- collecty_graph* graph, const char* object, char* title, size_t length) {
- return __collecty_string_set(title, length, _("Context Switches"));
+static int contextswitches_title(td_ctx* ctx,
+ td_graph* graph, const char* object, char* title, size_t length) {
+ return __td_string_set(title, length, _("Context Switches"));
}
-static int contextswitches_vlabel(collecty_ctx* ctx,
- collecty_graph* graph, const char* object, char* vlabel, size_t length) {
- return __collecty_string_set(vlabel, length, _("Context Switches/s"));
+static int contextswitches_vlabel(td_ctx* ctx,
+ td_graph* graph, const char* object, char* vlabel, size_t length) {
+ return __td_string_set(vlabel, length, _("Context Switches/s"));
}
-static int contextswitches_render(collecty_ctx* ctx,
- collecty_graph* graph, collecty_args* args, const char* object) {
+static int contextswitches_render(td_ctx* ctx,
+ td_graph* graph, td_args* args, const char* object) {
int r;
// This requires the contextswitches source
- r = collecty_graph_require_source(graph, args, "contextswitches", object);
+ r = td_graph_require_source(graph, args, "contextswitches", object);
if (r < 0)
return r;
return 0;
}
-const collecty_graph_impl contextswitches_graph = {
+const td_graph_impl contextswitches_graph = {
.name = "ContextSwitches",
.render = contextswitches_render,
.title = contextswitches_title,
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_GRAPH_CONTEXTSWITCHES_H
-#define COLLECTY_GRAPH_CONTEXTSWITCHES_H
+#ifndef TELEMETRY_GRAPH_CONTEXTSWITCHES_H
+#define TELEMETRY_GRAPH_CONTEXTSWITCHES_H
#include "../graph.h"
-extern const collecty_graph_impl contextswitches_graph;
+extern const td_graph_impl contextswitches_graph;
-#endif /* COLLECTY_GRAPH_CONTEXTSWITCHES_H */
+#endif /* TELEMETRY_GRAPH_CONTEXTSWITCHES_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_GRAPHS_GRAPH_H
-#define COLLECTY_GRAPHS_GRAPH_H
+#ifndef TELEMETRY_GRAPHS_GRAPH_H
+#define TELEMETRY_GRAPHS_GRAPH_H
/*
This is a convenience header that includes several things that we need
#define SCRIPT(args, def, ...) \
do { \
- int __r = collecty_args_push(args, def, ##__VA_ARGS__); \
+ int __r = td_args_push(args, def, ##__VA_ARGS__); \
if (__r < 0) \
return __r; \
} while(0)
} while (0)
-#endif /* COLLECTY_GRAPHS_GRAPH_H */
+#endif /* TELEMETRY_GRAPHS_GRAPH_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#define COLOR_LOAD5 ORANGE
#define COLOR_LOAD1 YELLOW
-static int loadavg_title(collecty_ctx* ctx, collecty_graph* graph,
+static int loadavg_title(td_ctx* ctx, td_graph* graph,
const char* object, char* title, size_t length) {
- return __collecty_string_set(title, length, _("Load Average"));
+ return __td_string_set(title, length, _("Load Average"));
}
-static int loadavg_render(collecty_ctx* ctx,
- collecty_graph* graph, collecty_args* args, const char* object) {
+static int loadavg_render(td_ctx* ctx,
+ td_graph* graph, td_args* args, const char* object) {
int r;
// This requires the loadavg source
- r = collecty_graph_require_source(graph, args, "loadavg", object);
+ r = td_graph_require_source(graph, args, "loadavg", object);
if (r < 0)
return r;
return 0;
}
-const collecty_graph_impl loadavg_graph = {
+const td_graph_impl loadavg_graph = {
.name = "LoadAverage",
.render = loadavg_render,
.title = loadavg_title,
.vlabel = loadavg_title,
// Flags
- .flags = COLLECTY_GRAPH_REVERSE,
+ .flags = TELEMETRY_GRAPH_REVERSE,
// Limits
.lower_limit = 0,
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_GRAPH_LOADAVG_H
-#define COLLECTY_GRAPH_LOADAVG_H
+#ifndef TELEMETRY_GRAPH_LOADAVG_H
+#define TELEMETRY_GRAPH_LOADAVG_H
#include "../graph.h"
-extern const collecty_graph_impl loadavg_graph;
+extern const td_graph_impl loadavg_graph;
-#endif /* COLLECTY_GRAPH_LOADAVG_H */
+#endif /* TELEMETRY_GRAPH_LOADAVG_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#define COLOR_SWAP_USED RED
#define COLOR_SWAP_TOTAL BLACK
-static int memory_title(collecty_ctx* ctx, collecty_graph* graph,
+static int memory_title(td_ctx* ctx, td_graph* graph,
const char* object, char* title, size_t length) {
- return __collecty_string_set(title, length, _("Memory Usage"));
+ return __td_string_set(title, length, _("Memory Usage"));
}
-static int memory_vlabel(collecty_ctx* ctx, collecty_graph* graph,
+static int memory_vlabel(td_ctx* ctx, td_graph* graph,
const char* object, char* vlabel, size_t length) {
- return __collecty_string_set(vlabel, length, _("Bytes"));
+ return __td_string_set(vlabel, length, _("Bytes"));
}
-static int memory_render(collecty_ctx* ctx,
- collecty_graph* graph, collecty_args* args, const char* object) {
+static int memory_render(td_ctx* ctx,
+ td_graph* graph, td_args* args, const char* object) {
int r;
// This requires the loadavg source
- r = collecty_graph_require_source(graph, args, "memory", object);
+ r = td_graph_require_source(graph, args, "memory", object);
if (r < 0)
return r;
return 0;
}
-const collecty_graph_impl memory_graph = {
+const td_graph_impl memory_graph = {
.name = "Memory",
.render = memory_render,
.title = memory_title,
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_GRAPH_MEMORY_H
-#define COLLECTY_GRAPH_MEMORY_H
+#ifndef TELEMETRY_GRAPH_MEMORY_H
+#define TELEMETRY_GRAPH_MEMORY_H
#include "../graph.h"
-extern const collecty_graph_impl memory_graph;
+extern const td_graph_impl memory_graph;
-#endif /* COLLECTY_GRAPH_MEMORY_H */
+#endif /* TELEMETRY_GRAPH_MEMORY_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#define COLOR_GUEST_NICE PINK
#define COLOR_IDLE LIGHT_GREY
-static int processor_title(collecty_ctx* ctx, collecty_graph* graph,
+static int processor_title(td_ctx* ctx, td_graph* graph,
const char* object, char* title, size_t length) {
- return __collecty_string_set(title, length, _("Processor Usage"));
+ return __td_string_set(title, length, _("Processor Usage"));
}
-static int processor_vlabel(collecty_ctx* ctx, collecty_graph* graph,
+static int processor_vlabel(td_ctx* ctx, td_graph* graph,
const char* object, char* vlabel, size_t length) {
- return __collecty_string_set(vlabel, length, _("Percent"));
+ return __td_string_set(vlabel, length, _("Percent"));
}
-static int processor_render(collecty_ctx* ctx,
- collecty_graph* graph, collecty_args* args, const char* object) {
+static int processor_render(td_ctx* ctx,
+ td_graph* graph, td_args* args, const char* object) {
int r;
// This requires the loadavg source
- r = collecty_graph_require_source(graph, args, "processor", object);
+ r = td_graph_require_source(graph, args, "processor", object);
if (r < 0)
return r;
// Add up all used cycles
- r = collecty_args_push(args,
+ r = td_args_push(args,
"CDEF:usage=user,nice,+,sys,+,wait,+,irq,+,softirq,+,steal,+,guest,+,guest_nice,+");
if (r < 0)
return r;
return 0;
}
-const collecty_graph_impl processor_graph = {
+const td_graph_impl processor_graph = {
.name = "Processor",
.render = processor_render,
.title = processor_title,
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_GRAPH_PROCESSOR_H
-#define COLLECTY_GRAPH_PROCESSOR_H
+#ifndef TELEMETRY_GRAPH_PROCESSOR_H
+#define TELEMETRY_GRAPH_PROCESSOR_H
#include "../graph.h"
-extern const collecty_graph_impl processor_graph;
+extern const td_graph_impl processor_graph;
-#endif /* COLLECTY_GRAPH_PROCESSOR_H */
+#endif /* TELEMETRY_GRAPH_PROCESSOR_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "graph.h"
#include "uptime.h"
-static int uptime_title(collecty_ctx* ctx, collecty_graph* graph,
+static int uptime_title(td_ctx* ctx, td_graph* graph,
const char* object, char* title, size_t length) {
- return __collecty_string_set(title, length, _("Uptime"));
+ return __td_string_set(title, length, _("Uptime"));
}
-static int uptime_vlabel(collecty_ctx* ctx, collecty_graph* graph,
+static int uptime_vlabel(td_ctx* ctx, td_graph* graph,
const char* object, char* vlabel, size_t length) {
- return __collecty_string_set(vlabel, length, _("Days"));
+ return __td_string_set(vlabel, length, _("Days"));
}
-static int uptime_render(collecty_ctx* ctx,
- collecty_graph* graph, collecty_args* args, const char* object) {
+static int uptime_render(td_ctx* ctx,
+ td_graph* graph, td_args* args, const char* object) {
int r;
// This requires the uptime source
- r = collecty_graph_require_source(graph, args, "uptime", object);
+ r = td_graph_require_source(graph, args, "uptime", object);
if (r < 0)
return r;
return 0;
}
-const collecty_graph_impl uptime_graph = {
+const td_graph_impl uptime_graph = {
.name = "Uptime",
.render = uptime_render,
.title = uptime_title,
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_GRAPH_UPTIME_H
-#define COLLECTY_GRAPH_UPTIME_H
+#ifndef TELEMETRY_GRAPH_UPTIME_H
+#define TELEMETRY_GRAPH_UPTIME_H
#include "../graph.h"
-extern const collecty_graph_impl uptime_graph;
+extern const td_graph_impl uptime_graph;
-#endif /* COLLECTY_GRAPH_UPTIME_H */
+#endif /* TELEMETRY_GRAPH_UPTIME_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_I18N_H
-#define COLLECTY_I18N_H
+#ifndef TELEMETRY_I18N_H
+#define TELEMETRY_I18N_H
#include <libintl.h>
#define _(x) dgettext(PACKAGE_NAME, x)
-#endif /* COLLECTY_I18N_H */
+#endif /* TELEMETRY_I18N_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "ctx.h"
#include "logging.h"
-void collecty_log_stderr(void* data, int priority, const char* file,
+void td_log_stderr(void* data, int priority, const char* file,
int line, const char* fn, const char* format, va_list args) {
fprintf(stderr, PACKAGE_NAME ": ");
vfprintf(stderr, format, args);
}
-void collecty_log_syslog(void* data, int priority, const char* file,
+void td_log_syslog(void* data, int priority, const char* file,
int line, const char* fn, const char* format, va_list args) {
char* buffer = NULL;
int r;
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_LOGGING_H
-#define COLLECTY_LOGGING_H
+#ifndef TELEMETRY_LOGGING_H
+#define TELEMETRY_LOGGING_H
#include <stdarg.h>
#include <syslog.h>
-typedef void (*collecty_log_callback)(void* data, int priority, const char* file,
+typedef void (*td_log_callback)(void* data, int priority, const char* file,
int line, const char* fn, const char* format, va_list args);
#include "ctx.h"
-void collecty_log_stderr(void* data, int priority, const char* file,
+void td_log_stderr(void* data, int priority, const char* file,
int line, const char* fn, const char* format, va_list args)
__attribute__((format(printf, 6, 0)));
-void collecty_log_syslog(void* data, int priority, const char* file,
+void td_log_syslog(void* data, int priority, const char* file,
int line, const char* fn, const char* format, va_list args)
__attribute__((format(printf, 6, 0)));
-#define collecty_ctx_log_condition(ctx, level, arg...) \
+#define td_ctx_log_condition(ctx, level, arg...) \
do { \
- if (collecty_ctx_get_log_level(ctx) >= level) \
- collecty_ctx_log(ctx, level, __FILE__, __LINE__, __FUNCTION__, ## arg); \
+ if (td_ctx_get_log_level(ctx) >= level) \
+ td_ctx_log(ctx, level, __FILE__, __LINE__, __FUNCTION__, ## arg); \
} while (0)
-#define INFO(ctx, arg...) collecty_ctx_log_condition(ctx, LOG_INFO, ## arg)
-#define WARN(ctx, arg...) collecty_ctx_log_condition(ctx, LOG_WARNING, ## arg)
-#define ERROR(ctx, arg...) collecty_ctx_log_condition(ctx, LOG_ERR, ## arg)
-#define DEBUG(ctx, arg...) collecty_ctx_log_condition(ctx, LOG_DEBUG, ## arg)
+#define INFO(ctx, arg...) td_ctx_log_condition(ctx, LOG_INFO, ## arg)
+#define WARN(ctx, arg...) td_ctx_log_condition(ctx, LOG_WARNING, ## arg)
+#define ERROR(ctx, arg...) td_ctx_log_condition(ctx, LOG_ERR, ## arg)
+#define DEBUG(ctx, arg...) td_ctx_log_condition(ctx, LOG_DEBUG, ## arg)
-#endif /* COLLECTY_LOGGING_H */
+#endif /* TELEMETRY_LOGGING_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
const char* argp_program_version = PACKAGE_VERSION;
-static const char* doc = "The collecty Daemon";
+static const char* doc = "The IPFire Telemetry Daemon";
enum {
OPT_DEBUG = 1,
};
static error_t parse(int key, char* arg, struct argp_state* state) {
- collecty_ctx* ctx = state->input;
+ td_ctx* ctx = state->input;
switch (key) {
case OPT_DEBUG:
// Log to stdout
- collecty_ctx_set_log_callback(ctx, collecty_log_stderr, NULL);
+ td_ctx_set_log_callback(ctx, td_log_stderr, NULL);
// Increase the log level
- collecty_ctx_set_log_level(ctx, LOG_DEBUG);
+ td_ctx_set_log_level(ctx, LOG_DEBUG);
break;
default:
}
int main(int argc, char* argv[]) {
- collecty_daemon* daemon = NULL;
- collecty_ctx* ctx = NULL;
+ td_daemon* daemon = NULL;
+ td_ctx* ctx = NULL;
struct argp parser = {
.options = options,
.parser = parse,
int r;
// Allocate a new context
- r = collecty_ctx_create(&ctx);
+ r = td_ctx_create(&ctx);
if (r < 0)
goto ERROR;
goto ERROR;
// Create a daemon
- r = collecty_daemon_create(&daemon, ctx);
+ r = td_daemon_create(&daemon, ctx);
if (r < 0) {
ERROR(ctx, "Failed to initialize the daemon: %s\n", strerror(-r));
goto ERROR;
}
// Run the daemon
- r = collecty_daemon_run(daemon);
+ r = td_daemon_run(daemon);
ERROR:
if (daemon) {
// Log an error if the daemon was not freed properly
- if (collecty_daemon_unref(daemon))
+ if (td_daemon_unref(daemon))
ERROR(ctx, "Failed to free the daemon\n");
}
if (ctx) {
- if (collecty_ctx_unref(ctx))
+ if (td_ctx_unref(ctx))
ERROR(ctx, "Failed to free the context\n");
}
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "parse.h"
#include "string.h"
-static void collecty_skip_whitespace(char** s) {
+static void td_skip_whitespace(char** s) {
char* p = *s;
// Consume any whitespace
*s = p;
}
-int __collecty_parse_token(char** line, char* token, size_t length) {
+int __td_parse_token(char** line, char* token, size_t length) {
char* p = *line;
int r;
// Skip any leading whitespace
- collecty_skip_whitespace(&p);
+ td_skip_whitespace(&p);
// End of line
if (!*p)
- return __collecty_string_set(token, length, "");
+ return __td_string_set(token, length, "");
// Pointer that points to the end of the token
char* e = p;
e++;
// Copy the token
- r = __collecty_string_setn(token, length, p, e - p);
+ r = __td_string_setn(token, length, p, e - p);
if (r < 0)
return r;
return 0;
}
-int collecty_parse_uint64(char** line, uint64_t* value) {
+int td_parse_uint64(char** line, uint64_t* value) {
char* p = *line;
char* e = NULL;
// Skip any leading whitespace
- collecty_skip_whitespace(&p);
+ td_skip_whitespace(&p);
// Parse the value
*value = strtoul(p, &e, 10);
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_PARSE_H
-#define COLLECTY_PARSE_H
+#ifndef TELEMETRY_PARSE_H
+#define TELEMETRY_PARSE_H
#include <stddef.h>
#include <stdint.h>
-#define collecty_parse_token(line, token) \
- __collecty_parse_token(line, token, sizeof(token))
+#define td_parse_token(line, token) \
+ __td_parse_token(line, token, sizeof(token))
-int __collecty_parse_token(char** line, char* token, size_t length);
+int __td_parse_token(char** line, char* token, size_t length);
-int collecty_parse_uint64(char** line, uint64_t* value);
+int td_parse_uint64(char** line, uint64_t* value);
-#endif /* COLLECTY_PARSE_H */
+#endif /* TELEMETRY_PARSE_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "proc.h"
#include "string.h"
-int collecty_proc_read_meminfo(collecty_ctx* ctx, collecty_proc_meminfo* meminfo) {
- collecty_file_parser parser[] = {
+int td_proc_read_meminfo(td_ctx* ctx, td_proc_meminfo* meminfo) {
+ td_file_parser parser[] = {
PARSE1("MemTotal: %lu kB", &meminfo->mem_total),
PARSE1("MemFree: %lu kB", &meminfo->mem_free),
PARSE1("MemAvailable: %lu kB", &meminfo->mem_available),
int r;
// Parse /proc/meminfo
- r = collecty_parse(ctx, "/proc/meminfo", parser);
+ r = td_parse(ctx, "/proc/meminfo", parser);
if (r < 0)
return r;
return 0;
}
-static int collecty_proc_read_stat_line(collecty_ctx* ctx,
+static int td_proc_read_stat_line(td_ctx* ctx,
const char* tag, char* line, unsigned long* fields, size_t max_fields) {
char* p = NULL;
char* e = NULL;
t = strtok_r(line, " ", &p);
// If the first token does not match the tag, we skip the line
- if (!collecty_string_equals(tag, t))
+ if (!td_string_equals(tag, t))
return 0;
// Read all tokens
return field;
}
-int collecty_proc_read_stat(collecty_ctx* ctx,
+int td_proc_read_stat(td_ctx* ctx,
const char* tag, unsigned long* fields, size_t max_fields) {
char* line = NULL;
size_t length = 0;
break;
// Process the line
- r = collecty_proc_read_stat_line(ctx, tag, line, fields, max_fields);
+ r = td_proc_read_stat_line(ctx, tag, line, fields, max_fields);
if (r)
break;
}
return r;
}
-int collecty_proc_read_pressure(collecty_ctx* ctx,
- const char* what, collecty_pressure_stats* stats) {
+int td_proc_read_pressure(td_ctx* ctx,
+ const char* what, td_pressure_stats* stats) {
char path[PATH_MAX];
int r;
// Make the path
- r = collecty_string_format(path, "/proc/pressure/%s", what);
+ r = td_string_format(path, "/proc/pressure/%s", what);
if (r < 0)
return -errno;
- collecty_file_parser parser[] = {
+ td_file_parser parser[] = {
PARSE4("some avg10=%lf avg60=%lf avg300=%lf total=%lu\n",
&stats->some.avg10, &stats->some.avg60, &stats->some.avg300, &stats->some.total),
PARSE4("full avg10=%lf avg60=%lf avg300=%lf total=%lu\n",
};
// Run the parser
- return collecty_parse(ctx, path, parser);
+ return td_parse(ctx, path, parser);
}
-typedef struct collecty_proc_softirq_state {
+typedef struct td_proc_softirq_state {
// Callback
- collecty_proc_softirq_callback callback;
+ td_proc_softirq_callback callback;
void* data;
// Line Number
unsigned long lineno;
-} collecty_proc_softirq_state;
+} td_proc_softirq_state;
-static int collecty_proc_softirq_line(collecty_ctx* ctx, collecty_file* file,
+static int td_proc_softirq_line(td_ctx* ctx, td_file* file,
unsigned long lineno, char* line, size_t length, void* data) {
- collecty_proc_softirq_state* state = data;
+ td_proc_softirq_state* state = data;
uint64_t n = 0;
uint64_t v = 0;
char key[16];
return 0;
// Parse the key
- r = collecty_parse_token(&line, key);
+ r = td_parse_token(&line, key);
if (r < 0)
return r;
// Remove the trailing :
- collecty_string_rstrip2(key, ':');
+ td_string_rstrip2(key, ':');
// Add up all values
while (*line) {
- r = collecty_parse_uint64(&line, &v);
+ r = td_parse_uint64(&line, &v);
if (r < 0)
return r;
return state->callback(ctx, key, n, state->data);
}
-int collecty_proc_read_softirq(collecty_ctx* ctx,
- collecty_proc_softirq_callback callback, void* data) {
- collecty_file* file = NULL;
+int td_proc_read_softirq(td_ctx* ctx,
+ td_proc_softirq_callback callback, void* data) {
+ td_file* file = NULL;
int r;
- collecty_proc_softirq_state state = {
+ td_proc_softirq_state state = {
.callback = callback,
.data = data,
.lineno = 0,
};
// Open /proc/softirqs
- r = collecty_file_open_path(&file, ctx, "/proc/softirqs");
+ r = td_file_open_path(&file, ctx, "/proc/softirqs");
if (r < 0)
goto ERROR;
// Walk through all lines
- r = collecty_file_walk(file, collecty_proc_softirq_line, &state);
+ r = td_file_walk(file, td_proc_softirq_line, &state);
ERROR:
if (file)
- collecty_file_unref(file);
+ td_file_unref(file);
return r;
}
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_PROC_H
-#define COLLECTY_PROC_H
+#ifndef TELEMETRY_PROC_H
+#define TELEMETRY_PROC_H
#include <stddef.h>
#include <stdint.h>
#include "ctx.h"
-typedef struct collecty_proc_meminfo {
+typedef struct td_proc_meminfo {
// Memory
uint64_t mem_total;
uint64_t mem_free;
// Swap
uint64_t swap_total;
uint64_t swap_free;
-} collecty_proc_meminfo;
+} td_proc_meminfo;
-int collecty_proc_read_meminfo(collecty_ctx* ctx, collecty_proc_meminfo* meminfo);
+int td_proc_read_meminfo(td_ctx* ctx, td_proc_meminfo* meminfo);
-int collecty_proc_read_stat(collecty_ctx* ctx,
+int td_proc_read_stat(td_ctx* ctx,
const char* tag, unsigned long* fields, size_t max_fields);
-typedef struct collecty_pressure_stats {
- struct collecty_pressure_stats_values {
+typedef struct td_pressure_stats {
+ struct td_pressure_stats_values {
double avg10;
double avg60;
double avg300;
unsigned long total;
} some;
- struct collecty_pressure_stats_values full;
-} collecty_pressure_stats;
+ struct td_pressure_stats_values full;
+} td_pressure_stats;
-int collecty_proc_read_pressure(collecty_ctx* ctx,
- const char* what, collecty_pressure_stats* stats);
+int td_proc_read_pressure(td_ctx* ctx,
+ const char* what, td_pressure_stats* stats);
// Soft IRQ
-typedef int (*collecty_proc_softirq_callback)
- (collecty_ctx* ctx, const char* key, uint64_t value, void* data);
+typedef int (*td_proc_softirq_callback)
+ (td_ctx* ctx, const char* key, uint64_t value, void* data);
-int collecty_proc_read_softirq(collecty_ctx* ctx,
- collecty_proc_softirq_callback callback, void* data);
+int td_proc_read_softirq(td_ctx* ctx,
+ td_proc_softirq_callback callback, void* data);
-#endif /* COLLECTY_PROC_H */
+#endif /* TELEMETRY_PROC_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "proto.h"
#include "string.h"
-typedef struct collecty_proto_object {
- STAILQ_ENTRY(collecty_proto_object) nodes;
+typedef struct td_proto_object {
+ STAILQ_ENTRY(td_proto_object) nodes;
// Protocol
char proto[8];
// Value
uint64_t value;
-} collecty_proto_object;
+} td_proto_object;
-struct collecty_proto {
- collecty_ctx* ctx;
+struct td_proto {
+ td_ctx* ctx;
int nrefs;
// Objects
- STAILQ_HEAD(objects, collecty_proto_object) objects;
+ STAILQ_HEAD(objects, td_proto_object) objects;
};
-static void collecty_proto_free(collecty_proto* self) {
- struct collecty_proto_object* o = NULL;
+static void td_proto_free(td_proto* self) {
+ struct td_proto_object* o = NULL;
// Cleanup the objects
for (;;) {
}
if (self->ctx)
- collecty_ctx_unref(self->ctx);
+ td_ctx_unref(self->ctx);
free(self);
}
-int collecty_proto_create(collecty_proto** proto, collecty_ctx* ctx) {
- collecty_proto* self = NULL;
+int td_proto_create(td_proto** proto, td_ctx* ctx) {
+ td_proto* self = NULL;
// Allocate some memory
self = calloc(1, sizeof(*self));
self->nrefs = 1;
// Store a reference to the context
- self->ctx = collecty_ctx_ref(ctx);
+ self->ctx = td_ctx_ref(ctx);
// Initialize the objects
STAILQ_INIT(&self->objects);
return 0;
}
-collecty_proto* collecty_proto_ref(collecty_proto* self) {
+td_proto* td_proto_ref(td_proto* self) {
++self->nrefs;
return self;
}
-collecty_proto* collecty_proto_unref(collecty_proto* self) {
+td_proto* td_proto_unref(td_proto* self) {
if (--self->nrefs > 0)
return self;
- collecty_proto_free(self);
+ td_proto_free(self);
return NULL;
}
-static int collecty_proto_set(collecty_proto* self,
+static int td_proto_set(td_proto* self,
const char* proto, const char* key, uint64_t value) {
- collecty_proto_object* o = NULL;
+ td_proto_object* o = NULL;
int r;
// Allocate a new object
return -errno;
// Store proto
- r = collecty_string_set(o->proto, proto);
+ r = td_string_set(o->proto, proto);
if (r < 0)
goto ERROR;
// Store key
- r = collecty_string_set(o->key, key);
+ r = td_string_set(o->key, key);
if (r < 0)
goto ERROR;
return r;
}
-static int collecty_proto_read_one(collecty_proto* self, char* keys, char* values) {
+static int td_proto_read_one(td_proto* self, char* keys, char* values) {
char* e = NULL;
char proto[8];
uint64_t n;
return -errno;
// Store the protocol
- r = collecty_string_set(proto, k);
+ r = td_string_set(proto, k);
if (r < 0)
return -errno;
}
// Store the value
- r = collecty_proto_set(self, proto, k, n);
+ r = td_proto_set(self, proto, k, n);
if (r < 0)
break;
}
return r;
}
-int collecty_proto_read(collecty_proto* self, const char* path) {
+int td_proto_read(td_proto* self, const char* path) {
char* line = NULL;
size_t length = 0;
FILE* f = NULL;
// Even line
case 0:
// Just store the keys
- r = collecty_string_set(keys, line);
+ r = td_string_set(keys, line);
if (r < 0)
goto ERROR;
break;
// Odd line
case 1:
- r = collecty_proto_read_one(self, keys, line);
+ r = td_proto_read_one(self, keys, line);
if (r < 0)
goto ERROR;
break;
return r;
}
-int collecty_proto_get(collecty_proto* self,
+int td_proto_get(td_proto* self,
const char* proto, const char* key, uint64_t* value) {
- collecty_proto_object* o = NULL;
+ td_proto_object* o = NULL;
// Walk through all objects
STAILQ_FOREACH(o, &self->objects, nodes) {
// Protocol must match
- if (!collecty_string_equals(o->proto, proto))
+ if (!td_string_equals(o->proto, proto))
continue;
// Key must match
- if (!collecty_string_equals(o->key, key))
+ if (!td_string_equals(o->key, key))
continue;
// Return the value
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_PROTO_H
-#define COLLECTY_PROTO_H
+#ifndef TELEMETRY_PROTO_H
+#define TELEMETRY_PROTO_H
#include <stdint.h>
-typedef struct collecty_proto collecty_proto;
+typedef struct td_proto td_proto;
#include "ctx.h"
-int collecty_proto_create(collecty_proto** proto, collecty_ctx* ctx);
+int td_proto_create(td_proto** proto, td_ctx* ctx);
-collecty_proto* collecty_proto_ref(collecty_proto* self);
-collecty_proto* collecty_proto_unref(collecty_proto* self);
+td_proto* td_proto_ref(td_proto* self);
+td_proto* td_proto_unref(td_proto* self);
-int collecty_proto_read(collecty_proto* self, const char* path);
+int td_proto_read(td_proto* self, const char* path);
-int collecty_proto_get(collecty_proto* self,
+int td_proto_get(td_proto* self,
const char* proto, const char* key, uint64_t* value);
-#endif /* COLLECTY_PROTO_H */
+#endif /* TELEMETRY_PROTO_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#define HEARTBEAT SEC_TO_USEC(300) // 5 minutes
-struct collecty_queue_object {
- STAILQ_ENTRY(collecty_queue_object) nodes;
+struct td_queue_object {
+ STAILQ_ENTRY(td_queue_object) nodes;
// Source
- collecty_source* source;
+ td_source* source;
// Object
char* object;
unsigned int num_samples;
};
-struct collecty_queue {
- collecty_ctx* ctx;
+struct td_queue {
+ td_ctx* ctx;
int nrefs;
// Event Loop
} events;
// Queue
- STAILQ_HEAD(queue, collecty_queue_object) queue;
+ STAILQ_HEAD(queue, td_queue_object) queue;
};
-static int collecty_queue_object_equals(
- collecty_queue* self, struct collecty_queue_object* o, const char* object) {
+static int td_queue_object_equals(
+ td_queue* self, struct td_queue_object* o, const char* object) {
// Objects match if they are both NULL
if (!o->object && !object)
return 1;
// If both have objects, we need to compare
if (o->object && object)
- return collecty_string_equals(o->object, object);
+ return td_string_equals(o->object, object);
// Otherwise we have no match
return 0;
}
-static int collecty_queue_heartbeat(sd_event_source* source, uint64_t usec, void* data) {
- collecty_queue* self = data;
+static int td_queue_heartbeat(sd_event_source* source, uint64_t usec, void* data) {
+ td_queue* self = data;
int r;
// Call again soon...
return r;
// Flush the queue
- return collecty_queue_flush(self);
+ return td_queue_flush(self);
}
-static int collecty_queue_exit(sd_event_source* source, void* data) {
- collecty_queue* self = data;
+static int td_queue_exit(sd_event_source* source, void* data) {
+ td_queue* self = data;
// Flush the queue
- return collecty_queue_flush(self);
+ return td_queue_flush(self);
}
-static void collecty_queue_free_object(struct collecty_queue_object* o) {
+static void td_queue_free_object(struct td_queue_object* o) {
if (o->samples) {
for (unsigned int i = 0; i < o->num_samples; i++)
free(o->samples[i]);
}
if (o->source)
- collecty_source_unref(o->source);
+ td_source_unref(o->source);
if (o->object)
free(o->object);
free(o);
}
-static void collecty_queue_free(collecty_queue* self) {
- struct collecty_queue_object* o = NULL;
+static void td_queue_free(td_queue* self) {
+ struct td_queue_object* o = NULL;
// Cleanup the queue
for (;;) {
STAILQ_REMOVE_HEAD(&self->queue, nodes);
// Free the object
- collecty_queue_free_object(o);
+ td_queue_free_object(o);
}
if (self->events.exit)
if (self->events.flush)
sd_event_source_unref(self->events.flush);
if (self->ctx)
- collecty_ctx_unref(self->ctx);
+ td_ctx_unref(self->ctx);
if (self->loop)
sd_event_unref(self->loop);
free(self);
}
-int collecty_queue_create(collecty_queue** queue,
- collecty_ctx* ctx, collecty_daemon* daemon) {
- collecty_queue* self = NULL;
+int td_queue_create(td_queue** queue,
+ td_ctx* ctx, td_daemon* daemon) {
+ td_queue* self = NULL;
int r;
// Allocate some memory
self->nrefs = 1;
// Store a reference to the context
- self->ctx = collecty_ctx_ref(ctx);
+ self->ctx = td_ctx_ref(ctx);
// Fetch a reference to the event loop
- self->loop = collecty_daemon_loop(daemon);
+ self->loop = td_daemon_loop(daemon);
// Initialize the queue
STAILQ_INIT(&self->queue);
// Create a timer which regularly flushes the queue
r = sd_event_add_time_relative(self->loop, &self->events.flush,
- CLOCK_MONOTONIC, HEARTBEAT, 0, collecty_queue_heartbeat, self);
+ CLOCK_MONOTONIC, HEARTBEAT, 0, td_queue_heartbeat, self);
if (r < 0) {
ERROR(self->ctx, "Failed to set up the heartbeat timer: %s\n", strerror(-r));
goto ERROR;
}
// Create an event that is called when the loop exits
- r = sd_event_add_exit(self->loop, &self->events.exit, collecty_queue_exit, self);
+ r = sd_event_add_exit(self->loop, &self->events.exit, td_queue_exit, self);
if (r < 0) {
ERROR(self->ctx, "Failed to setup exit handler: %s\n", strerror(-r));
goto ERROR;
ERROR:
if (self)
- collecty_queue_unref(self);
+ td_queue_unref(self);
return r;
}
-collecty_queue* collecty_queue_ref(collecty_queue* self) {
+td_queue* td_queue_ref(td_queue* self) {
++self->nrefs;
return self;
}
-collecty_queue* collecty_queue_unref(collecty_queue* self) {
+td_queue* td_queue_unref(td_queue* self) {
if (--self->nrefs > 0)
return self;
- collecty_queue_free(self);
+ td_queue_free(self);
return NULL;
}
-static struct collecty_queue_object* collecty_queue_find_object(
- collecty_queue* self, collecty_source* source, const char* object) {
- struct collecty_queue_object* o = NULL;
+static struct td_queue_object* td_queue_find_object(
+ td_queue* self, td_source* source, const char* object) {
+ struct td_queue_object* o = NULL;
STAILQ_FOREACH(o, &self->queue, nodes) {
// The source must match
continue;
// Check if the object matches
- if (collecty_queue_object_equals(self, o, object))
+ if (td_queue_object_equals(self, o, object))
return o;
}
return NULL;
}
-static int collecty_queue_object_append_sample(collecty_queue* self, collecty_source* source,
- const char* object, struct collecty_queue_object* o, const char* sample) {
+static int td_queue_object_append_sample(td_queue* self, td_source* source,
+ const char* object, struct td_queue_object* o, const char* sample) {
struct timeval t = {};
char** samples = NULL;
char* s = NULL;
return 0;
}
-static int collecty_queue_valid_object(collecty_queue* queue, const char* object) {
+static int td_queue_valid_object(td_queue* queue, const char* object) {
// Check for any invalid characters
for (const char* p = object; *p; p++) {
switch (*p) {
/*
Submits a new reading into the queue
*/
-int collecty_queue_submit(collecty_queue* self,
- collecty_source* source, const char* object, const char* sample) {
- struct collecty_queue_object* o = NULL;
+int td_queue_submit(td_queue* self,
+ td_source* source, const char* object, const char* sample) {
+ struct td_queue_object* o = NULL;
int r;
// Check inputs
// Check if the object is valid
if (object) {
- r = collecty_queue_valid_object(self, object);
+ r = td_queue_valid_object(self, object);
if (r < 0) {
ERROR(self->ctx, "%s has submitted an invalid object: %s\n",
- collecty_source_name(source), object);
+ td_source_name(source), object);
goto ERROR;
}
}
// Check if we can append the sample
- o = collecty_queue_find_object(self, source, object);
+ o = td_queue_find_object(self, source, object);
if (o)
- return collecty_queue_object_append_sample(self, source, object, o, sample);
+ return td_queue_object_append_sample(self, source, object, o, sample);
// Allocate some memory
o = calloc(1, sizeof(*o));
return -errno;
// Reference the source
- o->source = collecty_source_ref(source);
+ o->source = td_source_ref(source);
// Store the object
if (object) {
}
// Store the sample
- r = collecty_queue_object_append_sample(self, source, object, o, sample);
+ r = td_queue_object_append_sample(self, source, object, o, sample);
if (r < 0)
goto ERROR;
ERROR:
if (o)
- collecty_queue_free_object(o);
+ td_queue_free_object(o);
return r;
}
-static int collecty_queue_flush_object(collecty_queue* self, struct collecty_queue_object* o) {
+static int td_queue_flush_object(td_queue* self, struct td_queue_object* o) {
int r;
// Call the source to write its data
- r = collecty_source_commit(o->source, o->object, o->num_samples, (const char**)o->samples);
+ r = td_source_commit(o->source, o->object, o->num_samples, (const char**)o->samples);
if (r < 0) {
ERROR(self->ctx, "Failed to write samples for %s(%s): %s\n",
- collecty_source_name(o->source), (o->object) ? o->object : NULL, strerror(-r));
+ td_source_name(o->source), (o->object) ? o->object : NULL, strerror(-r));
}
// Remove the object from the queue
- STAILQ_REMOVE(&self->queue, o, collecty_queue_object, nodes);
+ STAILQ_REMOVE(&self->queue, o, td_queue_object, nodes);
// Free the object
- collecty_queue_free_object(o);
+ td_queue_free_object(o);
return 0;
}
-int collecty_queue_flush(collecty_queue* self) {
- struct collecty_queue_object* o = NULL;
+int td_queue_flush(td_queue* self) {
+ struct td_queue_object* o = NULL;
int r;
DEBUG(self->ctx, "Flushing the queue...\n");
break;
// Flush the object
- r = collecty_queue_flush_object(self, o);
+ r = td_queue_flush_object(self, o);
if (r < 0)
return r;
}
return 0;
}
-int collecty_queue_flush_source(collecty_queue* self,
- collecty_source* source, const char* object) {
- struct collecty_queue_object* o = NULL;
+int td_queue_flush_source(td_queue* self,
+ td_source* source, const char* object) {
+ struct td_queue_object* o = NULL;
STAILQ_FOREACH(o, &self->queue, nodes) {
// Continue if the source does not match
continue;
// Continue if the object does not match
- if (!collecty_queue_object_equals(self, o, object))
+ if (!td_queue_object_equals(self, o, object))
continue;
// Flush the object
- return collecty_queue_flush_object(self, o);
+ return td_queue_flush_object(self, o);
}
return 0;
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_QUEUE_H
-#define COLLECTY_QUEUE_H
+#ifndef TELEMETRY_QUEUE_H
+#define TELEMETRY_QUEUE_H
-typedef struct collecty_queue collecty_queue;
+typedef struct td_queue td_queue;
#include "ctx.h"
#include "daemon.h"
#include "source.h"
-int collecty_queue_create(collecty_queue** queue,
- collecty_ctx* ctx, collecty_daemon* daemon);
+int td_queue_create(td_queue** queue,
+ td_ctx* ctx, td_daemon* daemon);
-collecty_queue* collecty_queue_ref(collecty_queue* self);
-collecty_queue* collecty_queue_unref(collecty_queue* self);
+td_queue* td_queue_ref(td_queue* self);
+td_queue* td_queue_unref(td_queue* self);
-int collecty_queue_submit(collecty_queue* self,
- collecty_source* source, const char* object, const char* sample);
+int td_queue_submit(td_queue* self,
+ td_source* source, const char* object, const char* sample);
-int collecty_queue_flush(collecty_queue* self);
+int td_queue_flush(td_queue* self);
-int collecty_queue_flush_source(collecty_queue* self,
- collecty_source* source, const char* object);
+int td_queue_flush_source(td_queue* self,
+ td_source* source, const char* object);
-#endif /* COLLECTY_QUEUE_H */
+#endif /* TELEMETRY_QUEUE_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#define RUNTIME_THRESHOLD MSEC_TO_USEC(250) // 250 milliseconds
// Define some default RRAs
-static const collecty_rrd_rra default_rras[] = {
+static const td_rrd_rra default_rras[] = {
// Keep AVERAGE/MIN/MAX with a one minute resolution for two weeks
{ "AVERAGE", "1m", "14d", },
{ "MIN", "1m", "14d", },
{ NULL },
};
-struct collecty_source {
- collecty_ctx* ctx;
+struct td_source {
+ td_ctx* ctx;
int nrefs;
// Daemon
- collecty_daemon* daemon;
+ td_daemon* daemon;
// Implementation
- const collecty_source_impl* impl;
+ const td_source_impl* impl;
// Event Loop
sd_event* loop;
} events;
// State
- enum collecty_source_state {
+ enum td_source_state {
STATE_HEALTHY = 0,
STATE_FLAPPING,
STATE_ERROR,
};
// Return the number of recent bad results
-static int collecty_source_count_bad_results(collecty_source* self) {
+static int td_source_count_bad_results(td_source* self) {
int counter = 0;
// Starting with the most recent result, count all bad results until a good one is found
return counter;
}
-static int collecty_source_is_flapping(collecty_source* self) {
+static int td_source_is_flapping(td_source* self) {
int changes = 0;
int r;
return changes >= FLAPPING_THRESHOLD;
}
-static int collecty_source_error_detection(collecty_source* self, int result, uint64_t runtime) {
- enum collecty_source_state state;
+static int td_source_error_detection(td_source* self, int result, uint64_t runtime) {
+ enum td_source_state state;
int r;
// Move everything up in the array
// Complain if an iteration took too long
if (runtime >= RUNTIME_THRESHOLD) {
ERROR(self->ctx, "Heartbeat for %s stalled the event loop for %.2lfms\n",
- collecty_source_name(self), USEC_TO_MSEC((double)runtime));
+ td_source_name(self), USEC_TO_MSEC((double)runtime));
// Decrease the priority for this source so it won't stall any other sources
r = sd_event_source_set_priority(self->events.heartbeat, SD_EVENT_PRIORITY_IDLE);
} else {
// Log the runtime
DEBUG(self->ctx, "Heartbeat for %s took %.2lfms\n",
- collecty_source_name(self), USEC_TO_MSEC((double)runtime));
+ td_source_name(self), USEC_TO_MSEC((double)runtime));
// Decrease the priority for this source so it won't stall any other sources
r = sd_event_source_set_priority(self->events.heartbeat, SD_EVENT_PRIORITY_NORMAL);
if (result) {
for (unsigned int i = 0; i < self->results.num; i++) {
DEBUG(self->ctx, "%s: result[%u] = %s\n",
- collecty_source_name(self), i, strerror(-self->results.r[i]));
+ td_source_name(self), i, strerror(-self->results.r[i]));
}
// Print bad results
DEBUG(self->ctx, "%s: bad results: %d\n",
- collecty_source_name(self), collecty_source_count_bad_results(self));
+ td_source_name(self), td_source_count_bad_results(self));
}
// Count all bad results
- int bad_results = collecty_source_count_bad_results(self);
+ int bad_results = td_source_count_bad_results(self);
// Disable the source if it has failed
if (bad_results >= NUM_RESULTS)
state = STATE_ERROR;
// Check if we are flapping
- else if (collecty_source_is_flapping(self))
+ else if (td_source_is_flapping(self))
state = STATE_FLAPPING;
// Otherwise we must be healthy
// Log the state change
switch (state) {
case STATE_HEALTHY:
- DEBUG(self->ctx, "%s is now healthy\n", collecty_source_name(self));
+ DEBUG(self->ctx, "%s is now healthy\n", td_source_name(self));
break;
case STATE_FLAPPING:
- ERROR(self->ctx, "%s is now flapping\n", collecty_source_name(self));
+ ERROR(self->ctx, "%s is now flapping\n", td_source_name(self));
break;
case STATE_ERROR:
- ERROR(self->ctx, "%s is now in error state\n", collecty_source_name(self));
+ ERROR(self->ctx, "%s is now in error state\n", td_source_name(self));
break;
case STATE_DISABLED:
- ERROR(self->ctx, "%s has been disabled\n", collecty_source_name(self));
+ ERROR(self->ctx, "%s has been disabled\n", td_source_name(self));
break;
}
return 0;
}
-static uint64_t collecty_source_elapsed_time(void) {
+static uint64_t td_source_elapsed_time(void) {
struct timespec ts = {};
int r;
return SEC_TO_USEC(ts.tv_sec) + NSEC_TO_USEC(ts.tv_nsec);
}
-static int collecty_source_heartbeat(sd_event_source* source, uint64_t usec, void* data) {
- collecty_source* self = data;
+static int td_source_heartbeat(sd_event_source* source, uint64_t usec, void* data) {
+ td_source* self = data;
uint64_t next_heartbeat;
uint64_t t_delay;
uint64_t t_start;
int r;
// Store the start timestamp
- t_start = collecty_source_elapsed_time();
+ t_start = td_source_elapsed_time();
// Compute how late we have been called
t_delay = t_start - usec;
// Complain if we got called very late
if (t_delay >= DELAY_THRESHOLD) {
ERROR(self->ctx, "Heartbeat for %s was delayed by %.2lfms\n",
- collecty_source_name(self), USEC_TO_MSEC((double)t_delay));
+ td_source_name(self), USEC_TO_MSEC((double)t_delay));
}
// Call the heartbeat method
r = self->impl->heartbeat(self->ctx, self);
if (r < 0) {
ERROR(self->ctx, "heartbeat() failed for %s: %s\n",
- collecty_source_name(self), strerror(-r));
+ td_source_name(self), strerror(-r));
}
// Fetch the end timestamp
- t_end = collecty_source_elapsed_time();
+ t_end = td_source_elapsed_time();
// Run error detection
- r = collecty_source_error_detection(self, r, t_end - t_start);
+ r = td_source_error_detection(self, r, t_end - t_start);
if (r < 0)
return r;
return 0;
}
-static int collecty_source_register_heartbeat(collecty_source* self) {
+static int td_source_register_heartbeat(td_source* self) {
uint64_t heartbeat = 0;
int r;
// Call the heartbeat function immediately
r = sd_event_add_time_relative(self->loop, &self->events.heartbeat,
- CLOCK_MONOTONIC, heartbeat, 0, collecty_source_heartbeat, self);
+ CLOCK_MONOTONIC, heartbeat, 0, td_source_heartbeat, self);
if (r < 0) {
ERROR(self->ctx, "Failed to register the heartbeat timer: %s\n", strerror(-r));
return r;
return 0;
}
-static int collecty_source_init(collecty_source* self) {
+static int td_source_init(td_source* self) {
int r;
// Do nothing if there is no init function
r = self->impl->init(self->ctx);
if (r < 0) {
ERROR(self->ctx, "Failed to initialize %s: %s\n",
- collecty_source_name(self), strerror(-r));
+ td_source_name(self), strerror(-r));
}
return r;
}
-static void collecty_source_free(collecty_source* self) {
+static void td_source_free(td_source* self) {
if (self->impl->free)
self->impl->free(self->ctx);
if (self->events.heartbeat)
if (self->loop)
sd_event_unref(self->loop);
if (self->daemon)
- collecty_daemon_unref(self->daemon);
+ td_daemon_unref(self->daemon);
if (self->ctx)
- collecty_ctx_unref(self->ctx);
+ td_ctx_unref(self->ctx);
free(self);
}
-int collecty_source_create(collecty_source** source,
- collecty_ctx* ctx, collecty_daemon* daemon, const collecty_source_impl* impl) {
- collecty_source* self = NULL;
+int td_source_create(td_source** source,
+ td_ctx* ctx, td_daemon* daemon, const td_source_impl* impl) {
+ td_source* self = NULL;
int r;
// Allocate some memory
self->nrefs = 1;
// Store a reference to the context
- self->ctx = collecty_ctx_ref(ctx);
+ self->ctx = td_ctx_ref(ctx);
// Store a reference to the daemon
- self->daemon = collecty_daemon_ref(daemon);
+ self->daemon = td_daemon_ref(daemon);
// Fetch a reference to the event loop
- self->loop = collecty_daemon_loop(daemon);
+ self->loop = td_daemon_loop(daemon);
// Store the implementation
self->impl = impl;
// Register heartbeat
- r = collecty_source_register_heartbeat(self);
+ r = td_source_register_heartbeat(self);
if (r < 0)
goto ERROR;
// Initialize the source
- r = collecty_source_init(self);
+ r = td_source_init(self);
if (r < 0)
goto ERROR;
ERROR:
if (self)
- collecty_source_unref(self);
+ td_source_unref(self);
return r;
}
-collecty_source* collecty_source_ref(collecty_source* self) {
+td_source* td_source_ref(td_source* self) {
++self->nrefs;
return self;
}
-collecty_source* collecty_source_unref(collecty_source* self) {
+td_source* td_source_unref(td_source* self) {
if (--self->nrefs > 0)
return self;
- collecty_source_free(self);
+ td_source_free(self);
return NULL;
}
-const char* collecty_source_name(collecty_source* self) {
+const char* td_source_name(td_source* self) {
return self->impl->name;
}
-int collecty_source_create_command(collecty_source* self, collecty_command** command) {
- return collecty_command_create(command, self->ctx, self->daemon);
+int td_source_create_command(td_source* self, td_command** command) {
+ return td_command_create(command, self->ctx, self->daemon);
}
-#define collecty_source_path(source, object, path) \
- __collecty_source_path(source, object, path, sizeof(path))
+#define td_source_path(source, object, path) \
+ __td_source_path(source, object, path, sizeof(path))
-static int __collecty_source_path(collecty_source* self,
+static int __td_source_path(td_source* self,
const char* object, char* path, size_t length) {
// Fetch the source name
- const char* name = collecty_source_name(self);
+ const char* name = td_source_name(self);
if (object)
- return __collecty_string_format(path, length, "%s/%s-%s.rrd", DATABASE_PATH, name, object);
+ return __td_string_format(path, length, "%s/%s-%s.rrd", DATABASE_PATH, name, object);
- return __collecty_string_format(path, length, "%s/%s.rrd", DATABASE_PATH, name);
+ return __td_string_format(path, length, "%s/%s.rrd", DATABASE_PATH, name);
}
/*
Called when a source has some data to submit
*/
-int collecty_source_submit(collecty_source* self,
+int td_source_submit(td_source* self,
const char* object, const char* format, ...) {
char value[2048];
va_list args;
// Format the arguments
va_start(args, format);
- r = collecty_string_vformat(value, format, args);
+ r = td_string_vformat(value, format, args);
va_end(args);
// Handle errors
return r;
// Submit the data to the daemon
- return collecty_daemon_submit(self->daemon, self, object, value);
+ return td_daemon_submit(self->daemon, self, object, value);
}
-static int collecty_source_create_database(collecty_source* self, const char* path) {
- collecty_args* args = NULL;
+static int td_source_create_database(td_source* self, const char* path) {
+ td_args* args = NULL;
char min[24];
char max[24];
int r;
- DEBUG(self->ctx, "Creating database for %s at %s\n", collecty_source_name(self), path);
+ DEBUG(self->ctx, "Creating database for %s at %s\n", td_source_name(self), path);
// Allocate a new argument array
- r = collecty_args_create(&args, self->ctx);
+ r = td_args_create(&args, self->ctx);
if (r < 0)
goto ERROR;
// Add all data sources
- for (const collecty_rrd_ds* ds = self->impl->rrd_dss; ds->field; ds++) {
+ for (const td_rrd_ds* ds = self->impl->rrd_dss; ds->field; ds++) {
// Format the minimum value
- r = collecty_format_number(min, ds->min);
+ r = td_format_number(min, ds->min);
if (r < 0)
goto ERROR;
// Format the maximum value
- r = collecty_format_number(max, ds->max);
+ r = td_format_number(max, ds->max);
if (r < 0)
goto ERROR;
// Add the DS line
- r = collecty_args_push(args, "DS:%s:%s:%lu:%s:%s",
+ r = td_args_push(args, "DS:%s:%s:%lu:%s:%s",
ds->field, ds->type, USEC_TO_SEC(HEARTBEAT), min, max);
if (r < 0)
goto ERROR;
}
// Add all default round-robin archives
- for (const collecty_rrd_rra* rra = default_rras; rra->type; rra++) {
- r = collecty_args_push(args, "RRA:%s:%.2f:%s:%s", rra->type, XFF, rra->steps, rra->rows);
+ for (const td_rrd_rra* rra = default_rras; rra->type; rra++) {
+ r = td_args_push(args, "RRA:%s:%.2f:%s:%s", rra->type, XFF, rra->steps, rra->rows);
if (r < 0)
goto ERROR;
}
// Add all custom round-robin archives
- for (const collecty_rrd_rra* rra = self->impl->rrd_rras; rra->type; rra++) {
- r = collecty_args_push(args, "RRA:%s:%.2f:%s:%s", rra->type, XFF, rra->steps, rra->rows);
+ for (const td_rrd_rra* rra = self->impl->rrd_rras; rra->type; rra++) {
+ r = td_args_push(args, "RRA:%s:%.2f:%s:%s", rra->type, XFF, rra->steps, rra->rows);
if (r < 0)
goto ERROR;
}
// Dump all arguments
- r = collecty_args_dump(args);
+ r = td_args_dump(args);
if (r < 0)
goto ERROR;
// Create the RRD file
r = rrd_create_r(path, USEC_TO_SEC(HEARTBEAT / 2), 0,
- collecty_args_argc(args), collecty_args_argv(args));
+ td_args_argc(args), td_args_argv(args));
if (r < 0) {
ERROR(self->ctx, "Failed to create %s: %s\n", path, rrd_get_error());
rrd_clear_error();
ERROR:
if (args)
- collecty_args_unref(args);
+ td_args_unref(args);
return r;
}
/*
Called to write all collected samples to disk
*/
-int collecty_source_commit(collecty_source* self,
+int td_source_commit(td_source* self,
const char* object, unsigned int num_samples, const char** samples) {
struct stat st = {};
char path[PATH_MAX];
int r;
// Make the path
- r = collecty_source_path(self, object, path);
+ r = td_source_path(self, object, path);
if (r < 0)
return r;
if (r < 0) {
switch (errno) {
case ENOENT:
- r = collecty_source_create_database(self, path);
+ r = td_source_create_database(self, path);
if (r < 0)
return r;
break;
return 0;
}
-static int collecty_source_render_add_DEF(collecty_source* self,
- collecty_args* args, const char* path, const collecty_rrd_ds* ds, const char* object) {
+static int td_source_render_add_DEF(td_source* self,
+ td_args* args, const char* path, const td_rrd_ds* ds, const char* object) {
char field[NAME_MAX];
int r;
// Append the object to the field name so that we can load multiple RRD of the same source
if (object) {
- r = collecty_string_format(field, "%s_%s", ds->field, object);
+ r = td_string_format(field, "%s_%s", ds->field, object);
if (r < 0)
return r;
} else {
- r = collecty_string_set(field, ds->field);
+ r = td_string_set(field, ds->field);
if (r < 0)
return r;
}
// Add the classic DEF line
- r = collecty_args_push(args, "DEF:%s=%s:%s:AVERAGE", field, path, ds->field);
+ r = td_args_push(args, "DEF:%s=%s:%s:AVERAGE", field, path, ds->field);
if (r < 0)
return r;
// Add VDEF for LAST
- r = collecty_args_push(args, "VDEF:%s_cur=%s,LAST", field, field);
+ r = td_args_push(args, "VDEF:%s_cur=%s,LAST", field, field);
if (r < 0)
return r;
// Add VDEF for AVERAGE
- r = collecty_args_push(args, "VDEF:%s_avg=%s,AVERAGE", field, field);
+ r = td_args_push(args, "VDEF:%s_avg=%s,AVERAGE", field, field);
if (r < 0)
return r;
// Add VDEF for MAXIMUM
- r = collecty_args_push(args, "VDEF:%s_max=%s,MAXIMUM", field, field);
+ r = td_args_push(args, "VDEF:%s_max=%s,MAXIMUM", field, field);
if (r < 0)
return r;
// Add VDEF for MINIMUM
- r = collecty_args_push(args, "VDEF:%s_min=%s,MINIMUM", field, field);
+ r = td_args_push(args, "VDEF:%s_min=%s,MINIMUM", field, field);
if (r < 0)
return r;
return 0;
}
-int collecty_source_render(collecty_source* self, collecty_args* args, const char* object) {
+int td_source_render(td_source* self, td_args* args, const char* object) {
char path[PATH_MAX];
int r;
// Determine the path to the RRD file
- r = collecty_source_path(self, object, path);
+ r = td_source_path(self, object, path);
if (r < 0)
return r;
// Add all data sources
- for (const collecty_rrd_ds* ds = self->impl->rrd_dss; ds->field; ds++) {
- r = collecty_source_render_add_DEF(self, args, path, ds, object);
+ for (const td_rrd_ds* ds = self->impl->rrd_dss; ds->field; ds++) {
+ r = td_source_render_add_DEF(self, args, path, ds, object);
if (r < 0)
return r;
}
// Commit any buffered data right now
- return collecty_daemon_flush_source(self->daemon, self, object);
+ return td_daemon_flush_source(self->daemon, self, object);
}
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_H
-#define COLLECTY_SOURCE_H
+#ifndef TELEMETRY_SOURCE_H
+#define TELEMETRY_SOURCE_H
-typedef struct collecty_source collecty_source;
+typedef struct td_source td_source;
#include "args.h"
#include "command.h"
#define MAX_DS 64
#define MAX_RRA 8
-typedef struct collecty_rrd_ds {
+typedef struct td_rrd_ds {
// Field
const char* field;
// Minimum/Maxmimum Value
int min;
int max;
-} collecty_rrd_ds;
+} td_rrd_ds;
-typedef struct collecty_rrd_rra {
+typedef struct td_rrd_rra {
// Type
const char* type;
// Rows
const char* rows;
-} collecty_rrd_rra;
+} td_rrd_rra;
-typedef struct collecty_source_impl {
+typedef struct td_source_impl {
const char* name;
// RRD Schema
- collecty_rrd_ds rrd_dss[MAX_DS];
- collecty_rrd_rra rrd_rras[MAX_RRA];
+ td_rrd_ds rrd_dss[MAX_DS];
+ td_rrd_rra rrd_rras[MAX_RRA];
// Init
- int (*init)(collecty_ctx* ctx);
+ int (*init)(td_ctx* ctx);
// Free
- int (*free)(collecty_ctx* ctx);
+ int (*free)(td_ctx* ctx);
// Heartbeat
- int (*heartbeat)(collecty_ctx* ctx, collecty_source* source);
-} collecty_source_impl;
+ int (*heartbeat)(td_ctx* ctx, td_source* source);
+} td_source_impl;
-int collecty_source_create(collecty_source** source,
- collecty_ctx* ctx, collecty_daemon* daemon, const collecty_source_impl* impl);
+int td_source_create(td_source** source,
+ td_ctx* ctx, td_daemon* daemon, const td_source_impl* impl);
-collecty_source* collecty_source_ref(collecty_source* self);
-collecty_source* collecty_source_unref(collecty_source* self);
+td_source* td_source_ref(td_source* self);
+td_source* td_source_unref(td_source* self);
-const char* collecty_source_name(collecty_source* self);
+const char* td_source_name(td_source* self);
-int collecty_source_create_command(collecty_source* self, collecty_command** command);
+int td_source_create_command(td_source* self, td_command** command);
-int collecty_source_submit(collecty_source* self, const char* object,
+int td_source_submit(td_source* self, const char* object,
const char* format, ...) __attribute__((format(printf, 3, 4)));
-int collecty_source_commit(collecty_source* self,
+int td_source_commit(td_source* self,
const char* object, unsigned int num_samples, const char** samples);
-int collecty_source_render(collecty_source* self,
- collecty_args* args, const char* object);
+int td_source_render(td_source* self,
+ td_args* args, const char* object);
-#endif /* COLLECTY_SOURCE_H */
+#endif /* TELEMETRY_SOURCE_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#endif /* ENABLE_TESTS */
// Register all sources
-static const collecty_source_impl* source_impls[] = {
+static const td_source_impl* source_impls[] = {
&conntrack_source,
&contextswitches_source,
&df_source,
NULL,
};
-struct collecty_sources {
- collecty_ctx* ctx;
+struct td_sources {
+ td_ctx* ctx;
int nrefs;
// Daemon
- collecty_daemon* daemon;
+ td_daemon* daemon;
// Sources
- collecty_source** sources;
+ td_source** sources;
unsigned int num_sources;
};
-static int collecty_sources_init(collecty_sources* self) {
- collecty_source** sources = NULL;
- collecty_source* source = NULL;
+static int td_sources_init(td_sources* self) {
+ td_source** sources = NULL;
+ td_source* source = NULL;
int r;
// Initialize all sources
- for (const collecty_source_impl** impl = source_impls; *impl; impl++) {
- r = collecty_source_create(&source, self->ctx, self->daemon, *impl);
+ for (const td_source_impl** impl = source_impls; *impl; impl++) {
+ r = td_source_create(&source, self->ctx, self->daemon, *impl);
if (r < 0)
return r;
}
// Store a reference to the source in the array
- sources[self->num_sources++] = collecty_source_ref(source);
+ sources[self->num_sources++] = td_source_ref(source);
// Replace the array
self->sources = sources;
// Unref the source
- collecty_source_unref(source);
+ td_source_unref(source);
source = NULL;
}
ERROR:
if (source)
- collecty_source_unref(source);
+ td_source_unref(source);
return r;
}
-static void collecty_sources_free(collecty_sources* self) {
+static void td_sources_free(td_sources* self) {
if (self->sources) {
for (unsigned int i = 0; i < self->num_sources; i++)
- collecty_source_unref(self->sources[i]);
+ td_source_unref(self->sources[i]);
free(self->sources);
}
if (self->daemon)
- collecty_daemon_unref(self->daemon);
+ td_daemon_unref(self->daemon);
if (self->ctx)
- collecty_ctx_unref(self->ctx);
+ td_ctx_unref(self->ctx);
free(self);
}
-int collecty_sources_create(collecty_sources** sources,
- collecty_ctx* ctx, collecty_daemon* daemon) {
- collecty_sources* self = NULL;
+int td_sources_create(td_sources** sources,
+ td_ctx* ctx, td_daemon* daemon) {
+ td_sources* self = NULL;
int r;
// Allocate some memory
self->nrefs = 1;
// Store a reference to the context
- self->ctx = collecty_ctx_ref(ctx);
+ self->ctx = td_ctx_ref(ctx);
// Store a reference to the daemon
- self->daemon = collecty_daemon_ref(daemon);
+ self->daemon = td_daemon_ref(daemon);
// Setup all sources
- r = collecty_sources_init(self);
+ r = td_sources_init(self);
if (r < 0)
goto ERROR;
ERROR:
if (self)
- collecty_sources_unref(self);
+ td_sources_unref(self);
return r;
}
-collecty_sources* collecty_sources_ref(collecty_sources* self) {
+td_sources* td_sources_ref(td_sources* self) {
++self->nrefs;
return self;
}
-collecty_sources* collecty_sources_unref(collecty_sources* self) {
+td_sources* td_sources_unref(td_sources* self) {
if (--self->nrefs > 0)
return self;
- collecty_sources_free(self);
+ td_sources_free(self);
return NULL;
}
-collecty_source* collecty_sources_get_by_name(collecty_sources* self, const char* name) {
+td_source* td_sources_get_by_name(td_sources* self, const char* name) {
const char* n = NULL;
// Iterate over all sources to find a match
for (unsigned int i = 0; i < self->num_sources; i++) {
// Fetch the name
- n = collecty_source_name(self->sources[i]);
+ n = td_source_name(self->sources[i]);
if (!n)
continue;
// Return the object if the name matches
- if (collecty_string_equals(name, n))
- return collecty_source_ref(self->sources[i]);
+ if (td_string_equals(name, n))
+ return td_source_ref(self->sources[i]);
}
return NULL;
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCES_H
-#define COLLECTY_SOURCES_H
+#ifndef TELEMETRY_SOURCES_H
+#define TELEMETRY_SOURCES_H
-typedef struct collecty_sources collecty_sources;
+typedef struct td_sources td_sources;
#include "ctx.h"
#include "daemon.h"
#include "source.h"
-int collecty_sources_create(collecty_sources** sources,
- collecty_ctx* ctx, collecty_daemon* daemon);
+int td_sources_create(td_sources** sources,
+ td_ctx* ctx, td_daemon* daemon);
-collecty_sources* collecty_sources_ref(collecty_sources* self);
-collecty_sources* collecty_sources_unref(collecty_sources* self);
+td_sources* td_sources_ref(td_sources* self);
+td_sources* td_sources_unref(td_sources* self);
-collecty_source* collecty_sources_get_by_name(collecty_sources* self, const char* name);
+td_source* td_sources_get_by_name(td_sources* self, const char* name);
-#endif /* COLLECTY_SOURCES_H */
+#endif /* TELEMETRY_SOURCES_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "../source.h"
#include "conntrack.h"
-static int conntrack_heartbeat(collecty_ctx* ctx, collecty_source* source) {
+static int conntrack_heartbeat(td_ctx* ctx, td_source* source) {
uint64_t count = 0;
uint64_t max = 0;
int r;
// Read the total number of connections
- r = collecty_read_uint64(ctx, "/proc/sys/net/netfilter/nf_conntrack_count", &count);
+ r = td_read_uint64(ctx, "/proc/sys/net/netfilter/nf_conntrack_count", &count);
if (r < 0) {
ERROR(ctx, "Failed to read %s: %s\n",
"/proc/sys/net/netfilter/nf_conntrack_count", strerror(-r));
}
// Read the maximum number of connections
- r = collecty_read_uint64(ctx, "/proc/sys/net/netfilter/nf_conntrack_max", &max);
+ r = td_read_uint64(ctx, "/proc/sys/net/netfilter/nf_conntrack_max", &max);
if (r < 0) {
ERROR(ctx, "Failed to read %s: %s\n",
"/proc/sys/net/netfilter/nf_conntrack_max", strerror(-r));
}
// Submit the values
- return collecty_source_submit(source, NULL, "%" PRIu64 ":%" PRIu64, count, max);
+ return td_source_submit(source, NULL, "%" PRIu64 ":%" PRIu64, count, max);
}
-const collecty_source_impl conntrack_source = {
+const td_source_impl conntrack_source = {
.name = "conntrack",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_CONNTRACK_H
-#define COLLECTY_SOURCE_CONNTRACK_H
+#ifndef TELEMETRY_SOURCE_CONNTRACK_H
+#define TELEMETRY_SOURCE_CONNTRACK_H
#include "../source.h"
-extern const collecty_source_impl conntrack_source;
+extern const td_source_impl conntrack_source;
-#endif /* COLLECTY_SOURCE_CONNTRACK_H */
+#endif /* TELEMETRY_SOURCE_CONNTRACK_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
static unsigned int num_cpus = 0;
static int* perf_eventfds = NULL;
-static int contextswitches_init(collecty_ctx* ctx) {
+static int contextswitches_init(td_ctx* ctx) {
struct perf_event_attr event = {
.type = PERF_TYPE_SOFTWARE,
.config = PERF_COUNT_SW_CONTEXT_SWITCHES,
return 0;
}
-static int contextswitches_free(collecty_ctx* ctx) {
+static int contextswitches_free(td_ctx* ctx) {
// Close any open file descriptors
if (perf_eventfds) {
for (unsigned int i = 0; i < num_cpus; i++) {
return 0;
}
-static int contextswitches_heartbeat(collecty_ctx* ctx, collecty_source* source) {
+static int contextswitches_heartbeat(td_ctx* ctx, td_source* source) {
long long total = 0;
uint64_t count = 0;
int fd = -EBADF;
}
// Submit the values
- return collecty_source_submit(source, NULL, "%lld", total);
+ return td_source_submit(source, NULL, "%lld", total);
}
-const collecty_source_impl contextswitches_source = {
+const td_source_impl contextswitches_source = {
.name = "contextswitches",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_CONTEXTSWITCHES_H
-#define COLLECTY_SOURCE_CONTEXTSWITCHES_H
+#ifndef TELEMETRY_SOURCE_CONTEXTSWITCHES_H
+#define TELEMETRY_SOURCE_CONTEXTSWITCHES_H
#include "../source.h"
-extern const collecty_source_impl contextswitches_source;
+extern const td_source_impl contextswitches_source;
-#endif /* COLLECTY_SOURCE_CONTEXTSWITCHES_H */
+#endif /* TELEMETRY_SOURCE_CONTEXTSWITCHES_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "../source.h"
#include "df.h"
-static int df_heartbeat(collecty_ctx* ctx, collecty_source* source) {
+static int df_heartbeat(td_ctx* ctx, td_source* source) {
struct mntent* mountpoint = NULL;
struct statvfs stat = {};
FILE* f = NULL;
size_t block_size = (stat.f_frsize) ? stat.f_frsize : stat.f_bsize;
// Submit stats
- r = collecty_source_submit(source, mountpoint->mnt_dir, "%lu:%lu:%lu:%lu",
+ r = td_source_submit(source, mountpoint->mnt_dir, "%lu:%lu:%lu:%lu",
// used
(stat.f_blocks - stat.f_bfree) * block_size,
// free
return r;
}
-const collecty_source_impl df_source = {
+const td_source_impl df_source = {
.name = "df",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_DF_H
-#define COLLECTY_SOURCE_DF_H
+#ifndef TELEMETRY_SOURCE_DF_H
+#define TELEMETRY_SOURCE_DF_H
#include "../source.h"
-extern const collecty_source_impl df_source;
+extern const td_source_impl df_source;
-#endif /* COLLECTY_SOURCE_DF_H */
+#endif /* TELEMETRY_SOURCE_DF_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "../source.h"
#include "ipfrag4.h"
-static int ipfrag4_heartbeat(collecty_ctx* ctx, collecty_source* source) {
- collecty_proto* proto = NULL;
+static int ipfrag4_heartbeat(td_ctx* ctx, td_source* source) {
+ td_proto* proto = NULL;
uint64_t frags_oks;
uint64_t frags_fails;
uint64_t frags_creates;
int r;
// Create the protocol parser
- r = collecty_proto_create(&proto, ctx);
+ r = td_proto_create(&proto, ctx);
if (r < 0)
goto ERROR;
// Read /proc/net/snmp
- r = collecty_proto_read(proto, "/proc/net/snmp");
+ r = td_proto_read(proto, "/proc/net/snmp");
if (r < 0)
goto ERROR;
// Read /proc/net/snmp
- r = collecty_proto_read(proto, "/proc/net/netstat");
+ r = td_proto_read(proto, "/proc/net/netstat");
if (r < 0)
goto ERROR;
// Fetch FragOKs
- r = collecty_proto_get(proto, "Ip", "FragOKs", &frags_oks);
+ r = td_proto_get(proto, "Ip", "FragOKs", &frags_oks);
if (r < 0)
goto ERROR;
// Fetch FragFails
- r = collecty_proto_get(proto, "Ip", "FragFails", &frags_fails);
+ r = td_proto_get(proto, "Ip", "FragFails", &frags_fails);
if (r < 0)
goto ERROR;
// Fetch FragFails
- r = collecty_proto_get(proto, "Ip", "FragFails", &frags_creates);
+ r = td_proto_get(proto, "Ip", "FragFails", &frags_creates);
if (r < 0)
goto ERROR;
// Fetch ReasmTimeout
- r = collecty_proto_get(proto, "Ip", "ReasmTimeout", &reasm_timeout);
+ r = td_proto_get(proto, "Ip", "ReasmTimeout", &reasm_timeout);
if (r < 0)
goto ERROR;
// Fetch ReasmReqds
- r = collecty_proto_get(proto, "Ip", "ReasmReqds", &reasm_reqds);
+ r = td_proto_get(proto, "Ip", "ReasmReqds", &reasm_reqds);
if (r < 0)
goto ERROR;
// Fetch ReasmOKs
- r = collecty_proto_get(proto, "Ip", "ReasmOKs", &reasm_oks);
+ r = td_proto_get(proto, "Ip", "ReasmOKs", &reasm_oks);
if (r < 0)
goto ERROR;
// Fetch ReasmFails
- r = collecty_proto_get(proto, "Ip", "ReasmFails", &reasm_fails);
+ r = td_proto_get(proto, "Ip", "ReasmFails", &reasm_fails);
if (r < 0)
goto ERROR;
// Submit the values
- r = collecty_source_submit(source, NULL,
+ r = td_source_submit(source, NULL,
"%lu:%lu:%lu:%lu:%lu:%lu:%lu", frags_oks, frags_fails, frags_creates,
reasm_timeout, reasm_reqds, reasm_oks, reasm_fails);
ERROR:
if (proto)
- collecty_proto_unref(proto);
+ td_proto_unref(proto);
return r;
}
-const collecty_source_impl ipfrag4_source = {
+const td_source_impl ipfrag4_source = {
.name = "ipfrag4",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_IPFRAG4_H
-#define COLLECTY_SOURCE_IPFRAG4_H
+#ifndef TELEMETRY_SOURCE_IPFRAG4_H
+#define TELEMETRY_SOURCE_IPFRAG4_H
#include "../source.h"
-extern const collecty_source_impl ipfrag4_source;
+extern const td_source_impl ipfrag4_source;
-#endif /* COLLECTY_SOURCE_IPFRAG4_H */
+#endif /* TELEMETRY_SOURCE_IPFRAG4_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "../source.h"
#include "loadavg.h"
-static int loadavg_heartbeat(collecty_ctx* ctx, collecty_source* source) {
+static int loadavg_heartbeat(td_ctx* ctx, td_source* source) {
double loadavg[3];
int r;
return r;
// Submit the values
- return collecty_source_submit(source, NULL,
+ return td_source_submit(source, NULL,
"%f:%f:%f", loadavg[0], loadavg[1], loadavg[2]);
}
-const collecty_source_impl loadavg_source = {
+const td_source_impl loadavg_source = {
.name = "loadavg",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_LOADAVG_H
-#define COLLECTY_SOURCE_LOADAVG_H
+#ifndef TELEMETRY_SOURCE_LOADAVG_H
+#define TELEMETRY_SOURCE_LOADAVG_H
#include "../source.h"
-extern const collecty_source_impl loadavg_source;
+extern const td_source_impl loadavg_source;
-#endif /* COLLECTY_SOURCE_LOADAVG_H */
+#endif /* TELEMETRY_SOURCE_LOADAVG_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "../source.h"
#include "memory.h"
-static int memory_heartbeat(collecty_ctx* ctx, collecty_source* source) {
- collecty_proc_meminfo meminfo = {};
+static int memory_heartbeat(td_ctx* ctx, td_source* source) {
+ td_proc_meminfo meminfo = {};
int r;
// Read all values from /proc/meminfo
- r = collecty_proc_read_meminfo(ctx, &meminfo);
+ r = td_proc_read_meminfo(ctx, &meminfo);
if (r < 0)
return r;
// Submit the values
- return collecty_source_submit(source, NULL,
+ return td_source_submit(source, NULL,
"%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu",
meminfo.mem_total, meminfo.mem_free, meminfo.mem_available,
meminfo.cached, meminfo.buffers, meminfo.active, meminfo.inactive,
meminfo.sunreclaim, meminfo.swap_total, meminfo.swap_free);
}
-const collecty_source_impl memory_source = {
+const td_source_impl memory_source = {
.name = "memory",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_MEMORY_H
-#define COLLECTY_SOURCE_MEMORY_H
+#ifndef TELEMETRY_SOURCE_MEMORY_H
+#define TELEMETRY_SOURCE_MEMORY_H
#include "../source.h"
-extern const collecty_source_impl memory_source;
+extern const td_source_impl memory_source;
-#endif /* COLLECTY_SOURCE_MEMORY_H */
+#endif /* TELEMETRY_SOURCE_MEMORY_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "../source.h"
#include "pressure-cpu.h"
-static int pressure_cpu_heartbeat(collecty_ctx* ctx, collecty_source* source) {
- collecty_pressure_stats stats = {};
+static int pressure_cpu_heartbeat(td_ctx* ctx, td_source* source) {
+ td_pressure_stats stats = {};
int r;
// Read all values from /proc/pressure/cpu
- r = collecty_proc_read_pressure(ctx, "cpu", &stats);
+ r = td_proc_read_pressure(ctx, "cpu", &stats);
if (r < 0)
return r;
// Submit the values
- return collecty_source_submit(source, NULL, "%.2f:%.2f:%.2f:%lu:%.2f:%.2f:%.2f:%lu",
+ return td_source_submit(source, NULL, "%.2f:%.2f:%.2f:%lu:%.2f:%.2f:%.2f:%lu",
stats.some.avg10, stats.some.avg60, stats.some.avg300, stats.some.total,
stats.full.avg10, stats.full.avg60, stats.full.avg300, stats.full.total);
}
-const collecty_source_impl pressure_cpu_source = {
+const td_source_impl pressure_cpu_source = {
.name = "pressure-cpu",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_PRESSURE_CPU_H
-#define COLLECTY_SOURCE_PRESSURE_CPU_H
+#ifndef TELEMETRY_SOURCE_PRESSURE_CPU_H
+#define TELEMETRY_SOURCE_PRESSURE_CPU_H
#include "../source.h"
-extern const collecty_source_impl pressure_cpu_source;
+extern const td_source_impl pressure_cpu_source;
-#endif /* COLLECTY_SOURCE_PRESSURE_CPU_H */
+#endif /* TELEMETRY_SOURCE_PRESSURE_CPU_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "../source.h"
#include "pressure-io.h"
-static int pressure_io_heartbeat(collecty_ctx* ctx, collecty_source* source) {
- collecty_pressure_stats stats = {};
+static int pressure_io_heartbeat(td_ctx* ctx, td_source* source) {
+ td_pressure_stats stats = {};
int r;
// Read all values from /proc/pressure/io
- r = collecty_proc_read_pressure(ctx, "io", &stats);
+ r = td_proc_read_pressure(ctx, "io", &stats);
if (r < 0)
return r;
// Submit the values
- return collecty_source_submit(source, NULL, "%.2f:%.2f:%.2f:%lu:%.2f:%.2f:%.2f:%lu",
+ return td_source_submit(source, NULL, "%.2f:%.2f:%.2f:%lu:%.2f:%.2f:%.2f:%lu",
stats.some.avg10, stats.some.avg60, stats.some.avg300, stats.some.total,
stats.full.avg10, stats.full.avg60, stats.full.avg300, stats.full.total);
}
-const collecty_source_impl pressure_io_source = {
+const td_source_impl pressure_io_source = {
.name = "pressure-io",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_PRESSURE_IO_H
-#define COLLECTY_SOURCE_PRESSURE_IO_H
+#ifndef TELEMETRY_SOURCE_PRESSURE_IO_H
+#define TELEMETRY_SOURCE_PRESSURE_IO_H
#include "../source.h"
-extern const collecty_source_impl pressure_io_source;
+extern const td_source_impl pressure_io_source;
-#endif /* COLLECTY_SOURCE_PRESSURE_IO_H */
+#endif /* TELEMETRY_SOURCE_PRESSURE_IO_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "../source.h"
#include "pressure-memory.h"
-static int pressure_memory_heartbeat(collecty_ctx* ctx, collecty_source* source) {
- collecty_pressure_stats stats = {};
+static int pressure_memory_heartbeat(td_ctx* ctx, td_source* source) {
+ td_pressure_stats stats = {};
int r;
// Read all values from /proc/pressure/memory
- r = collecty_proc_read_pressure(ctx, "memory", &stats);
+ r = td_proc_read_pressure(ctx, "memory", &stats);
if (r < 0)
return r;
// Submit the values
- return collecty_source_submit(source, NULL, "%.2f:%.2f:%.2f:%lu:%.2f:%.2f:%.2f:%lu",
+ return td_source_submit(source, NULL, "%.2f:%.2f:%.2f:%lu:%.2f:%.2f:%.2f:%lu",
stats.some.avg10, stats.some.avg60, stats.some.avg300, stats.some.total,
stats.full.avg10, stats.full.avg60, stats.full.avg300, stats.full.total);
}
-const collecty_source_impl pressure_memory_source = {
+const td_source_impl pressure_memory_source = {
.name = "pressure-memory",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_PRESSURE_MEMORY_H
-#define COLLECTY_SOURCE_PRESSURE_MEMORY_H
+#ifndef TELEMETRY_SOURCE_PRESSURE_MEMORY_H
+#define TELEMETRY_SOURCE_PRESSURE_MEMORY_H
#include "../source.h"
-extern const collecty_source_impl pressure_memory_source;
+extern const td_source_impl pressure_memory_source;
-#endif /* COLLECTY_SOURCE_PRESSURE_MEMORY_H */
+#endif /* TELEMETRY_SOURCE_PRESSURE_MEMORY_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
// /proc/stat currently carries 10 fields
#define MAX_FIELDS 10
-static int processor_heartbeat(collecty_ctx* ctx, collecty_source* source) {
+static int processor_heartbeat(td_ctx* ctx, td_source* source) {
unsigned long usage[MAX_FIELDS] = {};
int r;
// Read all values from /proc/stat
- r = collecty_proc_read_stat(ctx, "cpu", usage, MAX_FIELDS);
+ r = td_proc_read_stat(ctx, "cpu", usage, MAX_FIELDS);
if (r < MAX_FIELDS)
return r;
// Submit the values
- return collecty_source_submit(source, NULL,
+ return td_source_submit(source, NULL,
"%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu",
usage[0], usage[1], usage[2], usage[3], usage[4],
usage[5], usage[6], usage[7], usage[8], usage[9]);
}
-const collecty_source_impl processor_source = {
+const td_source_impl processor_source = {
.name = "processor",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_PROCESSOR_H
-#define COLLECTY_SOURCE_PROCESSOR_H
+#ifndef TELEMETRY_SOURCE_PROCESSOR_H
+#define TELEMETRY_SOURCE_PROCESSOR_H
#include "../source.h"
-extern const collecty_source_impl processor_source;
+extern const td_source_impl processor_source;
-#endif /* COLLECTY_SOURCE_PROCESSOR_H */
+#endif /* TELEMETRY_SOURCE_PROCESSOR_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "../source.h"
#include "softirq.h"
-static int callback(collecty_ctx* ctx, const char* key, uint64_t value, void* data) {
- collecty_source* source = data;
+static int callback(td_ctx* ctx, const char* key, uint64_t value, void* data) {
+ td_source* source = data;
// Submit the data
- return collecty_source_submit(source, key, "%lu", value);
+ return td_source_submit(source, key, "%lu", value);
}
-static int softirq_heartbeat(collecty_ctx* ctx, collecty_source* source) {
- return collecty_proc_read_softirq(ctx, callback, source);
+static int softirq_heartbeat(td_ctx* ctx, td_source* source) {
+ return td_proc_read_softirq(ctx, callback, source);
}
-const collecty_source_impl softirq_source = {
+const td_source_impl softirq_source = {
.name = "softirq",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_SOFTIRQS_H
-#define COLLECTY_SOURCE_SOFTIRQS_H
+#ifndef TELEMETRY_SOURCE_SOFTIRQS_H
+#define TELEMETRY_SOURCE_SOFTIRQS_H
#include "../source.h"
-extern const collecty_source_impl softirq_source;
+extern const td_source_impl softirq_source;
-#endif /* COLLECTY_SOURCE_SOFTIRQS_H */
+#endif /* TELEMETRY_SOURCE_SOFTIRQS_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
This is a test source which always fails.
*/
-static int test_error_heartbeat(collecty_ctx* ctx, collecty_source* source) {
+static int test_error_heartbeat(td_ctx* ctx, td_source* source) {
return -ENOSPC;
}
-const collecty_source_impl test_error_source = {
+const td_source_impl test_error_source = {
.name = "test-error",
// Methods
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_TEST_ERROR_H
-#define COLLECTY_SOURCE_TEST_ERROR_H
+#ifndef TELEMETRY_SOURCE_TEST_ERROR_H
+#define TELEMETRY_SOURCE_TEST_ERROR_H
#include "../source.h"
-extern const collecty_source_impl test_error_source;
+extern const td_source_impl test_error_source;
-#endif /* COLLECTY_SOURCE_TEST_ERROR_H */
+#endif /* TELEMETRY_SOURCE_TEST_ERROR_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
This is a test source which fails with a certain probability.
*/
-static int test_flapping_heartbeat(collecty_ctx* ctx, collecty_source* source) {
+static int test_flapping_heartbeat(td_ctx* ctx, td_source* source) {
int r;
// Fetch some random value
return -ENOSPC;
// Otherwise return the random number
- return collecty_source_submit(source, NULL, "%d", r);
+ return td_source_submit(source, NULL, "%d", r);
}
-const collecty_source_impl test_flapping_source = {
+const td_source_impl test_flapping_source = {
.name = "test-flapping",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_TEST_FLAPPING_H
-#define COLLECTY_SOURCE_TEST_FLAPPING_H
+#ifndef TELEMETRY_SOURCE_TEST_FLAPPING_H
+#define TELEMETRY_SOURCE_TEST_FLAPPING_H
#include "../source.h"
-extern const collecty_source_impl test_flapping_source;
+extern const td_source_impl test_flapping_source;
-#endif /* COLLECTY_SOURCE_TEST_FLAPPING_H */
+#endif /* TELEMETRY_SOURCE_TEST_FLAPPING_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
This is a test stalls the event loop.
*/
-static int test_stall_heartbeat(collecty_ctx* ctx, collecty_source* source) {
+static int test_stall_heartbeat(td_ctx* ctx, td_source* source) {
// Sleep for 500ms
return usleep(MSEC_TO_USEC(500));
}
-const collecty_source_impl test_stall_source = {
+const td_source_impl test_stall_source = {
.name = "test-stall",
// Methods
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_TEST_STALL_H
-#define COLLECTY_SOURCE_TEST_STALL_H
+#ifndef TELEMETRY_SOURCE_TEST_STALL_H
+#define TELEMETRY_SOURCE_TEST_STALL_H
#include "../source.h"
-extern const collecty_source_impl test_stall_source;
+extern const td_source_impl test_stall_source;
-#endif /* COLLECTY_SOURCE_TEST_STALL_H */
+#endif /* TELEMETRY_SOURCE_TEST_STALL_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "../source.h"
#include "unbound.h"
-static int unbound_on_success(collecty_ctx* ctx,
- int rc, collecty_file* stdout, void* data) {
- collecty_source* source = data;
+static int unbound_on_success(td_ctx* ctx,
+ int rc, td_file* stdout, void* data) {
+ td_source* source = data;
unsigned long rec_time_median = 0;
unsigned long rec_replies = 0;
unsigned long cachehits = 0;
double rec_time_avg = 0;
int r;
- collecty_file_parser parser[] = {
+ td_file_parser parser[] = {
PARSE1("total.num.queries=%lu", &queries),
PARSE1("total.num.cachehits=%lu", &cachehits),
PARSE1("total.num.cachemiss=%lu", &cachemiss),
};
// Parse the output
- r = collecty_file_parse(stdout, parser);
+ r = td_file_parse(stdout, parser);
if (r < 0)
return r;
// Submit values
- return collecty_source_submit(source, NULL, "%lu:%lu:%lu:%lu:%lu:%lf:%lu",
+ return td_source_submit(source, NULL, "%lu:%lu:%lu:%lu:%lu:%lf:%lu",
queries, cachehits, cachemiss, prefetch, rec_replies, rec_time_avg, rec_time_median);
}
-static int unbound_heartbeat(collecty_ctx* ctx, collecty_source* source) {
- collecty_command* command = NULL;
+static int unbound_heartbeat(td_ctx* ctx, td_source* source) {
+ td_command* command = NULL;
int r;
// Run unbound-control to fetch stats
const char* argv[] = { "unbound-control", "stats_noreset", NULL };
// Create a new command
- r = collecty_source_create_command(source, &command);
+ r = td_source_create_command(source, &command);
if (r < 0)
goto ERROR;
// Register the success callback
- collecty_command_on_success(command, unbound_on_success, source);
+ td_command_on_success(command, unbound_on_success, source);
// Execute the command
- r = collecty_command_execute(command, argv);
+ r = td_command_execute(command, argv);
ERROR:
if (command)
- collecty_command_unref(command);
+ td_command_unref(command);
return r;
}
-const collecty_source_impl unbound_source = {
+const td_source_impl unbound_source = {
.name = "unbound",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_UNBOUND_H
-#define COLLECTY_SOURCE_UNBOUND_H
+#ifndef TELEMETRY_SOURCE_UNBOUND_H
+#define TELEMETRY_SOURCE_UNBOUND_H
#include "../source.h"
-extern const collecty_source_impl unbound_source;
+extern const td_source_impl unbound_source;
-#endif /* COLLECTY_SOURCE_UNBOUND_H */
+#endif /* TELEMETRY_SOURCE_UNBOUND_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "../source.h"
#include "uptime.h"
-static int uptime_heartbeat(collecty_ctx* ctx, collecty_source* source) {
+static int uptime_heartbeat(td_ctx* ctx, td_source* source) {
struct sysinfo info = {};
int r;
return -errno;
// Submit the uptime
- return collecty_source_submit(source, NULL, "%ld", info.uptime);
+ return td_source_submit(source, NULL, "%ld", info.uptime);
}
-const collecty_source_impl uptime_source = {
+const td_source_impl uptime_source = {
.name = "uptime",
// RRD Data Sources
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_SOURCE_UPTIME_H
-#define COLLECTY_SOURCE_UPTIME_H
+#ifndef TELEMETRY_SOURCE_UPTIME_H
+#define TELEMETRY_SOURCE_UPTIME_H
#include "../source.h"
-extern const collecty_source_impl uptime_source;
+extern const td_source_impl uptime_source;
-#endif /* COLLECTY_SOURCE_UPTIME_H */
+#endif /* TELEMETRY_SOURCE_UPTIME_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_STRING_H
-#define COLLECTY_STRING_H
+#ifndef TELEMETRY_STRING_H
+#define TELEMETRY_STRING_H
#include <ctype.h>
#include <errno.h>
#include "util.h"
-inline int collecty_string_equals(const char* s1, const char* s2) {
+inline int td_string_equals(const char* s1, const char* s2) {
return strcmp(s1, s2) == 0;
}
-#define collecty_string_vformat(s, format, args) \
- __collecty_string_vformat(s, sizeof(s), format, args)
+#define td_string_vformat(s, format, args) \
+ __td_string_vformat(s, sizeof(s), format, args)
-static inline int __collecty_string_vformat(char* s,
+static inline int __td_string_vformat(char* s,
const size_t length, const char* format, va_list args)
__attribute__((format(printf, 3, 0)));
-static inline int __collecty_string_vformat(char* s,
+static inline int __td_string_vformat(char* s,
const size_t length, const char* format, va_list args) {
// Write string to buffer
const ssize_t required = vsnprintf(s, length, format, args);
return 0;
}
-#define collecty_string_format(s, format, ...) \
- __collecty_string_format(s, sizeof(s), format, __VA_ARGS__)
+#define td_string_format(s, format, ...) \
+ __td_string_format(s, sizeof(s), format, __VA_ARGS__)
-static inline int __collecty_string_format(char* s,
+static inline int __td_string_format(char* s,
const size_t length, const char* format, ...)
__attribute__((format(printf, 3, 4)));
-static inline int __collecty_string_format(char* s,
+static inline int __td_string_format(char* s,
const size_t length, const char* format, ...) {
va_list args;
int r;
- // Call __collecty_string_vformat
+ // Call __td_string_vformat
va_start(args, format);
- r = __collecty_string_vformat(s, length, format, args);
+ r = __td_string_vformat(s, length, format, args);
va_end(args);
return r;
}
-#define collecty_string_set(s, value) \
- __collecty_string_set(s, sizeof(s), value)
+#define td_string_set(s, value) \
+ __td_string_set(s, sizeof(s), value)
-static inline int __collecty_string_set(char* s, const size_t length, const char* value) {
+static inline int __td_string_set(char* s, const size_t length, const char* value) {
// If value is NULL or an empty, we will overwrite the buffer with just zeros
if (unlikely(!value)) {
*s = '\0';
return -ENOBUFS;
}
-#define collecty_string_setn(s, value, l) \
- __collecty_string_setn(s, sizeof(s), value, l)
+#define td_string_setn(s, value, l) \
+ __td_string_setn(s, sizeof(s), value, l)
-static inline int __collecty_string_setn(char* s, const size_t length, const char* value, const size_t l) {
+static inline int __td_string_setn(char* s, const size_t length, const char* value, const size_t l) {
// Fail if we don't have enough space
if (unlikely(l >= length))
return -ENOBUFS;
return l;
}
-static inline void collecty_string_lstrip(char* s) {
+static inline void td_string_lstrip(char* s) {
if (!s)
return;
memmove(s, s + 1, l--);
}
-static inline void collecty_string_rstrip(char* s) {
+static inline void td_string_rstrip(char* s) {
if (!s)
return;
s[l-- - 1] = '\0';
}
-static inline void collecty_string_rstrip2(char* s, char c) {
+static inline void td_string_rstrip2(char* s, char c) {
if (!s)
return;
s[l-- - 1] = '\0';
}
-static inline void collecty_string_strip(char* s) {
+static inline void td_string_strip(char* s) {
// Strip everything on the left side
- collecty_string_lstrip(s);
+ td_string_lstrip(s);
// Strip everything on the right side
- collecty_string_rstrip(s);
+ td_string_rstrip(s);
}
-#endif /* COLLECTY_STRING_H */
+#endif /* TELEMETRY_STRING_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_TIME_H
-#define COLLECTY_TIME_H
+#ifndef TELEMETRY_TIME_H
+#define TELEMETRY_TIME_H
// Seconds to milliseconds
#define SEC_TO_MSEC(s) ((s) * 1000UL)
// Nanoseconds to microseconds
#define NSEC_TO_USEC(ns) ((ns) / 1000UL)
-#endif /* COLLECTY_TIME_H */
+#endif /* TELEMETRY_TIME_H */
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
#include "string.h"
#include "util.h"
-int __collecty_format_number(char* buffer, size_t length, int number) {
+int __td_format_number(char* buffer, size_t length, int number) {
// Format the number if positive or zero
if (number >= 0)
- return __collecty_string_format(buffer, length, "%d", number);
+ return __td_string_format(buffer, length, "%d", number);
// Otherwise we set it to UNKNOWN
- return __collecty_string_set(buffer, length, "U");
+ return __td_string_set(buffer, length, "U");
}
// Helper function to set the title
-int collecty_format_title(char** title, const char* format, ...) {
+int td_format_title(char** title, const char* format, ...) {
va_list args;
int r;
/*#############################################################################
# #
-# collecty - A system statistics collection daemon for IPFire #
+# telemetryd - The IPFire Telemetry Collection Service #
# Copyright (C) 2025 IPFire Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# #
#############################################################################*/
-#ifndef COLLECTY_UTIL_H
-#define COLLECTY_UTIL_H
+#ifndef TELEMETRY_UTIL_H
+#define TELEMETRY_UTIL_H
#include <stddef.h>
# endif
#endif
-#define collecty_format_number(buffer, number) \
- __collecty_format_number(buffer, sizeof(buffer), number)
+#define td_format_number(buffer, number) \
+ __td_format_number(buffer, sizeof(buffer), number)
-int __collecty_format_number(char* buffer, size_t length, int number);
+int __td_format_number(char* buffer, size_t length, int number);
// Helper function to set the title
-int collecty_format_title(char** title, const char* format, ...)
+int td_format_title(char** title, const char* format, ...)
__attribute__((format(printf, 2, 3)));
-#endif /* COLLECTY_UTIL_H */
+#endif /* TELEMETRY_UTIL_H */
+++ /dev/null
-[D-BUS Service]
-Name=org.ipfire.collecty1
-Exec=usr/bin/collectyd
-User=root
-SystemdService=collecty.service
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<!--
- This file is part of collecty.
+ This file is part of telemetry.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
<busconfig>
<policy user="root">
- <allow own="org.ipfire.collecty1"/>
- <allow send_destination="org.ipfire.collecty1"/>
- <allow receive_sender="org.ipfire.collecty1"/>
+ <allow own="org.ipfire.telemetry1"/>
+ <allow send_destination="org.ipfire.telemetry1"/>
+ <allow receive_sender="org.ipfire.telemetry1"/>
</policy>
<policy context="default">
- <allow send_destination="org.ipfire.collecty1"/>
- <allow receive_sender="org.ipfire.collecty1"/>
+ <allow send_destination="org.ipfire.telemetry1"/>
+ <allow receive_sender="org.ipfire.telemetry1"/>
</policy>
</busconfig>
--- /dev/null
+[D-BUS Service]
+Name=org.ipfire.telemetry1
+Exec=/usr/bin/telemetryd
+User=root
+SystemdService=telemetry.service
+++ /dev/null
-[Unit]
-Description=collecty - A system data collecting daemon
-
-[Service]
-Type=dbus
-ExecStart=@sbindir@/collectyd
-ExecReload=/bin/kill -HUP $MAINPID
-BusName=org.ipfire.collecty1
-
-[Install]
-WantedBy=multi-user.target
+++ /dev/null
-[Unit]
-Description=Collecty Service Bus Name
-
-[BusName]
-Service=collecty.service
-AllowWorld=talk
--- /dev/null
+[Unit]
+Description=IPFire Telemetry Service Bus Name
+
+[BusName]
+Service=telemetry.service
+AllowWorld=talk
--- /dev/null
+[Unit]
+Description=The IPFire Telemetry Collection Service
+
+[Service]
+Type=dbus
+ExecStart=@sbindir@/telemetryd
+ExecReload=/bin/kill -HUP $MAINPID
+BusName=org.ipfire.telemetry1
+
+[Install]
+WantedBy=multi-user.target