From e13b448e37d0c3219d684f73c151fcffeecaba93 Mon Sep 17 00:00:00 2001 From: Castulo Martinez Date: Fri, 8 Mar 2019 22:26:50 +0000 Subject: [PATCH] Function to format a message before printing There is the need to print info about swupd operations in a parsable JSON format. This function provides a wrapper function to format the messages to comply with the JSON format if the --json-output flag is used. Signed-off-by: Castulo Martinez --- src/globals.c | 1 - src/lib/log.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/lib/log.h | 21 +++++++++++- src/swupd.h | 1 - 4 files changed, 107 insertions(+), 8 deletions(-) diff --git a/src/globals.c b/src/globals.c index a1e8199c..9cd8979b 100644 --- a/src/globals.c +++ b/src/globals.c @@ -59,7 +59,6 @@ bool keepcache = false; timelist *global_times = NULL; int max_retries = 3; int retry_delay = 10; -bool json_output = false; /* NOTE: Today the content and version server urls are the same in * all cases. It is highly likely these will eventually differ, eg: diff --git a/src/lib/log.c b/src/lib/log.c index 408300d5..1d9f102f 100644 --- a/src/lib/log.c +++ b/src/lib/log.c @@ -19,19 +19,94 @@ #define _GNU_SOURCE +#include #include +#include +#include #include #include "log.h" #define DEBUG_HEADER_SIZE 50 static int cur_log_level = LOG_INFO; +static int json_format = 0; void set_log_level(int log_level) { cur_log_level = log_level; } +void set_json_format(void) +{ + json_format = 1; +} + +void json_start(const char *op) +{ + if (json_format) { + fprintf(stderr, "[\n"); + fflush(stderr); + fprintf(stderr, "{ \"%s\" : \"start\" },\n", op); + fflush(stderr); + } +} + +void json_end(const char *op) +{ + if (json_format) { + fprintf(stderr, "{ \"%s\" : \"end\" }\n", op); + fflush(stderr); + fprintf(stderr, "]\n"); + fflush(stderr); + } +} + +void format_to_json(const char *type, const char *msg, va_list args_list) +{ + const int MAX_TYPE_LENGTH = 8; + char *full_msg; + char ltype[MAX_TYPE_LENGTH]; + + /* make sure the type is all lower case */ + if (type) { + for (int i = 0; type[i]; i++) { + ltype[i] = tolower(type[i]); + } + ltype[strlen(type)] = '\0'; + } else { + /* if no type was provided we default to info */ + strcpy(ltype, "info"); + } + + /* build the full message based on all the arguments */ + if (vasprintf(&full_msg, msg, args_list) < 0) { + abort(); + } + + if (strcmp(full_msg, "") != 0) { + int j = 0; + for (unsigned int i = 0; i <= strlen(full_msg); i++) { + /* if the message has double quotes replace them with single quotes + * since double quotes are not supported in JSON */ + if (full_msg[i] == '"') { + full_msg[i] = '\''; + } + /* remove all '\n' from the message */ + if (full_msg[i] != '\n') { + full_msg[j] = full_msg[i]; + j++; + } + } + full_msg[j] = '\0'; + + /* add the JSON format and print immediately */ + fprintf(stderr, "{ \"type\" : \"%s\", \"msg\" : \"%s\" },\n", ltype, full_msg); + fflush(stderr); + } + + free(full_msg); +} + void log_full(int log_level, FILE *out, const char *file, int line, const char *label, const char *format, ...) { if (cur_log_level < log_level) { @@ -44,7 +119,7 @@ void log_full(int log_level, FILE *out, const char *file, int line, const char * int printed; // In debug mode, print more information - if (cur_log_level == LOG_DEBUG) { + if (cur_log_level == LOG_DEBUG && !json_format) { time_t currtime; time(&currtime); timeinfo = localtime(&currtime); @@ -56,11 +131,18 @@ void log_full(int log_level, FILE *out, const char *file, int line, const char * } } - if (label) { - fprintf(out, "%s: ", label); + /* initialize the arguments list */ + va_start(ap, format); + + if (json_format) { + format_to_json(label, format, ap); + } else { + if (label) { + fprintf(out, "%s: ", label); + } + vfprintf(out, format, ap); } - va_start(ap, format); - vfprintf(out, format, ap); + /* clean memory assigned to arguments list */ va_end(ap); } diff --git a/src/lib/log.h b/src/lib/log.h index 89921e2b..f84651ff 100644 --- a/src/lib/log.h +++ b/src/lib/log.h @@ -2,7 +2,6 @@ #define __SWUPD_LOG__ #include -#include #ifdef __cplusplus extern "C" { @@ -34,6 +33,26 @@ void log_full(int log_level, FILE *out, const char *file, int line, const char * #define info(_fmt, ...) log_full(LOG_INFO, stdout, __FILE__, __LINE__, NULL, _fmt, ##__VA_ARGS__); #define debug(_fmt, ...) log_full(LOG_DEBUG, stdout, __FILE__, __LINE__, "Debug", _fmt, ##__VA_ARGS__); +/* + * Enables the JSON formatter + */ +void set_json_format(void); + +/* + * Converts the provided message to a JSON formatted stream + */ +void format_to_json(const char *, const char *, va_list); + +/* + * Generates the initial message of a JSON stream + */ +void json_start(const char *); + +/* + * Generates the final message of a JSON stream + */ +void json_end(const char *); + #ifdef __cplusplus } #endif diff --git a/src/swupd.h b/src/swupd.h index fd9d6e80..a619f94c 100644 --- a/src/swupd.h +++ b/src/swupd.h @@ -188,7 +188,6 @@ extern int skip_diskspace_check; extern timelist *global_times; extern int max_retries; extern int retry_delay; -extern bool json_output; extern char *version_url; extern char *content_url;