/src/fsm/log/* adds the three files:

- manager.c,
- oper.c and
- appendix.c

and the functions needed to init, edit and publish the log.

fsm_add_log() is in manager.c  There are the filters.

init(), add(), publish() are in oper.c
                   These are the executive functions.

and functions whose usefulness remains to be demonstrated
are in appendix.

In fsm.h remain the structures (fsm_log_struct, fsm_log_struct_unit)
and the two enums (severity and source)
This commit is contained in:
Jean Sirmai 2024-11-08 16:41:18 +01:00
parent d9b398c3b0
commit 55a43c7861
Signed by: jean
GPG Key ID: FB3115C340E057E3
4 changed files with 415 additions and 102 deletions

View File

@ -1,58 +1,32 @@
/** /**
* @file * @file
* FSM (Finite State Machine) header * Fsm (finite state machine) header
* *
* This file is part of Gem-graph. * This file is part of Gem-graph.
* *
* @cond LICENSE
* Copyright © 2021 Libre en Communs <contact@a-lec.org>
* Copyright © 2021-2024 Adrien Bourmault <neox@a-lec.org>
* Copyright © 2021-2024 Jean Sirmai <jean@a-lec.org>
* *
* This program is free software: you can redistribute it and/or modify it under * This commit introduces the functions that the log needs.
* the terms of the GNU Affero General Public License as published by the Free * @see readme.docs and this text below.
* Software Foundation, eisrc/log/ther 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 <http://www.gnu.org/licenses/>.
* @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. * 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 * All functions are now in dedicated files.
* 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. * 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 * 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 * All events sent to the log must pass through this function, which allows them
* to be filtered before being published in the log. * to be filtered before being published in the log.
* *
* ---
*
* Here's how the procedure works. * Here's how the procedure works.
* A message is send to the fsm_add_log() function for each documented event. * 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 * 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. * 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() * The four mandatory executive functions that the log needs to init, add and
* - fsm_log_struct_unit() * publish are in the dedicated file: /src/fsm/log/oper.c:
* .
* *
* - fsm_enum_log_severity() * NB: fsm_clear_log() is designed to close what was initiated by fsm_init_log().
* - fsm_enum_log_source() * 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_init_log()
* - fsm_publish_log() * - fsm_publish_log()
* - fsm_clear_log() * - fsm_clear_log()
* - fsm_add_log_event() * - 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_get_log_length()
* - fsm_seek_log() * - fsm_seek_log()
* - fsm_remove_log() * - fsm_remove_log()
* . * .
* *
* - fsm_add_log() *
* . * @cond LICENSE
* Copyright © 2021 Libre en Communs <contact@a-lec.org>
* Copyright © 2021-2024 Adrien Bourmault <neox@a-lec.org>
* Copyright © 2021-2024 Jean Sirmai <jean@a-lec.org>
*
* 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 <http://www.gnu.org/licenses/>.
* @endcond
*/ */
@ -243,61 +238,10 @@ long fsm_remove_log (fsm_log_struct *jj,
const char *function_source, const char *function_source,
const char *string_value); 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, void fsm_add_log (int severity,
int source, int source,
const char *file_source, const char *file_source,
const char *function_source, const char *function_source,
const char *string_value); const char *string_value);

112
src/fsm/log/appendix.c Normal file
View File

@ -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 <contact@a-lec.org>
* Copyright © 2021-2024 Adrien Bourmault <neox@a-lec.org>
* Copyright © 2021-2024 Jean Sirmai <jean@a-lec.org>
*
* 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 <http://www.gnu.org/licenses/>.
* @endcond
*/
#include <stdio.h>
#include <stdlib.h>
#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);
}

104
src/fsm/log/manager.c Normal file
View File

@ -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 <contact@a-lec.org>
* Copyright © 2021-2024 Adrien Bourmault <neox@a-lec.org>
* Copyright © 2021-2024 Jean Sirmai <jean@a-lec.org>
*
* 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 <http://www.gnu.org/licenses/>.
* @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);
}

153
src/fsm/log/oper.c Normal file
View File

@ -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 <contact@a-lec.org>
* Copyright © 2021-2024 Adrien Bourmault <neox@a-lec.org>
* Copyright © 2021-2024 Jean Sirmai <jean@a-lec.org>
*
* 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 <http://www.gnu.org/licenses/>.
* @endcond
*/
#include <time.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#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 ++;
}
}