version 1.3, 2025/03/09 15:20:18
|
version 1.10, 2025/04/15 14:39:06
|
Line 1
|
Line 1
|
/* |
/* |
* * |
* $Id$ |
* * * |
* freem error logging |
* * * |
|
* *************** |
|
* * * * * |
|
* * MUMPS * |
|
* * * * * |
|
* *************** |
|
* * * |
|
* * * |
|
* * |
|
* |
|
* log.c |
|
* freem error logging |
|
* |
* |
* |
* |
* Author: Serena Willis <snw@coherent-logic.com> |
* Author: Serena Willis <snw@coherent-logic.com> |
* Copyright (C) 1998 MUG Deutschland |
* Copyright (C) 1998 MUG Deutschland |
* Copyright (C) 2020 Coherent Logic Development LLC |
* Copyright (C) 2020, 2025 Coherent Logic Development LLC |
* |
* |
* |
* |
* This file is part of FreeM. |
* This file is part of FreeM. |
Line 35
|
Line 23
|
* You should have received a copy of the GNU Affero Public License |
* You should have received a copy of the GNU Affero Public License |
* along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
* along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
* |
* |
|
* $Log$ |
|
* Revision 1.10 2025/04/15 14:39:06 snw |
|
* Further improvements to logging |
|
* |
|
* Revision 1.9 2025/04/15 02:24:43 snw |
|
* Improve FreeM logging capabilities |
|
* |
|
* Revision 1.8 2025/04/04 02:12:25 snw |
|
* Bump to 0.63.0-rc5 and make sure m_log function is never empty |
|
* |
|
* Revision 1.7 2025/04/04 01:18:21 snw |
|
* Remove vestigial logging code and bump to 0.63.0-rc4 |
|
* |
|
* Revision 1.6 2025/04/01 23:21:45 snw |
|
* fmadm commands for stopping, starting, and restarting environments now functional |
|
* |
|
* Revision 1.5 2025/04/01 20:11:46 snw |
|
* Further work on fmadm |
|
* |
|
* Revision 1.4 2025/03/09 19:50:47 snw |
|
* Second phase of REUSE compliance and header reformat |
|
* |
|
* |
|
* SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC |
|
* SPDX-License-Identifier: AGPL-3.0-or-later |
**/ |
**/ |
|
|
#include <stdio.h> |
#include <stdio.h> |
Line 43
|
Line 56
|
# include <syslog.h> |
# include <syslog.h> |
#endif |
#endif |
#include <stdlib.h> |
#include <stdlib.h> |
|
#include <stdarg.h> |
|
|
|
#if defined(USE_SYS_TIME_H) && !defined(MSDOS) && !defined(__osf__) |
|
# include <sys/time.h> |
|
#else |
|
# include <time.h> |
|
#endif |
|
|
#include "mpsdef.h" |
#include "mpsdef.h" |
|
|
void m_log (int level, const char *msg) |
short log_threshold_file; |
|
short log_threshold_syslog; |
|
short log_threshold_stderr; |
|
|
|
|
|
void init_log(void) |
|
{ |
|
log_threshold_file = LOG_INFO; |
|
log_threshold_syslog = LOG_INFO; |
|
log_threshold_stderr = LOG_WARNING; |
|
} |
|
|
|
void log_level_to_text(int level, char *buf) |
|
{ |
|
switch (level) { |
|
|
|
case LOG_DEBUG: |
|
sprintf (buf, "DEBUG"); |
|
break; |
|
|
|
case LOG_INFO: |
|
sprintf (buf, "INFO"); |
|
break; |
|
|
|
case LOG_WARNING: |
|
sprintf (buf, "WARNING"); |
|
break; |
|
|
|
case LOG_ERROR: |
|
sprintf (buf, "ERROR"); |
|
break; |
|
|
|
case LOG_FATAL: |
|
sprintf (buf, "FATAL"); |
|
break; |
|
|
|
default: |
|
sprintf (buf, "LEVEL %d", level); |
|
break; |
|
|
|
} |
|
} |
|
|
|
void m_log(int level, const char *msg) |
{ |
{ |
|
|
|
FILE *fp; |
|
time_t unix_epoch; |
|
char timeval[255]; |
|
char filename[4096]; |
|
char lvl[20]; |
|
struct tm *logtime; |
|
|
|
log_level_to_text (level, lvl); |
|
|
|
if (level >= log_threshold_file) { |
|
snprintf (filename, sizeof (filename) - 1, "/var/log/freem/%s.log", shm_env); |
|
|
|
if ((fp = fopen (filename, "a+")) != NULL) { |
|
unix_epoch = time (0L); |
|
logtime = localtime (&unix_epoch); |
|
strftime (timeval, sizeof (timeval) - 1, "%F %T", logtime); |
|
fprintf (fp, "%s [LEVEL %s PID %ld]: %s\n", timeval, lvl, pid, 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\r\n", msg); |
|
|
|
if (level >= LOG_FATAL) { |
|
cleanup (); |
|
exit (LOG_FATAL); |
|
} |
|
|
|
return; |
|
} |
|
|
|
void logprintf(int level, char *fmt, ...) |
|
{ |
|
va_list ptr; |
|
va_start (ptr, fmt); |
|
|
|
char logmsg[BIGSTR]; |
|
char tmps[BIGSTR]; |
|
|
|
char ch; |
|
char typ; |
|
char subtyp; |
|
|
|
register int i; |
|
|
|
for (i = 0; fmt[i] != '\0'; i++) { |
|
ch = fmt[i]; |
|
|
|
switch (ch) { |
|
|
|
case '%': |
|
typ = fmt[++i]; |
|
|
|
switch (typ) { |
|
|
|
case '%': /* literal percent sign */ |
|
strcat (logmsg, "%"); |
|
break; |
|
|
|
case 'c': /* char */ |
|
sprintf (tmps, "%c", va_arg (ptr, int)); |
|
strcat (logmsg, tmps); |
|
break; |
|
|
|
case 's': /* C string */ |
|
strcat (logmsg, va_arg (ptr, char *)); |
|
break; |
|
|
|
case 'S': /* FreeM string */ |
|
stcpy (tmps, va_arg (ptr, char *)); |
|
stcnv_m2c (tmps); |
|
strcat (logmsg, tmps); |
|
break; |
|
|
|
case 'd': /* int */ |
|
sprintf (tmps, "%d", va_arg (ptr, int)); |
|
strcat (logmsg, tmps); |
|
break; |
|
|
|
case 'l': /* long... */ |
|
subtyp = fmt[++i]; |
|
switch (subtyp) { |
|
|
|
case 'd': /* long int */ |
|
sprintf (tmps, "%ld", va_arg (ptr, long)); |
|
strcat (logmsg, tmps); |
|
break; |
|
|
|
case 'f': /* float */ |
|
sprintf (tmps, "%lf", va_arg (ptr, double)); |
|
strcat (logmsg, tmps); |
|
break; |
|
|
|
} |
|
break; |
|
} |
|
|
|
case '\\': |
|
typ = fmt[++i]; |
|
switch (typ) { |
|
case 'n': |
|
sprintf (tmps, "\n"); |
|
strcat (logmsg, tmps); |
|
break; |
|
|
|
case 'r': |
|
sprintf (tmps, "\r"); |
|
strcat (logmsg, tmps); |
|
break; |
|
|
|
case 't': |
|
sprintf (tmps, "\t"); |
|
strcat (logmsg, tmps); |
|
break; |
|
|
|
case '\\': |
|
sprintf (tmps, "\\"); |
|
strcat (logmsg, tmps); |
|
break; |
|
} |
|
|
|
default: |
|
sprintf (tmps, "%c", ch); |
|
strcat (logmsg, tmps); |
|
break; |
|
} |
|
} |
|
|
|
m_log (level, logmsg); |
|
|
|
va_end (ptr); |
|
return; |
} |
} |