void formatStream();
Context *upper; ///< previous or parent record in nested debugging calls
std::ostringstream buf; ///< debugs() output sink
+ bool forceAlert; ///< the current debugs() will be a syslog ALERT
};
/// whether debugging the given section and the given level produces output
/// logs output buffer created in Start() and closes debugging context
static void Finish();
+ /// configures the active debugging context to write syslog ALERT
+ static void ForceAlert();
private:
static Context *Current; ///< deepest active context; nil outside debugs()
};
} \
} while (/*CONSTCOND*/ 0)
+/// Does not change the stream being manipulated. Exists for its side effect:
+/// In a debugs() context, forces the message to become a syslog ALERT.
+/// Outside of debugs() context, has no effect and should not be used.
+std::ostream& ForceAlert(std::ostream& s);
+
/** stream manipulator which does nothing.
* \deprecated Do not add to new code, and remove when editing old code
*
/* Legacy debug function definitions */
void _db_init(const char *logfile, const char *options);
-void _db_print(const char *,...) PRINTF_FORMAT_ARG1;
void _db_set_syslog(const char *facility);
void _db_rotate_log(void);
#ifdef LOG_LOCAL4
static int syslog_facility = 0;
#endif
-static void _db_print_syslog(const char *format, va_list args);
+static void _db_print_syslog(const bool forceAlert, const char *format, va_list args);
#endif
static void _db_print_stderr(const char *format, va_list args);
static void _db_print_file(const char *format, va_list args);
assert(!file_ == !name);
}
+static
void
-_db_print(const char *format,...)
+_db_print(const bool forceAlert, const char *format,...)
{
char f[BUFSIZ];
f[0]='\0';
_db_print_stderr(f, args2);
#if HAVE_SYSLOG
- _db_print_syslog(format, args3);
+ _db_print_syslog(forceAlert, format, args3);
#endif
#if _SQUID_WINDOWS_
#if HAVE_SYSLOG
static void
-_db_print_syslog(const char *format, va_list args)
+_db_print_syslog(const bool forceAlert, const char *format, va_list args)
{
/* level 0,1 go to syslog */
- if (Debug::Level() > 1)
- return;
+ if (!forceAlert) {
+ if (Debug::Level() > 1)
+ return;
- if (!Debug::log_syslog)
- return;
+ if (!Debug::log_syslog)
+ return;
+ }
char tmpbuf[BUFSIZ];
tmpbuf[0] = '\0';
tmpbuf[BUFSIZ - 1] = '\0';
- syslog(Debug::Level() == 0 ? LOG_WARNING : LOG_NOTICE, "%s", tmpbuf);
+ syslog(forceAlert ? LOG_ALERT : (Debug::Level() == 0 ? LOG_WARNING : LOG_NOTICE), "%s", tmpbuf);
}
#endif /* HAVE_SYSLOG */
if (Ctx_Valid_Level < Ctx_Reported_Level) {
if (Ctx_Reported_Level != Ctx_Valid_Level + 1)
- _db_print("ctx: exit levels from %2d down to %2d\n",
+ _db_print(false, "ctx: exit levels from %2d down to %2d\n",
Ctx_Reported_Level, Ctx_Valid_Level + 1);
else
- _db_print("ctx: exit level %2d\n", Ctx_Reported_Level);
+ _db_print(false, "ctx: exit level %2d\n", Ctx_Reported_Level);
Ctx_Reported_Level = Ctx_Valid_Level;
}
while (Ctx_Reported_Level < Ctx_Current_Level) {
++Ctx_Reported_Level;
++Ctx_Valid_Level;
- _db_print("ctx: enter level %2d: '%s'\n", Ctx_Reported_Level,
+ _db_print(false, "ctx: enter level %2d: '%s'\n", Ctx_Reported_Level,
ctx_get_descr(Ctx_Reported_Level));
}
Debug::Context::Context(const int aSection, const int aLevel):
level(aLevel),
sectionLevel(Levels[aSection]),
- upper(Current)
+ upper(Current),
+ forceAlert(false)
{
formatStream();
}
Debug::Finish()
{
// TODO: Optimize to remove at least one extra copy.
- _db_print("%s\n", Current->buf.str().c_str());
+ _db_print(Current->forceAlert, "%s\n", Current->buf.str().c_str());
+ Current->forceAlert = false;
Context *past = Current;
Current = past->upper;
// else it was a static topContext from Debug::Start()
}
+void
+Debug::ForceAlert()
+{
+ // the ForceAlert(ostream) manipulator should only be used inside debugs()
+ if (Current)
+ Current->forceAlert = true;
+}
+
+std::ostream&
+ForceAlert(std::ostream& s)
+{
+ Debug::ForceAlert();
+ return s;
+}
+
/// print data bytes using hex notation
void
Raw::printHex(std::ostream &os) const
static void
fatal_common(const char *message)
{
-#if HAVE_SYSLOG
- syslog(LOG_ALERT, "%s", message);
-#endif
-
- fprintf(debug_log, "FATAL: %s\n", message);
-
- if (Debug::log_stderr > 0 && debug_log != stderr)
- fprintf(stderr, "FATAL: %s\n", message);
-
- fprintf(debug_log, "Squid Cache (Version %s): Terminated abnormally.\n",
- version_string);
-
- fflush(debug_log);
+ debugs(1, DBG_CRITICAL, ForceAlert << "FATAL: " << message);
+ debugs(1, DBG_CRITICAL, "Squid Cache (Version " << version_string << "): Terminated abnormally.");
PrintRusage();
death(int sig)
{
if (sig == SIGSEGV)
- fprintf(debug_log, "FATAL: Received Segment Violation...dying.\n");
+ debugs(1, DBG_CRITICAL, ForceAlert << "FATAL: Received Segment Violation...dying.");
else if (sig == SIGBUS)
- fprintf(debug_log, "FATAL: Received Bus Error...dying.\n");
+ debugs(1, DBG_CRITICAL, ForceAlert << "FATAL: Received Bus Error...dying.");
else
- fprintf(debug_log, "FATAL: Received signal %d...dying.\n", sig);
+ debugs(1, DBG_CRITICAL, ForceAlert << "FATAL: Received signal " << sig << "...dying.");
#if PRINT_STACK_TRACE
#if _SQUID_HPUX_
if (!opt_catch_signals)
fatal_dump(message);
- _db_print("WARNING: %s\n", message);
+ debugs(50, DBG_CRITICAL, "WARNING: " << message);
}
const char *