/* debug.c * * vim:smartindent ts=8:sts=2:sta:et:ai:shiftwidth=2 **************************************************************** * Copyright (C) 2005 Canonical Limited * Authors: Robert Collins * * See the file "COPYING" for further information about * the copyright and warranty status of this work. * * The bulk of this file was extracted from squid. The original * copyright statement follows. * * DEBUG: section 0 Debug Routines * AUTHOR: Harvest Derived * * SQUID Web Proxy Cache http://www.squid-cache.org/ * ---------------------------------------------------------- * * Squid is the result of efforts by numerous individuals from * the Internet community; see the CONTRIBUTORS file for full * details. Many organizations have provided support for Squid's * development; see the SPONSORS file for full details. Squid is * Copyrighted (C) 2001 by the Regents of the University of * California; see the COPYRIGHT file for full details. Squid * incorporates software developed and/or copyrighted by other * sources; see the CREDITS file for full details. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */ #include "config-options.h" #include "po/gettext.h" #include "hackerlab/bugs/panic.h" #include "hackerlab/os/stdarg.h" #include "hackerlab/os/errno-to-string.h" #include "hackerlab/char/str.h" #include "hackerlab/vu/safe.h" #include "hackerlab/vu/safe-printfmt.h" #include "libdate/date-string.h" #include "libarch/debug.h" /** * \broef an array of debug sections, and the verbosity level * of that section. * you can think of this as a chattiness level: * the higher the number, the more detail is show */ int arch_debug_levels[MAX_DEBUG_SECTIONS]; /** * \brief the debug level for the current message being output */ int arch_debug_level; static char *debug_log_file = NULL; static int debug_log = -1; //static const char *debugLogTime(time_t); static void _db_print_stderr(const char *format, va_list args); static void _db_print_file(const char *format, va_list args); static void arch_db_init(const char *logfile, const char *options); /* what debug level stdout should be capped at. * levels about this will only go to file by default */ int opt_debug_stderr = 1; #define BUFSIZ 4096 void arch_db_print(const char *format,...) { /* disabled for now */ #if enableme t_uchar *datestr; #endif va_list args1; va_list args2; va_start(args1, format); va_start(args2, format); #if enableme datestr = pretty_date (curtime()); safe_printfmt (2, ); snprintf(f, BUFSIZ, "%s| %s", debugLogTime(squid_curtime), format); #endif /* Add other debug targets here */ _db_print_file(format, args1); _db_print_stderr(format, args2); va_end(args1); va_end(args2); #if enableme lim_free (0, datestr); #endif } static void _db_print_file(const char *format, va_list args) { if (debug_log < 0) return; /* 2 == stderr */ if (debug_log == 2) return; safe_printfmt_va_list(debug_log, format, args); safe_flush(debug_log); } static void _db_print_stderr(const char *format, va_list args) { if (opt_debug_stderr < arch_debug_level) return; safe_printfmt_va_list (2, format, args); } static void debugArg(const char *arg) { int s = 0; int l = 0; int i; if (!str_casecmp_n(arg, 3, "ALL", 3)) { s = -1; arg += 4; } else { s = atoi(arg); while (*arg && *arg++ != ','); } l = atoi(arg); invariant(s >= -1); invariant(s < MAX_DEBUG_SECTIONS); if (l < 0) l = 0; if (l > 10) l = 10; if (s >= 0) { arch_debug_levels[s] = l; return; } for (i = 0; i < MAX_DEBUG_SECTIONS; i++) arch_debug_levels[i] = l; } static void debugOpenLog(const char *logfile) { int errn; if (logfile == NULL) { debug_log = 2; return; } /* keep a local copy */ debug_log_file = str_replace (debug_log_file, str_save (0, logfile)); if (debug_log > -1 && debug_log != 2) safe_close(debug_log); debug_log = vu_open(&errn, (t_uchar *)logfile, O_CREAT| O_APPEND | O_WRONLY, 0666); if (debug_log < 0) { safe_printfmt(2, "WARNING: Cannot write log file: %s\n", logfile); safe_printfmt(2, "%s\n", errno_to_string (errn)); safe_printfmt(2, " messages will be sent to 'stderr'.\n"); safe_flush(2); debug_log = 2; } } #define w_space " \t" void arch_db_init(const char *logfile, const char *options) { int i; char *p = NULL; t_uchar *s = NULL; for (i = 0; i < MAX_DEBUG_SECTIONS; i++) arch_debug_levels[i] = -1; if (options) { t_uchar * cur; p = str_save (0, options); s = p; for (cur = str_separate(&s, w_space); cur; cur = str_separate(&s, w_space)) debugArg(cur); lim_free(0, p); } else { /* defaults */ debugArg ("ALL,1"); } debugOpenLog(logfile); } extern char ** environ; /** * \brief setup debug logging * magic config routine */ void arch_debug_init() { char *options = NULL; char *file = NULL; int x; for (x = 0; environ[x]; ++x) { if (!str_cmp_prefix ("ARCH_DEBUG_OPTIONS=", environ[x])) options = str_chr_index (environ [x], '=') + 1; else if (!str_cmp_prefix ("ARCH_DEBUG_LOG=", environ[x])) { file = str_chr_index (environ [x], '=') + 1; } } arch_db_init (file, options); }