From a64c960548a3bf4b6dbd05f06cb3b210934e7bcf Mon Sep 17 00:00:00 2001 From: Jean Sirmai Date: Fri, 8 Nov 2024 16:13:05 +0100 Subject: [PATCH] /src/fsm/log/* introduces the functions that the log needs. The most important function: fsm_add_log() harbours the filters. It is in the file: /src/fsm/log/manager.c The four mandatory executive functions that the log needs to init, add and publish are in the dedicated file: /src/fsm/log/oper.c Three functions whose usefulness remains to be demonstrated are in /src/fsm/log/appendix.c The two structures (fsm_log_struct, fsm_log_struct_unit) and the two enums (severity, source) stay in fsm.h --- include/fsm.h | 148 +++++++++++++-------------------------- src/fsm/log/appendix.c | 112 ++++++++++++++++++++++++++++++ src/fsm/log/manager.c | 104 ++++++++++++++++++++++++++++ src/fsm/log/oper.c | 153 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 415 insertions(+), 102 deletions(-) create mode 100644 src/fsm/log/appendix.c create mode 100644 src/fsm/log/manager.c create mode 100644 src/fsm/log/oper.c diff --git a/include/fsm.h b/include/fsm.h index cc466d0..3585e2e 100644 --- a/include/fsm.h +++ b/include/fsm.h @@ -1,58 +1,32 @@ /** * @file - * FSM (Finite State Machine) header + * Fsm (finite state machine) header * * This file is part of Gem-graph. * - * @cond LICENSE - * Copyright © 2021 Libre en Communs - * Copyright © 2021-2024 Adrien Bourmault - * Copyright © 2021-2024 Jean Sirmai * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the Free - * Software Foundation, eisrc/log/ther version 3 of the License, or (at your option) any - * later version. + * This commit introduces the functions that the log needs. + * @see readme.docs and this text below. * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more - * details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * @endcond - * - * - * The fsm header lists all the structures that the log will need. + * --- * * The two structures and the two enums listed below will stay in the fsm header. * - * All functions but the last one will be in a dedicated file: src/log/oper.c - * This file will contain the declaration of the log with the static attribute, - * which will force all the functions that read or write it to be in it. + * All functions are now in dedicated files. + * + * The most important function: fsm_add_log() is in the file: + * /src/fsm/log/manager.c + * + * This file contains the declaration of the log with the static attribute, + * which forces all the functions that read or write it to be in it. * Forcing all functions that read or write to the log to be grouped together - * will prevent uncontrolled operations. + * help to prevent uncontrolled operations. * - * The four most important functions are: - * - fsm_init_log() - * - fsm_publish_log() - * - fsm_clear_log() - * - fsm_add_log_event() - * . - * - * A typical list would also feature the last three functions: - * - fsm_get_log_length() - * - fsm_seek_log() - * - fsm_remove_log() - * . - * but in the case of a log, their usefulness remains to be demonstrated. - * - * - * A last function: fsm_add_log() will be in another file: src/log/manager.c. * All events sent to the log must pass through this function, which allows them * to be filtered before being published in the log. * + * --- + * * Here's how the procedure works. * A message is send to the fsm_add_log() function for each documented event. * If there are too many events, this is the only function that allows you to @@ -70,28 +44,49 @@ * * file_source, function_source and string_value are three strings. * - * Here is the list of all the structures that the log will need. The functions - * will be documented in future commits. + * --- * - * - fsm_log_struct() - * - fsm_log_struct_unit() - * . + * The four mandatory executive functions that the log needs to init, add and + * publishare in the dedicated file: /src/fsm/log/oper.c: * - * - fsm_enum_log_severity() - * - fsm_enum_log_source() - * . + * NB: fsm_clear_log() is designed to close what was initiated by fsm_init_log(). + * As, in this commit, fsm_publish_log() is the last instruction and no memory + * leaks are detected, the use of fsm_clear_log() is not required. * * - fsm_init_log() * - fsm_publish_log() * - fsm_clear_log() * - fsm_add_log_event() + * . + * + * A typical list would also feature the following three functions + * but in the case of a log, their usefulness remains to be demonstrated. + * These functions are therefore apart in the file /src/fsm/log/appendix.c + * * - fsm_get_log_length() * - fsm_seek_log() * - fsm_remove_log() * . * - * - fsm_add_log() - * . + * + * @cond LICENSE + * Copyright © 2021 Libre en Communs + * Copyright © 2021-2024 Adrien Bourmault + * Copyright © 2021-2024 Jean Sirmai + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * @endcond */ @@ -243,61 +238,10 @@ long fsm_remove_log (fsm_log_struct *jj, const char *function_source, const char *string_value); - -/** - * @brief (1) This comment is not a duplicate: it will be displaced in the file: - * src/log/manager.c in next commits. - * - * It will be mandatory for any event to call the function fsm_add_log() - * to be published in the journal and it is here and only here that filters will - * be found. - * - * -- - * - * @details The fsm_struct_journal (gg_logs) will be a static instance in a - * dedicated file: src/log/manager.c - * Therefore, all the functions that read or write it will be in this file. - * This is to avoid uncontrolled operations on it. - * - * While the program is running, messages will be sent to the fsm_add_log() - * function for each documented event. - * If there are too many events, this is the only function that allows you to - * apply one or more filters before publication. This allows you to select the - * events of interest, which can vary depending on the type of session. - * - * These filters can operate on any of the following five parameters: - * severity, source, file_source, function_source, string_value . - * They can be combined using any logical operators and parentheses. - * - * -- - * - * @since 2024-08 - * - * @callgraph - * @see fsm_add_log_event() insertion into the log list - * - * @callergraph @see Almost all functions will have to report events and will - * therefore call fsm_add_log(). - * @see main() will send the first and last messages. - * - * - * @param severity: one of the following pre-defined values - * - * FATAL - ERROR - WARN - INFO - DEBUG - TRACE - * - * @param source: a pre-defined value (a name of a structure) that can be - * associated to each event. It can be set to 'NULL'. - * - * @param *file_source the name of the file that emits the event - * @param *function_source the function that emits the event - * @param *string_value any value that better specifies the event - * - * @see fsm_enum_log_severity - * @see fsm_enum_log_source - */ void fsm_add_log (int severity, int source, const char *file_source, const char *function_source, const char *string_value); + diff --git a/src/fsm/log/appendix.c b/src/fsm/log/appendix.c new file mode 100644 index 0000000..ab92fac --- /dev/null +++ b/src/fsm/log/appendix.c @@ -0,0 +1,112 @@ +/** + * @file + * + * This file is part of Gem-graph. The log (or journal) stores chronologically + * the events during a session run (rules exec, mainly) + * + * This file groups some functions that a typical list should implement but whose + * utility remains to evaluate in the case of a log list. + * + * @cond LICENSE + * Copyright © 2021 Libre en Communs + * Copyright © 2021-2024 Adrien Bourmault + * Copyright © 2021-2024 Jean Sirmai + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * @endcond + */ + +#include +#include +#include "../../../include/fsm.h" + +/** + * remove an event; + * the removal is a pop back + * + * @since 2024-09 + * + * @param *jj + * @param *file_source + * @param *function_source + * @param *string_value + * + * @returns the removed event date microseconds + */ +long fsm_remove_log (fsm_log_struct *jj, + const char *file_source, + const char *function_source, + const char *string_value) +{ + long usec; + fsm_log_struct_unit *tmp = jj->last; + if (! tmp) return -1; + usec = tmp->usec; + jj->last = tmp->prev; + if (jj->last) jj->last->next = NULL; + else jj->first = NULL; + free (tmp); + return usec; +} + + + +/** + * get log length + * + * @since 2024-09 + * + * @param *jj + * @returns log length + */ +int fsm_get_log_length (fsm_log_struct jj) +{ + fsm_log_struct_unit *a_unit = jj.first; + int nb = 0; + while (a_unit) + { + nb ++; + a_unit = a_unit->next; + } + return nb; +} + + +/** + * seek for an event + * + * @since 2024-09 + * + * @param *jj + * @param usec + * @param *file_source + * @param *function_source + * @param *string_value + */ +void fsm_seek_log (fsm_log_struct jj, + long usec, + const char *file_source, + const char *function_source, + const char *string_value) +{ + fsm_log_struct_unit *a_unit = jj.first; + int nb = 0; + while (a_unit) + { + if (usec == a_unit->usec) nb++; + a_unit = a_unit->next; + } + if (nb > 0) printf ("> date (usec) %ld found %d times in journal\n", usec, nb); + else printf ("> date (usec) %ld not found in journal\n", usec); +} diff --git a/src/fsm/log/manager.c b/src/fsm/log/manager.c new file mode 100644 index 0000000..334fdae --- /dev/null +++ b/src/fsm/log/manager.c @@ -0,0 +1,104 @@ +/** + * @file + * @brief fsm (Finite State Machine) log manager + * + * This file is part of Gem-graph. + * + * @details + * The log (journal) is created, edited and published from here. + * This file contains only (1) the static fsm_log_struct gg_logs + * and (2) the function fsm_add_log() that all calls must pass through to send a + * message to the log. + * + * @cond LICENSE + * Copyright © 2021 Libre en Communs + * Copyright © 2021-2024 Adrien Bourmault + * Copyright © 2021-2024 Jean Sirmai + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * @endcond + */ + +#include "../../../include/fsm.h" + + +/******************************************************************************* + * L O G / J O U R N A L * +*******************************************************************************/ + +/** + * The fsm_struct_journal (gg_logs) is a static instance in the file + * /src/fsm/log/manager.c + * Therefore, all the functions that read or write it are in this file. + * This helps to avoid uncontrolled operations. + */ +static fsm_log_struct gg_logs; + + +/** + * @brief It is mandatory for any event to call this function to be published in + * the journal. + * + * @details The fsm_struct_journal (gg_logs) is a static instance in the file + * /src/fsm/log/manager.c + * Therefore, all the functions that read or write it will be in this file. + * This is to avoid uncontrolled operations on it. + * + * A message is send to the log for each documented event. + * + * If there are too many events, one or several filters can be applied + * here (and only here) before publication, to select only some events + * of interest (during debugging, for example). + * + * These filters can operate on any the following five parameters: + * severity, source, file_source (text), function_source (text), + * string_value (text). + * + * They can be combined using any logical operators and parentheses. + * + * @since 2024-08 + * + * @callgraph + * @see fsm_add_log_event() + * + * @callergraph + * see fsm_init() + * + * @param severity: one of the following pre-defined values + * + * FATAL - ERROR - WARN - INFO - DEBUG - TRACE + * + * @param source: a pre-defined value (a name of a structure) that can be + * associated to each event. It can be set to 'NULL'. + * + * @param *file_source the name of the file that emits the event + * @param *function_source the function that emits the event + * @param *string_value any value that better specifies the event + * + * @see fsm_enum_log_severity + * @see fsm_enum_log_source + */ +void fsm_add_log (int severity, + int source, + const char *file_source, + const char *function_source, + const char *string_value) +{ + if + ( + severity < TRACE + // && source == RULE_CONDITION + ) + fsm_add_log_event (&gg_logs, file_source, function_source, string_value); +} diff --git a/src/fsm/log/oper.c b/src/fsm/log/oper.c new file mode 100644 index 0000000..4b4b295 --- /dev/null +++ b/src/fsm/log/oper.c @@ -0,0 +1,153 @@ +/** + * @file + * + * This file is part of Gem-graph. + * + * The log (journal) stores chronologically the events during a session. + * + * This file contains the executive functions needed to init the log, add an + * event and publish the log. + * + * The log presentation is: + * [date - rank - source file - source function - value] + * + * Today, the log is simply printed in the console using glib/g_message(); + * It will be printed in chronological order in a file. + * + * @cond LICENSE + * Copyright © 2021 Libre en Communs + * Copyright © 2021-2024 Adrien Bourmault + * Copyright © 2021-2024 Jean Sirmai + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * @endcond + */ + + +#include +#include +#include +#include +#include +#include "../../../include/fsm.h" + + +/** + * init the log: a double chained list + * + * first and last records are set to NULL + * + * @since 2024-09 + * + * @param *jj + */ +void fsm_init_log (fsm_log_struct *jj) +{ + jj->first = NULL; + jj->last = NULL; +} + + +/** + * removes all the log content and free each unit + * + * @since 2024-09 + * + * @param *jj + */ +void fsm_clear_log (fsm_log_struct *jj) +{ + fsm_log_struct_unit *tmp; + fsm_log_struct_unit *a_unit = jj->first; + while(a_unit) + { + tmp = a_unit; + a_unit = a_unit->next; + free (tmp); + } + jj->first = NULL; + jj->last = NULL; +} + + +/** + * add an event + * + * *new_unit = malloc (sizeof(fsm_log_struct_unit)); + * + * warn: is never free (as new log units are never removed) + * + * @since 2024-09 + * + * @param *jj + * @param *file_source + * @param *function_source + * @param *string_value + */ +void fsm_add_log_event (fsm_log_struct *jj, + const char *file_source, + const char *function_source, + const char *string_value) +{ + struct timeval tv; + gettimeofday (&tv, NULL); + fsm_log_struct_unit *new_unit = malloc (sizeof(fsm_log_struct_unit)); + if (! new_unit) exit (EXIT_FAILURE); + + new_unit->yy_dd_mm = tv.tv_sec; + new_unit->usec = tv.tv_usec; + new_unit->file_source = file_source; + new_unit->function_source = function_source; + new_unit->string_value = string_value; + + new_unit->next = jj->first; + new_unit->prev = NULL; + if (jj->first) jj->first->prev = new_unit; + else jj->last = new_unit; + jj->first = new_unit; +} + + +#define LOG_MAX_LENGTH 255 /**< arbitrary */ + +/** + * publish all the logs chronologically (using the g_lib function: g_message) + * + * today, simply printed in the console; TODO: print in a file + * + * @since 2024-09 + * + * @param *jj + */ +void fsm_publish_log (fsm_log_struct jj) +{ + fsm_log_struct_unit *a_unit = jj.last; + char buf [LOG_MAX_LENGTH]; + int nb = 0; + while (a_unit) + { + strftime(buf, sizeof(buf), "%D %T", localtime(&a_unit->yy_dd_mm)); + g_message ("%s + %-6ld %6d %-32s %-38s %-50s", + buf, + a_unit->usec, + nb, + a_unit->file_source, + a_unit->function_source, + a_unit->string_value); + a_unit = a_unit->prev; + nb ++; + } +} + +