2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section 00 Debug Routines */
12 #include "base/TextException.h"
13 #include "debug/Stream.h"
17 #include "time/gadgets.h"
26 char *Debug::debugOptions
= nullptr;
27 int Debug::override_X
= 0;
28 bool Debug::log_syslog
= false;
29 int Debug::Levels
[MAX_DEBUG_SECTIONS
];
30 char *Debug::cache_log
= nullptr;
31 int Debug::rotateNumber
= -1;
33 /// a counter related to the number of debugs() calls
34 using DebugRecordCount
= uint64_t;
38 /// Debugging module singleton.
39 static DebugModule
*Module_
= nullptr;
41 /// Explicitly configured maximum level for debugs() messages written to stderr.
42 /// debugs() messages with this (or lower) level will be written to stderr (and
43 /// possibly other channels).
44 static std::optional
<int> ExplicitStderrLevel
;
46 /// ExplicitStderrLevel preference or default: Just like with
47 /// ExplicitStderrLevel, debugs() messages with this (or lower) level will be
48 /// written to stderr (and possibly other channels), but this setting is ignored
49 /// when ExplicitStderrLevel is set. This setting is also ignored after major
50 /// problems that prevent logging of important debugs() messages (e.g., failing
51 /// to open cache_log or assertions).
52 static int DefaultStderrLevel
= -1;
54 /// early debugs() with higher level are not buffered and, hence, may be lost
55 static constexpr int EarlyMessagesLevel
= DBG_IMPORTANT
;
57 /// pre-formatted name of the current process for debugs() messages (or empty)
58 static std::string ProcessLabel
;
60 static const char *debugLogTime(const timeval
&);
64 static int syslog_facility
= 0;
69 extern LPCRITICAL_SECTION dbg_mutex
;
70 typedef BOOL (WINAPI
* PFInitializeCriticalSectionAndSpinCount
) (LPCRITICAL_SECTION
, DWORD
);
73 static void ResetSections(const int level
= DBG_IMPORTANT
);
75 /// Whether ResetSections() has been called already. We need to keep track of
76 /// this state because external code may trigger ResetSections() before the
77 /// DebugModule constructor has a chance to ResetSections() to their defaults.
78 /// TODO: Find a way to static-initialize Debug::Levels instead.
79 static bool DidResetSections
= false;
81 /// a named FILE with very-early/late usage safety mechanisms
86 ~DebugFile() { clear(); }
87 DebugFile(DebugFile
&&) = delete; // no copying or moving of any kind
89 /// switches to the new pair, absorbing FILE and duping the name
90 void reset(FILE *newFile
, const char *newName
);
92 /// go back to the initial state
93 void clear() { reset(nullptr, nullptr); }
95 /// an opened cache_log stream or nil
96 FILE *file() { return file_
; }
101 friend void ResyncDebugLog(FILE *newFile
);
103 FILE *file_
= nullptr; ///< opened "real" file or nil; never stderr
106 /// meta-information of a Finish()ed debugs() message
107 class DebugMessageHeader
110 DebugMessageHeader(const DebugRecordCount aRecordNumber
, const Debug::Context
&);
112 DebugRecordCount recordNumber
; ///< LogMessage() calls before this message
113 struct timeval timestamp
; ///< approximate debugs() call time
114 int section
; ///< debugs() section
115 int level
; ///< debugs() level
116 bool forceAlert
; ///< debugs() forceAlert flag
119 // Avoid SBuf for CompiledDebugMessageBody:
120 // * SBuf's own debugging may create a lot of reentrant debugging noise.
121 // * Debug::Context::buf is an std::string-based STL ostream. Converting its
122 // buf() result to a different kind of string may increase complexity/cost.
123 // TODO: Consider switching to a simple fixed-size buffer and a matching stream!
124 /// The processed "content" (i.e. the last parameter) part of a debugs() call.
125 using CompiledDebugMessageBody
= std::string
;
127 /// a fully processed debugs(), ready to be logged
128 class CompiledDebugMessage
131 using Header
= DebugMessageHeader
;
132 using Body
= CompiledDebugMessageBody
;
134 CompiledDebugMessage(const Header
&, const Body
&);
136 Header header
; ///< debugs() meta-information; reflected in log line prefix
137 Body body
; ///< the log line after the prefix (without the newline)
140 // We avoid PoolingAllocator for CompiledDebugMessages to minimize reentrant
141 // debugging noise. This noise reduction has negligible performance overhead
142 // because it only applied to early messages, and there are few of them.
143 /// debugs() messages captured in LogMessage() call order
144 using CompiledDebugMessages
= std::deque
<CompiledDebugMessage
>;
146 /// a receiver of debugs() messages (e.g., stderr or cache.log)
150 using EarlyMessages
= std::unique_ptr
<CompiledDebugMessages
>;
152 explicit DebugChannel(const char *aName
);
153 virtual ~DebugChannel() = default;
155 // no copying or moving or any kind (for simplicity sake and to prevent accidental copies)
156 DebugChannel(DebugChannel
&&) = delete;
158 /// whether we are still expecting (and buffering) early messages
159 bool collectingEarlyMessages() const { return bool(earlyMessages
); }
161 /// end early message buffering, logging any saved messages
162 void stopEarlyMessageCollection();
164 /// end early message buffering, without logging any saved messages
165 /// \returns (a possibly empty container with) saved messages or nil
166 EarlyMessages
releaseEarlyMessages() { return EarlyMessages(earlyMessages
.release()); }
168 /// Write the message to the channel if the channel accepts (such) messages.
169 /// This writing may be delayed until the channel configuration is settled.
170 void log(const DebugMessageHeader
&, const CompiledDebugMessageBody
&);
173 /// output iterator for writing CompiledDebugMessages to a given channel
177 using difference_type
= void;
178 using value_type
= void;
179 using pointer
= void;
180 using reference
= void;
181 using iterator_category
= std::output_iterator_tag
;
183 explicit Logger(DebugChannel
&ch
): channel(ch
) {}
185 Logger
&operator=(const CompiledDebugMessage
&message
)
187 if (Debug::Enabled(message
.header
.section
, message
.header
.level
))
188 channel
.get().log(message
.header
, message
.body
);
192 // These no-op operators are provided to satisfy LegacyOutputIterator requirements,
193 // as is customary for similar STL output iterators like std::ostream_iterator.
194 Logger
&operator*() { return *this; }
195 Logger
&operator++() { return *this; }
196 Logger
&operator++(int) { return *this; }
199 // wrap: output iterators must be CopyAssignable; raw references are not
200 std::reference_wrapper
<DebugChannel
> channel
; ///< output destination
203 /// whether we should write() the corresponding debugs() message now
204 /// (assumes some higher-level code applied cache.log section/level filter)
205 virtual bool shouldWrite(const DebugMessageHeader
&) const = 0;
207 /// write the corresponding debugs() message into the channel
208 virtual void write(const DebugMessageHeader
&, const CompiledDebugMessageBody
&) = 0;
210 /// stores the given early message (if possible) or forgets it (otherwise)
211 void saveMessage(const DebugMessageHeader
&, const CompiledDebugMessageBody
&);
213 /// stop saving and log() any "early" messages, in recordNumber order
214 static void StopSavingAndLog(DebugChannel
&, DebugChannel
* = nullptr);
216 /// Formats a validated debugs() record and writes it to the given FILE.
217 void writeToStream(FILE &, const DebugMessageHeader
&, const CompiledDebugMessageBody
&);
219 /// reacts to a written a debugs() message
220 void noteWritten(const DebugMessageHeader
&);
223 const char * const name
= nullptr; ///< unique channel label for debugging
225 /// the number of messages sent to the underlying channel so far
226 DebugRecordCount written
= 0;
228 /// DebugMessageHeader::recordNumber of the last message we wrote
229 DebugRecordCount lastWrittenRecordNumber
= 0;
231 /// debugs() messages waiting for the channel configuration to settle (and
232 /// the channel to open) so that their eligibility for logging can be
233 /// determined (and the messages can be actually written somewhere)
234 EarlyMessages earlyMessages
;
237 /// DebugChannel managing messages destined for the configured cache_log file
238 class CacheLogChannel
: public DebugChannel
241 CacheLogChannel(): DebugChannel("cache_log") {}
244 /* DebugChannel API */
245 bool shouldWrite(const DebugMessageHeader
&) const final
;
246 void write(const DebugMessageHeader
&, const CompiledDebugMessageBody
&) final
;
249 /// DebugChannel managing messages destined for "standard error stream" (stderr)
250 class StderrChannel
: public DebugChannel
253 StderrChannel(): DebugChannel("stderr") {}
255 /// start to take care of past/saved and future cacheLovirtual gChannel messages
256 void takeOver(CacheLogChannel
&);
258 /// stop providing a cache_log replacement (if we were providing it)
259 void stopCoveringForCacheLog();
261 /// \copydoc DebugChannel::shouldWrite()
262 bool enabled(const int messageDebugLevel
) const;
265 /* DebugChannel API */
266 bool shouldWrite(const DebugMessageHeader
&) const final
;
267 void write(const DebugMessageHeader
&, const CompiledDebugMessageBody
&) final
;
270 /// whether we are the last resort for logging debugs() messages
271 bool coveringForCacheLog
= false;
274 /// syslog DebugChannel
275 class SyslogChannel
: public DebugChannel
278 SyslogChannel(): DebugChannel("syslog") {}
280 void markOpened() { opened
= true; }
283 /* DebugChannel API */
284 bool shouldWrite(const DebugMessageHeader
&) const final
;
285 void write(const DebugMessageHeader
&, const CompiledDebugMessageBody
&) final
;
288 bool opened
= false; ///< whether openlog() was called
291 /// Manages private module state that must be available during program startup
292 /// and (especially) termination. Any non-trivial state objects must be
293 /// encapsulated here because debugs() may be called before dynamic
294 /// initialization or after the destruction of static objects in debug.cc.
300 // we provide debugging services for the entire duration of the program
301 ~DebugModule() = delete;
303 /// \copydoc Debug::PrepareToDie()
306 /// Log the given debugs() message to appropriate channel(s) (eventually).
307 /// Assumes the message has passed the global section/level filter.
308 void log(const DebugMessageHeader
&, const CompiledDebugMessageBody
&);
310 /// Start using an open cache_log file as the primary debugs() destination.
311 /// Stop using stderr as a cache_log replacement (if we were doing that).
314 /// Start using stderr as the primary debugs() destination.
315 /// Stop waiting for an open cache_log file (if we were doing that).
316 void banCacheLogUse();
319 CacheLogChannel cacheLogChannel
;
320 StderrChannel stderrChannel
;
321 SyslogChannel syslogChannel
;
324 /// Maintains the number of code paths on the current call stack that need
325 /// protection from new debugs() calls. Squid cannot _block_ re-entrant debugs()
326 /// calls, but the high-level debugs() handling code queues re-entrant logging
327 /// attempts when Busy() instead of letting them through to sensitive code.
328 class LoggingSectionGuard
331 LoggingSectionGuard();
332 ~LoggingSectionGuard();
334 /// whether new debugs() messages must be queued
335 static bool Busy() { return LoggingConcurrencyLevel
; }
338 /// the current number of protected callers
339 static size_t LoggingConcurrencyLevel
;
342 size_t LoggingSectionGuard::LoggingConcurrencyLevel
= 0;
344 /// debugs() messages postponed due to LoggingSectionGuard::Busy(). This is the
345 /// head of the invasive Context::upper FIFO list of such messages.
346 static Debug::Context
*WaitingForIdle
= nullptr;
349 /// safe during static initialization, even if it has not been constructed yet
350 /// safe during program termination, even if it has been destructed already
351 static DebugFile TheLog
;
355 return TheLog
.file() ? TheLog
.file() : stderr
;
358 /// used for the side effect: fills Debug::Levels with the given level
360 ResetSections(const int level
)
362 DidResetSections
= true;
363 for (auto §ionLevel
: Debug::Levels
)
364 sectionLevel
= level
;
367 /// optimization: formats ProcessLabel once for frequent debugs() reuse
369 LabelThisProcess(const char * const name
, const std::optional
<int> id
= std::optional
<int>())
372 assert(strlen(name
));
373 std::stringstream os
;
375 if (id
.has_value()) {
376 assert(id
.value() >= 0);
379 ProcessLabel
= os
.str();
383 Debug::NameThisHelper(const char * const name
)
385 LabelThisProcess(name
);
387 if (const auto parentProcessDebugOptions
= getenv("SQUID_DEBUG")) {
388 assert(!debugOptions
);
389 debugOptions
= xstrdup(parentProcessDebugOptions
);
392 // do not restrict helper (i.e. stderr) logging beyond debug_options
393 EnsureDefaultStderrLevel(DBG_DATA
);
395 // helpers do not write to cache.log directly; instead, ipcCreate()
396 // diverts helper stderr output to cache.log of the parent process
402 debugs(84, 2, "starting " << name
<< " with PID " << getpid());
406 Debug::NameThisKid(const int kidIdentifier
)
408 // to reduce noise and for backward compatibility, do not label kid messages
411 LabelThisProcess("kid", std::optional
<int>(kidIdentifier
));
413 ProcessLabel
.clear(); // probably already empty
416 /* LoggingSectionGuard */
418 LoggingSectionGuard::LoggingSectionGuard()
420 ++LoggingConcurrencyLevel
;
423 LoggingSectionGuard::~LoggingSectionGuard()
425 if (--LoggingConcurrencyLevel
== 0)
426 Debug::LogWaitingForIdle();
431 // Depending on DBG_CRITICAL activity and command line options, this code may
432 // run as early as static initialization during program startup or as late as
433 // the first debugs(DBG_CRITICAL) call from the main loop.
434 DebugModule::DebugModule()
436 // explicit initialization before any use by debugs() calls; see bug #2656
439 (void)std::atexit(&Debug::PrepareToDie
);
441 if (!DidResetSections
)
446 DebugModule::log(const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
448 cacheLogChannel
.log(header
, body
);
449 stderrChannel
.log(header
, body
);
450 syslogChannel
.log(header
, body
);
454 DebugModule::prepareToDie()
456 const LoggingSectionGuard sectionGuard
;
458 // Switch to stderr to improve our chances to log _early_ debugs(). However,
459 // use existing cache_log and/or stderr levels for post-open/close ones.
460 if (cacheLogChannel
.collectingEarlyMessages() && !TheLog
.file())
463 cacheLogChannel
.stopEarlyMessageCollection();
464 stderrChannel
.stopEarlyMessageCollection();
465 syslogChannel
.stopEarlyMessageCollection();
467 // Explicit last-resort call because we want to dump any pending messages
468 // (possibly including an assertion) even if another call, higher in the
469 // call stack, is currently in the sensitive section. Squid is dying, and
470 // that other caller (if any) will not get control back and, hence, will not
471 // trigger a Debug::LogWaitingForIdle() check. In most cases, we will log
472 // any pending messages successfully here. In the remaining few cases, we
473 // will lose them just like we would lose them without this call. The
474 // (small) risk here is that we might abort() or crash trying.
475 Debug::LogWaitingForIdle();
477 // Do not close/destroy channels: While the Debug module is not _guaranteed_
478 // to get control after prepareToDie(), debugs() calls are still very much
479 // _possible_, and we want to support/log them for as long as we can.
483 DebugModule::useCacheLog()
485 assert(TheLog
.file());
486 stderrChannel
.stopCoveringForCacheLog(); // in case it was covering
487 cacheLogChannel
.stopEarlyMessageCollection(); // in case it was collecting
491 DebugModule::banCacheLogUse()
493 assert(!TheLog
.file());
494 stderrChannel
.takeOver(cacheLogChannel
);
497 /// safe access to the debugging module
503 Module_
= new DebugModule();
505 // Optimization: Do not wait for others to tell us what we already know.
506 Debug::SettleSyslog();
514 ResyncDebugLog(FILE *newFile
)
516 TheLog
.file_
= newFile
;
521 DebugChannel::DebugChannel(const char * const aName
):
523 earlyMessages(new CompiledDebugMessages())
528 DebugChannel::stopEarlyMessageCollection()
531 StopSavingAndLog(*this);
532 // else already stopped
536 DebugChannel::log(const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
538 if (header
.recordNumber
<= lastWrittenRecordNumber
)
541 if (!shouldWrite(header
))
542 return saveMessage(header
, body
);
544 // We only save messages until we learn whether the channel is going to be
545 // used. We now know that it will be used. Also logs saved early messages
546 // (if they became eligible now) before lastWrittenRecordNumber blocks them.
547 stopEarlyMessageCollection();
555 auto &module
= Module();
556 (void)module
.cacheLogChannel
.releaseEarlyMessages();
557 (void)module
.stderrChannel
.releaseEarlyMessages();
558 (void)module
.syslogChannel
.releaseEarlyMessages();
562 Debug::PrepareToDie()
564 Module().prepareToDie();
568 DebugChannel::StopSavingAndLog(DebugChannel
&channelA
, DebugChannel
*channelBOrNil
)
570 const LoggingSectionGuard sectionGuard
;
572 assert(&channelA
!= channelBOrNil
);
573 const auto asOrNil
= channelA
.releaseEarlyMessages();
574 const auto bsOrNil
= channelBOrNil
? channelBOrNil
->releaseEarlyMessages() : nullptr;
575 const auto &as
= asOrNil
? *asOrNil
: CompiledDebugMessages();
576 const auto &bs
= bsOrNil
? *bsOrNil
: CompiledDebugMessages();
578 const auto writtenEarlier
= channelA
.written
;
580 std::merge(as
.begin(), as
.end(), bs
.begin(), bs
.end(), Logger(channelA
),
581 [](const CompiledDebugMessage
&mA
, const CompiledDebugMessage
&mB
) {
582 return mA
.header
.recordNumber
< mB
.header
.recordNumber
;
585 const auto writtenNow
= channelA
.written
- writtenEarlier
;
586 if (const auto totalCount
= as
.size() + bs
.size()) {
587 debugs(0, 5, "wrote " << writtenNow
<< " out of " << totalCount
<< '=' <<
588 as
.size() << '+' << bs
.size() << " early messages to " << channelA
.name
);
593 DebugChannel::saveMessage(const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
596 return; // we have stopped saving early messages
598 if (header
.level
> EarlyMessagesLevel
)
599 return; // this message is not important enough to save
601 // Given small EarlyMessagesLevel, only a Squid bug can cause so many
602 // earlyMessages. Saving/dumping excessive messages correctly is not only
603 // difficult but is more likely to complicate triage than help: It is the
604 // first earlyMessages that are going to be the most valuable. Our assert()
605 // will dump them if at all possible.
606 assert(earlyMessages
->size() < 1000);
608 earlyMessages
->emplace_back(header
, body
);
612 DebugChannel::writeToStream(FILE &destination
, const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
614 fprintf(&destination
, "%s%s| %s\n",
615 debugLogTime(header
.timestamp
),
616 ProcessLabel
.c_str(),
622 DebugChannel::noteWritten(const DebugMessageHeader
&header
)
625 lastWrittenRecordNumber
= header
.recordNumber
;
628 /* CacheLogChannel */
631 CacheLogChannel::shouldWrite(const DebugMessageHeader
&) const
633 return TheLog
.file();
637 CacheLogChannel::write(const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
639 writeToStream(*TheLog
.file(), header
, body
);
640 fflush(TheLog
.file());
646 StderrChannel::enabled(const int level
) const
649 return false; // nowhere to write
651 if (ExplicitStderrLevel
.has_value()) // explicit admin restrictions (-d)
652 return level
<= ExplicitStderrLevel
.value();
654 // whether the given level is allowed by emergency handling circumstances
655 // (coveringForCacheLog) or configuration aspects (e.g., -k or -z)
656 return coveringForCacheLog
|| level
<= DefaultStderrLevel
;
660 StderrChannel::shouldWrite(const DebugMessageHeader
&header
) const
662 return enabled(header
.level
);
666 StderrChannel::write(const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
668 writeToStream(*stderr
, header
, body
);
672 StderrChannel::takeOver(CacheLogChannel
&cacheLogChannel
)
674 if (coveringForCacheLog
)
676 coveringForCacheLog
= true;
678 StopSavingAndLog(*this, &cacheLogChannel
);
682 StderrChannel::stopCoveringForCacheLog()
684 if (!coveringForCacheLog
)
687 coveringForCacheLog
= false;
688 debugs(0, DBG_IMPORTANT
, "Resuming logging to cache_log");
692 Debug::EnsureDefaultStderrLevel(const int maxDefault
)
694 if (DefaultStderrLevel
< maxDefault
)
695 DefaultStderrLevel
= maxDefault
; // may set or increase
696 // else: somebody has already requested a more permissive maximum
700 Debug::ResetStderrLevel(const int maxLevel
)
702 ExplicitStderrLevel
= maxLevel
; // may set, increase, or decrease
706 Debug::SettleStderr()
708 auto &stderrChannel
= Module().stderrChannel
;
710 stderrChannel
.stopEarlyMessageCollection();
713 // Some users might expect -X to force -d9. Tell them what is happening.
715 stderrChannel
.enabled(DBG_DATA
) ? "; stderr will see all messages":
716 stderrChannel
.enabled(DBG_CRITICAL
) ? "; stderr will not see some messages":
717 "; stderr will see no messages";
718 if (ExplicitStderrLevel
)
719 debugs(0, DBG_CRITICAL
, "Using -X and -d" << ExplicitStderrLevel
.value() << outcome
);
721 debugs(0, DBG_CRITICAL
, "Using -X without -d" << outcome
);
726 Debug::StderrEnabled()
728 return Module().stderrChannel
.enabled(DBG_CRITICAL
);
731 /* DebugMessageHeader */
733 DebugMessageHeader::DebugMessageHeader(const DebugRecordCount aRecordNumber
, const Debug::Context
&context
):
734 recordNumber(aRecordNumber
),
735 section(context
.section
),
736 level(context
.level
),
737 forceAlert(context
.forceAlert
)
739 (void)getCurrentTime(); // update current_time
740 timestamp
= current_time
;
743 /* CompiledDebugMessage */
745 CompiledDebugMessage::CompiledDebugMessage(const Header
&aHeader
, const Body
&aBody
):
754 DebugFile::reset(FILE *newFile
, const char *newName
)
756 // callers must use nullptr instead of the used-as-the-last-resort stderr
757 assert(newFile
!= stderr
|| !stderr
);
760 fd_close(fileno(file_
));
763 file_
= newFile
; // may be nil
766 fd_open(fileno(file_
), FD_LOG
, Debug::cache_log
);
769 name
= newName
? xstrdup(newName
) : nullptr;
771 // all open files must have a name
772 // all cleared files must not have a name
773 assert(!file_
== !name
);
776 /// broadcasts debugs() message to the logging channels
778 Debug::LogMessage(const Context
&context
)
781 /* Multiple WIN32 threads may call this simultaneously */
784 HMODULE krnl_lib
= GetModuleHandle("Kernel32");
785 PFInitializeCriticalSectionAndSpinCount InitializeCriticalSectionAndSpinCount
= nullptr;
788 InitializeCriticalSectionAndSpinCount
=
789 (PFInitializeCriticalSectionAndSpinCount
) GetProcAddress(krnl_lib
,
790 "InitializeCriticalSectionAndSpinCount");
792 dbg_mutex
= static_cast<CRITICAL_SECTION
*>(xcalloc(1, sizeof(CRITICAL_SECTION
)));
794 if (InitializeCriticalSectionAndSpinCount
) {
795 /* let multiprocessor systems EnterCriticalSection() fast */
797 if (!InitializeCriticalSectionAndSpinCount(dbg_mutex
, 4000)) {
798 if (const auto logFile
= TheLog
.file()) {
799 fprintf(logFile
, "FATAL: %s: can't initialize critical section\n", __FUNCTION__
);
803 fprintf(stderr
, "FATAL: %s: can't initialize critical section\n", __FUNCTION__
);
806 InitializeCriticalSection(dbg_mutex
);
810 EnterCriticalSection(dbg_mutex
);
813 static DebugRecordCount LogMessageCalls
= 0;
814 const DebugMessageHeader
header(++LogMessageCalls
, context
);
815 Module().log(header
, context
.buf
.str());
818 LeaveCriticalSection(dbg_mutex
);
823 debugArg(const char *arg
)
828 if (!strncasecmp(arg
, "rotate=", 7)) {
830 Debug::rotateNumber
= atoi(arg
);
832 } else if (!strncasecmp(arg
, "ALL", 3)) {
837 while (*arg
&& *arg
++ != ',');
843 if (s
>= MAX_DEBUG_SECTIONS
)
844 s
= MAX_DEBUG_SECTIONS
-1;
853 Debug::Levels
[s
] = l
;
861 debugOpenLog(const char *logfile
)
865 // Bug 4423: ignore the stdio: logging module name if present
866 const char *logfilename
;
867 if (strncmp(logfile
, "stdio:",6) == 0)
868 logfilename
= logfile
+ 6;
870 logfilename
= logfile
;
872 if (auto log
= fopen(logfilename
, "a+")) {
874 setmode(fileno(log
), O_TEXT
);
876 TheLog
.reset(log
, logfilename
);
877 Module().useCacheLog();
879 const auto xerrno
= errno
;
881 Module().banCacheLogUse();
883 // report the problem after banCacheLogUse() to improve our chances of
884 // reporting earlier debugs() messages (that cannot be written after us)
885 debugs(0, DBG_CRITICAL
, "ERROR: Cannot open cache_log (" << logfilename
<< ") for writing;" <<
886 Debug::Extra
<< "fopen(3) error: " << xstrerr(xerrno
));
893 static struct syslog_facility_name
{
898 syslog_facility_names
[] = {
907 "authpriv", LOG_AUTHPRIV
1008 _db_set_syslog(const char *facility
)
1010 Debug::log_syslog
= true;
1015 syslog_facility
= LOG_DAEMON
;
1018 syslog_facility
= LOG_LOCAL4
;
1019 #endif /* LOG_DAEMON */
1023 struct syslog_facility_name
*n
;
1025 for (n
= syslog_facility_names
; n
->name
; ++n
) {
1026 if (strcmp(n
->name
, facility
) == 0) {
1027 syslog_facility
= n
->facility
;
1032 fprintf(stderr
, "unknown syslog facility '%s'\n", facility
);
1038 fprintf(stderr
, "syslog facility type not supported on your system\n");
1040 #endif /* LOG_LOCAL4 */
1046 SyslogPriority(const DebugMessageHeader
&header
)
1048 return header
.forceAlert
? LOG_ALERT
:
1049 (header
.level
== 0 ? LOG_WARNING
: LOG_NOTICE
);
1053 SyslogChannel::write(const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
1055 syslog(SyslogPriority(header
), "%s", body
.c_str());
1056 noteWritten(header
);
1062 SyslogChannel::write(const DebugMessageHeader
&, const CompiledDebugMessageBody
&)
1064 assert(!"unreachable code because opened, shouldWrite() are always false");
1067 #endif /* HAVE_SYSLOG */
1070 SyslogChannel::shouldWrite(const DebugMessageHeader
&header
) const
1075 assert(Debug::log_syslog
);
1076 return header
.forceAlert
|| header
.level
<= DBG_IMPORTANT
;
1080 Debug::ConfigureSyslog(const char *facility
)
1083 _db_set_syslog(facility
);
1087 fatalf("Logging to syslog not available on this platform");
1092 Debug::parseOptions(char const *options
)
1098 debugs(0, 9, "command-line -X overrides: " << options
);
1105 p
= xstrdup(options
);
1107 for (s
= strtok(p
, w_space
); s
; s
= strtok(nullptr, w_space
))
1115 Debug::BanCacheLogUse()
1117 Debug::parseOptions(debugOptions
);
1118 Module().banCacheLogUse();
1122 Debug::UseCacheLog()
1124 Debug::parseOptions(debugOptions
);
1125 debugOpenLog(cache_log
);
1129 Debug::StopCacheLogUse()
1131 if (TheLog
.file()) {
1132 // UseCacheLog() was successful.
1133 Module().cacheLogChannel
.stopEarlyMessageCollection(); // paranoid
1136 // UseCacheLog() was not called at all or failed to open cache_log.
1137 Module().banCacheLogUse(); // may already be banned
1142 Debug::SettleSyslog()
1144 #if HAVE_SYSLOG && defined(LOG_LOCAL4)
1146 if (Debug::log_syslog
) {
1147 openlog(APP_SHORTNAME
, LOG_PID
| LOG_NDELAY
| LOG_CONS
, syslog_facility
);
1148 Module().syslogChannel
.markOpened();
1151 #endif /* HAVE_SYSLOG */
1153 Module().syslogChannel
.stopEarlyMessageCollection();
1157 _db_rotate_log(void)
1164 if (stat(TheLog
.name
, &sb
) == 0)
1165 if (S_ISREG(sb
.st_mode
) == 0)
1169 char from
[MAXPATHLEN
];
1172 char to
[MAXPATHLEN
];
1176 * NOTE: we cannot use xrename here without having it in a
1177 * separate file -- tools.c has too many dependencies to be
1178 * used everywhere debug.c is used.
1180 /* Rotate numbers 0 through N up one */
1181 for (int i
= Debug::rotateNumber
; i
> 1;) {
1183 snprintf(from
, MAXPATHLEN
, "%s.%d", TheLog
.name
, i
- 1);
1184 snprintf(to
, MAXPATHLEN
, "%s.%d", TheLog
.name
, i
);
1190 if (rename(from
, to
) == -1) {
1191 const auto saved_errno
= errno
;
1192 debugs(0, DBG_IMPORTANT
, "ERROR: log rotation failed: " << xstrerr(saved_errno
));
1196 /* Rotate the current log to .0 */
1197 if (Debug::rotateNumber
> 0) {
1198 // form file names before we may clear TheLog below
1199 snprintf(from
, MAXPATHLEN
, "%s", TheLog
.name
);
1200 snprintf(to
, MAXPATHLEN
, "%s.%d", TheLog
.name
, 0);
1204 if (remove(to
) == -1) {
1205 const auto saved_errno
= errno
;
1206 debugs(0, DBG_IMPORTANT
, "ERROR: removal of log file " << to
<< " failed: " << xstrerr(saved_errno
));
1208 TheLog
.clear(); // Windows cannot rename() open files
1211 if (rename(from
, to
) == -1) {
1212 const auto saved_errno
= errno
;
1213 debugs(0, DBG_IMPORTANT
, "ERROR: renaming file " << from
<< " to "
1214 << to
<< "failed: " << xstrerr(saved_errno
));
1218 // Close (if we have not already) and reopen the log because
1219 // it may have been renamed "manually" before HUP'ing us.
1220 debugOpenLog(Debug::cache_log
);
1224 debugLogTime(const timeval
&t
)
1226 static char buf
[128]; // arbitrary size, big enough for the below timestamp strings.
1227 static time_t last_t
= 0;
1229 if (Debug::Level() > 1) {
1231 // 4 bytes smaller than buf to ensure .NNN catenation by snprintf()
1232 // is safe and works even if strftime() fills its buffer.
1233 char buf2
[sizeof(buf
)-4];
1234 const auto tm
= localtime(&last_t
);
1235 strftime(buf2
, sizeof(buf2
), "%Y/%m/%d %H:%M:%S", tm
);
1236 buf2
[sizeof(buf2
)-1] = '\0';
1237 const auto sz
= snprintf(buf
, sizeof(buf
), "%s.%03d", buf2
, static_cast<int>(t
.tv_usec
/ 1000));
1238 assert(0 < sz
&& sz
< static_cast<int>(sizeof(buf
)));
1239 // force buf reset for subsequent level-0/1 messages that should have no milliseconds
1241 } else if (t
.tv_sec
!= last_t
) {
1243 const auto tm
= localtime(&last_t
);
1244 const int sz
= strftime(buf
, sizeof(buf
), "%Y/%m/%d %H:%M:%S", tm
);
1245 assert(0 < sz
&& sz
<= static_cast<int>(sizeof(buf
)));
1248 buf
[sizeof(buf
)-1] = '\0';
1252 /// Whether there are any xassert() calls in the call stack. Treat as private to
1253 /// xassert(): It is moved out only to simplify the asserting code path.
1254 static auto Asserting_
= false;
1257 xassert(const char *msg
, const char *file
, int line
)
1259 // if the non-trivial code below has itself asserted, then simplify instead
1260 // of running out of stack and complicating triage
1266 debugs(0, DBG_CRITICAL
, "FATAL: assertion failed: " << file
<< ":" << line
<< ": \"" << msg
<< "\"");
1268 Debug::PrepareToDie();
1272 Debug::Context
*Debug::Current
= nullptr;
1274 Debug::Context::Context(const int aSection
, const int aLevel
):
1277 sectionLevel(Levels
[aSection
]),
1280 waitingForIdle(false)
1285 /// Optimization: avoids new Context creation for every debugs().
1287 Debug::Context::rewind(const int aSection
, const int aLevel
)
1291 sectionLevel
= Levels
[aSection
];
1292 assert(upper
== Current
);
1293 assert(!waitingForIdle
);
1295 buf
.str(CompiledDebugMessageBody());
1300 /// configures default formatting for the debugging stream
1302 Debug::FormatStream(std::ostream
&buf
)
1304 const static std::ostringstream cleanStream
;
1305 buf
.flags(cleanStream
.flags() | std::ios::fixed
);
1306 buf
.width(cleanStream
.width());
1309 // If this is not enough, use copyfmt(cleanStream) which is ~10% slower.
1313 Debug::Extra(std::ostream
&os
)
1315 // Prevent previous line formats bleeding onto this line: Previous line code
1316 // may not even be aware of some detailing code automatically adding extras.
1324 Debug::LogWaitingForIdle()
1326 if (!WaitingForIdle
)
1327 return; // do not lock in vain because unlocking would calls us
1329 const LoggingSectionGuard sectionGuard
;
1330 while (const auto current
= WaitingForIdle
) {
1331 assert(current
->waitingForIdle
);
1332 LogMessage(*current
);
1333 WaitingForIdle
= current
->upper
;
1338 std::ostringstream
&
1339 Debug::Start(const int section
, const int level
)
1341 Context
*future
= nullptr;
1343 if (LoggingSectionGuard::Busy()) {
1344 // a very rare reentrant debugs() call that originated during Finish() and such
1345 future
= new Context(section
, level
);
1346 future
->waitingForIdle
= true;
1347 } else if (Current
) {
1348 // a rare reentrant debugs() call that originated between Start() and Finish()
1349 future
= new Context(section
, level
);
1351 // Optimization: Nearly all debugs() calls get here; avoid allocations
1352 static Context
*topContext
= new Context(1, 1);
1353 topContext
->rewind(section
, level
);
1354 future
= topContext
;
1365 const LoggingSectionGuard sectionGuard
;
1367 // TODO: #include "base/CodeContext.h" instead if doing so works well.
1368 extern std::ostream
&CurrentCodeContextDetail(std::ostream
&os
);
1369 if (Current
->level
<= DBG_IMPORTANT
)
1370 Current
->buf
<< CurrentCodeContextDetail
;
1372 if (Current
->waitingForIdle
) {
1373 const auto past
= Current
;
1374 Current
= past
->upper
;
1375 past
->upper
= nullptr;
1376 // do not delete `past` because we store it in WaitingForIdle below
1378 // waitingForIdle messages are queued here instead of Start() because
1379 // their correct order is determined by the Finish() call timing/order.
1380 // Linear search, but this list ought to be very short (usually empty).
1381 auto *last
= &WaitingForIdle
;
1383 last
= &(*last
)->upper
;
1389 LogMessage(*Current
);
1390 Current
->forceAlert
= false;
1392 Context
*past
= Current
;
1393 Current
= past
->upper
;
1396 // else it was a static topContext from Debug::Start()
1402 // the ForceAlert(ostream) manipulator should only be used inside debugs()
1404 Current
->forceAlert
= true;
1408 ForceAlert(std::ostream
& s
)
1410 Debug::ForceAlert();