Atrinik Server 2.5
server/logger.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00039 #include <stdarg.h>
00040 #include <global.h>
00041 
00044 static const char *const loglevel_names[] =
00045 {
00046     "[System] ",
00047     "[Error]  ",
00048     "[Bug]    ",
00049     "[Chat]   ",
00050     "[Info]   ",
00051     "[Debug]  "
00052 };
00053 
00056 static uint8 loglevel_name_disable = 0;
00057 
00061 static void do_print(const char *buf)
00062 {
00063     fputs(buf, logfile);
00064 
00065     /* Is logfile a custom file, and not stderr (default)? */
00066     if (logfile != stderr)
00067     {
00068         /* Log to stderr as well. */
00069         fputs(buf, stderr);
00070         /* Flush the log file. */
00071         fflush(logfile);
00072     }
00073 }
00074 
00087 void LOG(LogLevel logLevel, const char *format, ...)
00088 {
00089     static int fatal_error = 0;
00090     char buf[HUGE_BUF * 2];
00091 
00092     if (logLevel <= settings.debug)
00093     {
00094         va_list ap;
00095         int written;
00096 
00097         /* If loglevel name was disabled but this is a bug or an error,
00098          * make an exception and put it onto the next line. */
00099         if (loglevel_name_disable && (logLevel == llevBug || logLevel == llevError))
00100         {
00101             loglevel_name_disable = 0;
00102             do_print("\n");
00103         }
00104 
00105         if (!loglevel_name_disable)
00106         {
00107             /* Prefix with timestamp. */
00108             if (settings.timestamp)
00109             {
00110                 snprintf(buf, sizeof(buf), "[%"FMT64U"] ", (uint64) time(NULL));
00111                 do_print(buf);
00112             }
00113 
00114             do_print(loglevel_names[logLevel]);
00115         }
00116 
00117         va_start(ap, format);
00118         written = vsnprintf(buf, sizeof(buf), format, ap);
00119         do_print(buf);
00120 
00121         if (written > 0)
00122         {
00123             /* If the last character isn't a newline, mark the next LOG
00124              * call to have the loglevel name disabled. */
00125             if (buf[written - 1] != '\n')
00126             {
00127                 loglevel_name_disable = 1;
00128             }
00129             else
00130             {
00131                 loglevel_name_disable = 0;
00132             }
00133         }
00134 
00135         va_end(ap);
00136     }
00137 
00138     if (logLevel == llevBug)
00139     {
00140         nroferrors++;
00141     }
00142 
00143     if (nroferrors > MAX_ERRORS || logLevel == llevError)
00144     {
00145         if (fatal_error == 0)
00146         {
00147             fatal_error = 1;
00148             fatal(logLevel);
00149         }
00150     }
00151 }