version 1.9, 2025/04/15 02:24:43
|
version 1.13, 2025/04/16 17:36:12
|
Line 24
|
Line 24
|
* along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
* along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
* |
* |
* $Log$ |
* $Log$ |
|
* Revision 1.13 2025/04/16 17:36:12 snw |
|
* Add FreeBSD shm cleanup script |
|
* |
|
* Revision 1.12 2025/04/15 16:49:36 snw |
|
* Make use of logprintf throughout codebase |
|
* |
|
* Revision 1.11 2025/04/15 14:56:20 snw |
|
* Fix broken build due to missing declarations |
|
* |
|
* Revision 1.10 2025/04/15 14:39:06 snw |
|
* Further improvements to logging |
|
* |
* Revision 1.9 2025/04/15 02:24:43 snw |
* Revision 1.9 2025/04/15 02:24:43 snw |
* Improve FreeM logging capabilities |
* Improve FreeM logging capabilities |
* |
* |
Line 54
|
Line 66
|
#endif |
#endif |
#include <stdlib.h> |
#include <stdlib.h> |
#include <stdarg.h> |
#include <stdarg.h> |
|
#include <unistd.h> |
|
|
#if defined(USE_SYS_TIME_H) && !defined(MSDOS) && !defined(__osf__) |
#if defined(USE_SYS_TIME_H) && !defined(MSDOS) && !defined(__osf__) |
# include <sys/time.h> |
# include <sys/time.h> |
Line 62
|
Line 75
|
#endif |
#endif |
|
|
#include "mpsdef.h" |
#include "mpsdef.h" |
|
#include "log.h" /* for logging constants */ |
|
#include "init.h" /* for cleanup() */ |
|
#include "iniconf.h" /* for read_profile_string() */ |
|
|
|
short log_threshold_file; |
|
short log_threshold_syslog; |
|
short log_threshold_stderr; |
|
|
|
|
|
void init_log(void) |
|
{ |
|
char buf[4096]; |
|
char *env_value; |
|
|
|
if (read_profile_string (env_config_file, shm_env, "log_threshold_file", buf) == TRUE) { |
|
if (strcmp (buf, "debug") == 0) { |
|
log_threshold_file = FM_LOG_DEBUG; |
|
} |
|
else if (strcmp (buf, "info") == 0) { |
|
log_threshold_file = FM_LOG_INFO; |
|
} |
|
else if (strcmp (buf, "warning") == 0) { |
|
log_threshold_file = FM_LOG_WARNING; |
|
} |
|
else if (strcmp (buf, "error") == 0) { |
|
log_threshold_file = FM_LOG_ERROR; |
|
} |
|
else if (strcmp (buf, "fatal") == 0) { |
|
log_threshold_file = FM_LOG_FATAL; |
|
} |
|
else { |
|
log_threshold_file = FM_LOG_INFO; |
|
} |
|
} |
|
else { |
|
log_threshold_file = FM_LOG_INFO; |
|
} |
|
|
|
if (read_profile_string (env_config_file, shm_env, "log_threshold_syslog", buf) == TRUE) { |
|
if (strcmp (buf, "debug") == 0) { |
|
log_threshold_syslog = FM_LOG_DEBUG; |
|
} |
|
else if (strcmp (buf, "info") == 0) { |
|
log_threshold_syslog = FM_LOG_INFO; |
|
} |
|
else if (strcmp (buf, "warning") == 0) { |
|
log_threshold_syslog = FM_LOG_WARNING; |
|
} |
|
else if (strcmp (buf, "error") == 0) { |
|
log_threshold_syslog = FM_LOG_ERROR; |
|
} |
|
else if (strcmp (buf, "fatal") == 0) { |
|
log_threshold_syslog = FM_LOG_FATAL; |
|
} |
|
else { |
|
log_threshold_syslog = FM_LOG_INFO; |
|
} |
|
} |
|
else { |
|
log_threshold_syslog = FM_LOG_INFO; |
|
} |
|
|
|
if (read_profile_string (env_config_file, shm_env, "log_threshold_stderr", buf) == TRUE) { |
|
if (strcmp (buf, "debug") == 0) { |
|
log_threshold_stderr = FM_LOG_DEBUG; |
|
} |
|
else if (strcmp (buf, "info") == 0) { |
|
log_threshold_stderr = FM_LOG_INFO; |
|
} |
|
else if (strcmp (buf, "warning") == 0) { |
|
log_threshold_stderr = FM_LOG_WARNING; |
|
} |
|
else if (strcmp (buf, "error") == 0) { |
|
log_threshold_stderr = FM_LOG_ERROR; |
|
} |
|
else if (strcmp (buf, "fatal") == 0) { |
|
log_threshold_stderr = FM_LOG_FATAL; |
|
} |
|
else { |
|
log_threshold_stderr = FM_LOG_INFO; |
|
} |
|
} |
|
else { |
|
log_threshold_stderr = FM_LOG_WARNING; |
|
} |
|
|
|
if ((env_value = getenv ("FREEM_LOG_THRESHOLD_FILE")) != NULL) { |
|
if (strcmp (env_value, "debug") == 0) { |
|
log_threshold_file = FM_LOG_DEBUG; |
|
} |
|
else if (strcmp (env_value, "info") == 0) { |
|
log_threshold_file = FM_LOG_INFO; |
|
} |
|
else if (strcmp (env_value, "warning") == 0) { |
|
log_threshold_file = FM_LOG_WARNING; |
|
} |
|
else if (strcmp (env_value, "error") == 0) { |
|
log_threshold_file = FM_LOG_ERROR; |
|
} |
|
else if (strcmp (env_value, "fatal") == 0) { |
|
log_threshold_file = FM_LOG_FATAL; |
|
} |
|
else { |
|
log_threshold_file = FM_LOG_INFO; |
|
} |
|
} |
|
|
|
if ((env_value = getenv ("FREEM_LOG_THRESHOLD_SYSLOG")) != NULL) { |
|
if (strcmp (env_value, "debug") == 0) { |
|
log_threshold_syslog = FM_LOG_DEBUG; |
|
} |
|
else if (strcmp (env_value, "info") == 0) { |
|
log_threshold_syslog = FM_LOG_INFO; |
|
} |
|
else if (strcmp (env_value, "warning") == 0) { |
|
log_threshold_syslog = FM_LOG_WARNING; |
|
} |
|
else if (strcmp (env_value, "error") == 0) { |
|
log_threshold_syslog = FM_LOG_ERROR; |
|
} |
|
else if (strcmp (env_value, "fatal") == 0) { |
|
log_threshold_syslog = FM_LOG_FATAL; |
|
} |
|
else { |
|
log_threshold_syslog = FM_LOG_INFO; |
|
} |
|
} |
|
|
|
if ((env_value = getenv ("FREEM_LOG_THRESHOLD_STDERR")) != NULL) { |
|
if (strcmp (env_value, "debug") == 0) { |
|
log_threshold_stderr = FM_LOG_DEBUG; |
|
} |
|
else if (strcmp (env_value, "info") == 0) { |
|
log_threshold_stderr = FM_LOG_INFO; |
|
} |
|
else if (strcmp (env_value, "warning") == 0) { |
|
log_threshold_stderr = FM_LOG_WARNING; |
|
} |
|
else if (strcmp (env_value, "error") == 0) { |
|
log_threshold_stderr = FM_LOG_ERROR; |
|
} |
|
else if (strcmp (env_value, "fatal") == 0) { |
|
log_threshold_stderr = FM_LOG_FATAL; |
|
} |
|
else { |
|
log_threshold_stderr = FM_LOG_INFO; |
|
} |
|
} |
|
|
|
|
|
|
|
} |
|
|
|
void log_level_to_text(int level, char *buf) |
|
{ |
|
switch (level) { |
|
|
|
case FM_LOG_DEBUG: |
|
sprintf (buf, "DEBUG"); |
|
break; |
|
|
|
case FM_LOG_INFO: |
|
sprintf (buf, "INFO"); |
|
break; |
|
|
|
case FM_LOG_WARNING: |
|
sprintf (buf, "WARNING"); |
|
break; |
|
|
|
case FM_LOG_ERROR: |
|
sprintf (buf, "ERROR"); |
|
break; |
|
|
|
case FM_LOG_FATAL: |
|
sprintf (buf, "FATAL"); |
|
break; |
|
|
|
default: |
|
sprintf (buf, "LEVEL %d", level); |
|
break; |
|
|
|
} |
|
} |
|
|
void m_log (int level, const char *msg) |
void m_log(int level, const char *msg) |
{ |
{ |
|
|
FILE *fp; |
FILE *fp; |
time_t unix_epoch; |
time_t unix_epoch; |
char timeval[255]; |
char timeval[255]; |
char filename[4096]; |
char filename[4096]; |
|
char lvl[20]; |
struct tm *logtime; |
struct tm *logtime; |
|
|
snprintf (filename, sizeof (filename) - 1, "/var/log/freem/%s.log", shm_env); |
log_level_to_text (level, lvl); |
|
|
if ((fp = fopen (filename, "a+")) != NULL) { |
if (level >= log_threshold_file) { |
unix_epoch = time (0L); |
snprintf (filename, sizeof (filename) - 1, "/var/log/freem/%s.log", shm_env); |
logtime = localtime (&unix_epoch); |
|
strftime (timeval, sizeof (timeval) - 1, "%F %T", logtime); |
if ((fp = fopen (filename, "a+")) != NULL) { |
fprintf (fp, "%s [LEVEL %d PID %ld]: %s\n", timeval, level, pid, msg); |
unix_epoch = time (0L); |
fclose (fp); |
logtime = localtime (&unix_epoch); |
|
strftime (timeval, sizeof (timeval) - 1, "%F %T", logtime); |
|
fprintf (fp, "%s [LEVEL %s PID %ld]: %s\n", timeval, lvl, getpid (), msg); |
|
fclose (fp); |
|
} |
} |
} |
|
|
#if defined(__linux__) | defined(__FreeBSD__) | defined(__sun__) |
#if defined(__linux__) | defined(__FreeBSD__) | defined(__sun__) |
syslog (level, "%s", msg); |
if (level >= log_threshold_syslog) { |
|
syslog (level, "%s", msg); |
|
} |
#endif |
#endif |
|
|
|
if (level >= log_threshold_stderr) fprintf (stderr, "%s [%s]\r\n", msg, lvl); |
|
|
|
if (level >= FM_LOG_FATAL) { |
|
cleanup (); |
|
exit (FM_LOG_FATAL); |
|
} |
|
|
return; |
return; |
|
|
} |
} |
|
|
|
|
void logprintf(int level, char *fmt, ...) |
void logprintf(int level, char *fmt, ...) |
{ |
{ |
va_list ptr; |
va_list ptr; |
Line 106 void logprintf(int level, char *fmt, ...
|
Line 313 void logprintf(int level, char *fmt, ...
|
|
|
register int i; |
register int i; |
|
|
|
logmsg[0] = '\0'; |
|
|
for (i = 0; fmt[i] != '\0'; i++) { |
for (i = 0; fmt[i] != '\0'; i++) { |
ch = fmt[i]; |
ch = fmt[i]; |
|
|
|
tmps[0] = '\0'; |
|
|
switch (ch) { |
switch (ch) { |
|
|
case '%': |
case '%': |
Line 118 void logprintf(int level, char *fmt, ...
|
Line 329 void logprintf(int level, char *fmt, ...
|
|
|
case '%': /* literal percent sign */ |
case '%': /* literal percent sign */ |
strcat (logmsg, "%"); |
strcat (logmsg, "%"); |
break; |
continue; |
|
|
case 'c': /* char */ |
case 'c': /* char */ |
sprintf (tmps, "%c", va_arg (ptr, int)); |
sprintf (tmps, "%c", va_arg (ptr, int)); |
strcat (logmsg, tmps); |
strcat (logmsg, tmps); |
break; |
continue; |
|
|
case 's': /* C string */ |
case 's': /* C string */ |
strcat (logmsg, va_arg (ptr, char *)); |
strcat (logmsg, va_arg (ptr, char *)); |
break; |
continue; |
|
|
case 'S': /* FreeM string */ |
case 'S': /* FreeM string */ |
stcpy (tmps, va_arg (ptr, char *)); |
stcpy (tmps, va_arg (ptr, char *)); |
stcnv_m2c (tmps); |
stcnv_m2c (tmps); |
strcat (logmsg, tmps); |
strcat (logmsg, tmps); |
break; |
continue; |
|
|
case 'd': /* int */ |
case 'd': /* int */ |
sprintf (tmps, "%d", va_arg (ptr, int)); |
sprintf (tmps, "%d", va_arg (ptr, int)); |
strcat (logmsg, tmps); |
strcat (logmsg, tmps); |
break; |
continue; |
|
|
|
case 'p': /* pointer */ |
|
sprintf (tmps, "%p", va_arg (ptr, void *)); |
|
strcat (logmsg, tmps); |
|
continue; |
|
|
case 'l': /* long... */ |
case 'l': /* long... */ |
subtyp = fmt[++i]; |
subtyp = fmt[++i]; |
switch (subtyp) { |
switch (subtyp) { |
Line 147 void logprintf(int level, char *fmt, ...
|
Line 363 void logprintf(int level, char *fmt, ...
|
case 'd': /* long int */ |
case 'd': /* long int */ |
sprintf (tmps, "%ld", va_arg (ptr, long)); |
sprintf (tmps, "%ld", va_arg (ptr, long)); |
strcat (logmsg, tmps); |
strcat (logmsg, tmps); |
break; |
continue; |
|
|
case 'f': /* float */ |
case 'f': /* float */ |
sprintf (tmps, "%lf", va_arg (ptr, double)); |
sprintf (tmps, "%lf", va_arg (ptr, double)); |
strcat (logmsg, tmps); |
strcat (logmsg, tmps); |
break; |
continue; |
|
|
} |
} |
break; |
continue; |
} |
} |
|
|
case '\\': |
case '\\': |
Line 164 void logprintf(int level, char *fmt, ...
|
Line 380 void logprintf(int level, char *fmt, ...
|
case 'n': |
case 'n': |
sprintf (tmps, "\n"); |
sprintf (tmps, "\n"); |
strcat (logmsg, tmps); |
strcat (logmsg, tmps); |
break; |
continue; |
|
|
case 'r': |
case 'r': |
sprintf (tmps, "\r"); |
sprintf (tmps, "\r"); |
strcat (logmsg, tmps); |
strcat (logmsg, tmps); |
break; |
continue; |
|
|
case 't': |
case 't': |
sprintf (tmps, "\t"); |
sprintf (tmps, "\t"); |
strcat (logmsg, tmps); |
strcat (logmsg, tmps); |
break; |
continue; |
|
|
case '\\': |
case '\\': |
sprintf (tmps, "\\"); |
sprintf (tmps, "\\"); |
strcat (logmsg, tmps); |
strcat (logmsg, tmps); |
break; |
continue; |
} |
} |
|
|
default: |
default: |