File:  [Coherent Logic Development] / freem / src / log.c
Revision 1.10: download - view: text, annotated - select for diffs
Tue Apr 15 14:39:06 2025 UTC (11 months, 2 weeks ago) by snw
Branches: MAIN
CVS tags: HEAD
Further improvements to logging

    1: /*
    2:  *   $Id: log.c,v 1.10 2025/04/15 14:39:06 snw Exp $
    3:  *    freem error logging
    4:  *
    5:  *  
    6:  *   Author: Serena Willis <snw@coherent-logic.com>
    7:  *    Copyright (C) 1998 MUG Deutschland
    8:  *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
    9:  *
   10:  *
   11:  *   This file is part of FreeM.
   12:  *
   13:  *   FreeM is free software: you can redistribute it and/or modify
   14:  *   it under the terms of the GNU Affero Public License as published by
   15:  *   the Free Software Foundation, either version 3 of the License, or
   16:  *   (at your option) any later version.
   17:  *
   18:  *   FreeM is distributed in the hope that it will be useful,
   19:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   20:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21:  *   GNU Affero Public License for more details.
   22:  *
   23:  *   You should have received a copy of the GNU Affero Public License
   24:  *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
   25:  *
   26:  *   $Log: log.c,v $
   27:  *   Revision 1.10  2025/04/15 14:39:06  snw
   28:  *   Further improvements to logging
   29:  *
   30:  *   Revision 1.9  2025/04/15 02:24:43  snw
   31:  *   Improve FreeM logging capabilities
   32:  *
   33:  *   Revision 1.8  2025/04/04 02:12:25  snw
   34:  *   Bump to 0.63.0-rc5 and make sure m_log function is never empty
   35:  *
   36:  *   Revision 1.7  2025/04/04 01:18:21  snw
   37:  *   Remove vestigial logging code and bump to 0.63.0-rc4
   38:  *
   39:  *   Revision 1.6  2025/04/01 23:21:45  snw
   40:  *   fmadm commands for stopping, starting, and restarting environments now functional
   41:  *
   42:  *   Revision 1.5  2025/04/01 20:11:46  snw
   43:  *   Further work on fmadm
   44:  *
   45:  *   Revision 1.4  2025/03/09 19:50:47  snw
   46:  *   Second phase of REUSE compliance and header reformat
   47:  *
   48:  *
   49:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
   50:  * SPDX-License-Identifier: AGPL-3.0-or-later
   51:  **/
   52: 
   53: #include <stdio.h>
   54: #include <string.h>
   55: #if defined(__linux__) | defined(__FreeBSD__) | defined(__sun__)
   56: # include <syslog.h>
   57: #endif
   58: #include <stdlib.h>
   59: #include <stdarg.h>
   60: 
   61: #if defined(USE_SYS_TIME_H) && !defined(MSDOS) && !defined(__osf__)
   62: # include <sys/time.h>
   63: #else
   64: # include <time.h> 
   65: #endif
   66: 
   67: #include "mpsdef.h"
   68: 
   69: short log_threshold_file;
   70: short log_threshold_syslog;
   71: short log_threshold_stderr;
   72: 
   73: 
   74: void init_log(void)
   75: {
   76:     log_threshold_file = LOG_INFO;
   77:     log_threshold_syslog = LOG_INFO;
   78:     log_threshold_stderr = LOG_WARNING;
   79: }
   80: 
   81: void log_level_to_text(int level, char *buf)
   82: {
   83:     switch (level) {
   84: 
   85:         case LOG_DEBUG:
   86:             sprintf (buf, "DEBUG");
   87:             break;
   88: 
   89:         case LOG_INFO:
   90:             sprintf (buf, "INFO");
   91:             break;
   92: 
   93:         case LOG_WARNING:
   94:             sprintf (buf, "WARNING");
   95:             break;
   96: 
   97:         case LOG_ERROR:
   98:             sprintf (buf, "ERROR");
   99:             break;
  100: 
  101:         case LOG_FATAL:
  102:             sprintf (buf, "FATAL");
  103:             break;
  104: 
  105:         default:
  106:             sprintf (buf, "LEVEL %d", level);
  107:             break;
  108: 
  109:     }
  110: }
  111: 
  112: void m_log(int level, const char *msg)
  113: {
  114: 
  115:     FILE *fp;
  116:     time_t unix_epoch;
  117:     char timeval[255];
  118:     char filename[4096];    
  119:     char lvl[20];
  120:     struct tm *logtime;
  121: 
  122:     log_level_to_text (level, lvl);
  123:     
  124:     if (level >= log_threshold_file) {
  125:         snprintf (filename, sizeof (filename) - 1, "/var/log/freem/%s.log", shm_env);
  126:         
  127:         if ((fp = fopen (filename, "a+")) != NULL) {
  128:             unix_epoch = time (0L);
  129:             logtime = localtime (&unix_epoch);
  130:             strftime (timeval, sizeof (timeval) - 1, "%F %T", logtime);
  131:             fprintf (fp, "%s [LEVEL %s PID %ld]:  %s\n", timeval, lvl, pid, msg);
  132:             fclose (fp);
  133:         }
  134:     }
  135:     
  136: #if defined(__linux__) | defined(__FreeBSD__) | defined(__sun__)
  137:     if (level >= log_threshold_syslog) {
  138:         syslog (level, "%s", msg);
  139:     }
  140: #endif
  141: 
  142:     if (level >= log_threshold_stderr) fprintf (stderr, "%s\r\n", msg);
  143: 
  144:     if (level >= LOG_FATAL) {
  145:         cleanup ();
  146:         exit (LOG_FATAL);
  147:     }
  148:     
  149:     return;    
  150: }
  151: 
  152: void logprintf(int level, char *fmt, ...)
  153: {
  154:     va_list ptr;
  155:     va_start (ptr, fmt);
  156: 
  157:     char logmsg[BIGSTR];
  158:     char tmps[BIGSTR];
  159:     
  160:     char ch;
  161:     char typ;
  162:     char subtyp;
  163: 
  164:     register int i;
  165: 
  166:     for (i = 0; fmt[i] != '\0'; i++) {
  167:         ch = fmt[i];
  168: 
  169:         switch (ch) {
  170:             
  171:             case '%':
  172:                 typ = fmt[++i];
  173: 
  174:                 switch (typ) {
  175:                     
  176:                     case '%': /* literal percent sign */
  177:                         strcat (logmsg, "%");
  178:                         break;
  179: 
  180:                     case 'c': /* char */
  181:                         sprintf (tmps, "%c", va_arg (ptr, int));
  182:                         strcat (logmsg, tmps);
  183:                         break;
  184: 
  185:                     case 's': /* C string */
  186:                         strcat (logmsg, va_arg (ptr, char *));
  187:                         break;
  188: 
  189:                     case 'S': /* FreeM string */
  190:                         stcpy (tmps, va_arg (ptr, char *));
  191:                         stcnv_m2c (tmps);
  192:                         strcat (logmsg, tmps);
  193:                         break;
  194: 
  195:                     case 'd': /* int */
  196:                         sprintf (tmps, "%d", va_arg (ptr, int));
  197:                         strcat (logmsg, tmps);
  198:                         break;
  199: 
  200:                     case 'l': /* long... */
  201:                         subtyp = fmt[++i];
  202:                         switch (subtyp) {
  203:                             
  204:                             case 'd': /* long int */
  205:                                 sprintf (tmps, "%ld", va_arg (ptr, long));
  206:                                 strcat (logmsg, tmps);
  207:                                 break;
  208: 
  209:                             case 'f': /* float */
  210:                                 sprintf (tmps, "%lf", va_arg (ptr, double));
  211:                                 strcat (logmsg, tmps);
  212:                                 break;
  213:                                 
  214:                         }
  215:                         break;
  216:                 }
  217:                 
  218:             case '\\':
  219:                 typ = fmt[++i];
  220:                 switch (typ) {
  221:                     case 'n':
  222:                         sprintf (tmps, "\n");
  223:                         strcat (logmsg, tmps);
  224:                         break;
  225:                         
  226:                     case 'r':
  227:                         sprintf (tmps, "\r");
  228:                         strcat (logmsg, tmps);
  229:                         break;
  230: 
  231:                     case 't':
  232:                         sprintf (tmps, "\t");
  233:                         strcat (logmsg, tmps);
  234:                         break;
  235:                         
  236:                     case '\\':
  237:                         sprintf (tmps, "\\");
  238:                         strcat (logmsg, tmps);
  239:                         break;
  240:                 }
  241:                 
  242:             default:
  243:                 sprintf (tmps, "%c", ch);
  244:                 strcat (logmsg, tmps);
  245:                 break;
  246:         }
  247:     }
  248: 
  249:     m_log (level, logmsg);
  250:         
  251:     va_end (ptr);
  252:     return;
  253: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>