From: Michael Tremer Date: Thu, 30 Oct 2025 19:03:25 +0000 (+0000) Subject: graphs: Allow manually changing the locale X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7a123d038f3fdd6ba038538d0d0bd310ae582afc;p=telemetry.git graphs: Allow manually changing the locale Signed-off-by: Michael Tremer --- diff --git a/src/client/main.c b/src/client/main.c index 1ef0543..04a60be 100644 --- a/src/client/main.c +++ b/src/client/main.c @@ -60,6 +60,9 @@ typedef struct td_client_ctx { const char* since; const char* until; } interval; + + // Locale + const char* locale; } td_client_ctx; enum { @@ -69,6 +72,7 @@ enum { OPT_SINCE = 4, OPT_UNTIL = 5, OPT_OMIT_TITLE = 6, + OPT_LOCALE = 7, }; static struct argp_option options[] = { @@ -82,6 +86,9 @@ static struct argp_option options[] = { // Flags { "omit-title", OPT_OMIT_TITLE, NULL, 0, "Omit the title in the graph image", 0}, + + // Locale + { "locale", OPT_LOCALE, "CODE", 0, "Render the graph for a different locale", 0 }, { NULL }, }; @@ -124,6 +131,10 @@ static error_t parse(int key, char* arg, struct argp_state* state) { ctx->flags |= OMIT_TITLE; break; + case OPT_LOCALE: + ctx->locale = arg; + break; + // Called for each argument case ARGP_KEY_ARG: // Take the graph name as first argument @@ -230,6 +241,13 @@ static int render(td_client_ctx* ctx) { goto ERROR; } + // Send the locale + if (ctx->locale) { + r = sd_bus_message_append(m, "{sv}", "locale", "s", ctx->locale); + if (r < 0) + goto ERROR; + } + // Close the array r = sd_bus_message_close_container(m); if (r < 0) diff --git a/src/daemon/graph-bus.c b/src/daemon/graph-bus.c index 540662e..f37c275 100644 --- a/src/daemon/graph-bus.c +++ b/src/daemon/graph-bus.c @@ -193,6 +193,12 @@ static int td_graph_bus_render(sd_bus_message* m, void* data, sd_bus_error* erro if (omit_title) options.flags |= TD_GRAPH_OMIT_TITLE; + + // Parse "locale" + } else if (td_string_equals(key, "locale")) { + r = sd_bus_message_read(m, "v", "s", &options.locale); + if (r < 0) + goto ERROR; } // Leave the container diff --git a/src/daemon/graph.c b/src/daemon/graph.c index b1a8a15..81522ca 100644 --- a/src/daemon/graph.c +++ b/src/daemon/graph.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -267,6 +268,19 @@ static int td_graph_render_title(td_graph* self, const char* object, return 0; } +static void td_graph_reset_locale(td_ctx* ctx, char* locale) { + const char* l = NULL; + + // Nothing to do if the locale is not known + if (!*locale) + return; + + // Set the locale + l = setlocale(LC_ALL, locale); + if (!l) + ERROR(ctx, "Failed to reset the locale to '%s': %m\n", locale); +} + 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; @@ -279,6 +293,10 @@ int td_graph_render(td_graph* self, const char* object, double ymax = 0; int r; + // Locale + char locale[NAME_MAX] = ""; + const char* l; + // Measure the runtime clock_t t_start = 0; clock_t t_end = 0; @@ -306,6 +324,15 @@ int td_graph_render(td_graph* self, const char* object, goto ERROR; } + // Fetch the current locale + l = setlocale(LC_ALL, NULL); + if (l) { + // Store the locale for it to be reset later + r = td_string_set(locale, l); + if (r < 0) + goto ERROR; + } + // Allocate a new argument list r = td_args_create(&args, self->ctx); if (r < 0) @@ -406,6 +433,15 @@ int td_graph_render(td_graph* self, const char* object, if (r < 0) goto ERROR; + // Change the locale + if (options->locale) { + l = setlocale(LC_ALL, options->locale); + if (l) + DEBUG(self->ctx, "Locale has been changed to: %s\n", l); + else + ERROR(self->ctx, "Failed to set locale '%s': %m. Ignoring.\n", options->locale); + } + // Call the implementation to add some arguments r = self->impl->render(self->ctx, self, args, object); if (r < 0) @@ -421,6 +457,11 @@ int td_graph_render(td_graph* self, const char* object, // warning since rrdtool >= 1.9 has constified their input arguments. r = rrd_graph(td_args_argc(args), (void*)td_args_argv(args), &data, &w, &h, f, &ymin, &ymax); + + // Reset the locale again + td_graph_reset_locale(self->ctx, locale); + + // Handle any errors if (r < 0) { ERROR(self->ctx, "Failed to generate the graph: %s\n", rrd_get_error()); rrd_clear_error(); @@ -452,6 +493,9 @@ int td_graph_render(td_graph* self, const char* object, } ERROR: + // Reset the locale + td_graph_reset_locale(self->ctx, locale); + if (data) { for (unsigned int i = 0; data[i]; i++) free(data[i]); diff --git a/src/daemon/graph.h b/src/daemon/graph.h index b2d505a..183b3f1 100644 --- a/src/daemon/graph.h +++ b/src/daemon/graph.h @@ -78,6 +78,9 @@ typedef struct td_graph_render_options { // Output Format const char* format; + // Locale + const char* locale; + // Dimensions struct { unsigned int h;