2 * Copyright (C) 1996-2022 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"
16 #include "time/gadgets.h"
25 char *Debug::debugOptions
= nullptr;
26 int Debug::override_X
= 0;
27 bool Debug::log_syslog
= false;
28 int Debug::Levels
[MAX_DEBUG_SECTIONS
];
29 char *Debug::cache_log
= nullptr;
30 int Debug::rotateNumber
= -1;
32 /// a counter related to the number of debugs() calls
33 using DebugRecordCount
= uint64_t;
37 /// Debugging module singleton.
38 static DebugModule
*Module_
= nullptr;
40 /// Explicitly configured maximum level for debugs() messages written to stderr.
41 /// debugs() messages with this (or lower) level will be written to stderr (and
42 /// possibly other channels).
43 static std::optional
<int> ExplicitStderrLevel
;
45 /// ExplicitStderrLevel preference or default: Just like with
46 /// ExplicitStderrLevel, debugs() messages with this (or lower) level will be
47 /// written to stderr (and possibly other channels), but this setting is ignored
48 /// when ExplicitStderrLevel is set. This setting is also ignored after major
49 /// problems that prevent logging of important debugs() messages (e.g., failing
50 /// to open cache_log or assertions).
51 static int DefaultStderrLevel
= -1;
53 /// early debugs() with higher level are not buffered and, hence, may be lost
54 static constexpr int EarlyMessagesLevel
= DBG_IMPORTANT
;
56 /// pre-formatted name of the current process for debugs() messages (or empty)
57 static std::string ProcessLabel
;
59 static const char *debugLogTime(const timeval
&);
63 static int syslog_facility
= 0;
68 extern LPCRITICAL_SECTION dbg_mutex
;
69 typedef BOOL (WINAPI
* PFInitializeCriticalSectionAndSpinCount
) (LPCRITICAL_SECTION
, DWORD
);
72 static void ResetSections(const int level
= DBG_IMPORTANT
);
74 /// Whether ResetSections() has been called already. We need to keep track of
75 /// this state because external code may trigger ResetSections() before the
76 /// DebugModule constructor has a chance to ResetSections() to their defaults.
77 /// TODO: Find a way to static-initialize Debug::Levels instead.
78 static bool DidResetSections
= false;
80 /// a named FILE with very-early/late usage safety mechanisms
85 ~DebugFile() { clear(); }
86 DebugFile(DebugFile
&&) = delete; // no copying or moving of any kind
88 /// switches to the new pair, absorbing FILE and duping the name
89 void reset(FILE *newFile
, const char *newName
);
91 /// go back to the initial state
92 void clear() { reset(nullptr, nullptr); }
94 /// an opened cache_log stream or nil
95 FILE *file() { return file_
; }
100 friend void ResyncDebugLog(FILE *newFile
);
102 FILE *file_
= nullptr; ///< opened "real" file or nil; never stderr
105 /// meta-information of a Finish()ed debugs() message
106 class DebugMessageHeader
109 DebugMessageHeader(const DebugRecordCount aRecordNumber
, const Debug::Context
&);
111 DebugRecordCount recordNumber
; ///< LogMessage() calls before this message
112 struct timeval timestamp
; ///< approximate debugs() call time
113 int section
; ///< debugs() section
114 int level
; ///< debugs() level
115 bool forceAlert
; ///< debugs() forceAlert flag
118 // Avoid SBuf for CompiledDebugMessageBody:
119 // * SBuf's own debugging may create a lot of reentrant debugging noise.
120 // * Debug::Context::buf is an std::string-based STL ostream. Converting its
121 // buf() result to a different kind of string may increase complexity/cost.
122 // TODO: Consider switching to a simple fixed-size buffer and a matching stream!
123 /// The processed "content" (i.e. the last parameter) part of a debugs() call.
124 using CompiledDebugMessageBody
= std::string
;
126 /// a fully processed debugs(), ready to be logged
127 class CompiledDebugMessage
130 using Header
= DebugMessageHeader
;
131 using Body
= CompiledDebugMessageBody
;
133 CompiledDebugMessage(const Header
&, const Body
&);
135 Header header
; ///< debugs() meta-information; reflected in log line prefix
136 Body body
; ///< the log line after the prefix (without the newline)
139 // We avoid PoolingAllocator for CompiledDebugMessages to minimize reentrant
140 // debugging noise. This noise reduction has negligible performance overhead
141 // because it only applied to early messages, and there are few of them.
142 /// debugs() messages captured in LogMessage() call order
143 using CompiledDebugMessages
= std::deque
<CompiledDebugMessage
>;
145 /// a receiver of debugs() messages (e.g., stderr or cache.log)
149 using EarlyMessages
= std::unique_ptr
<CompiledDebugMessages
>;
151 explicit DebugChannel(const char *aName
);
152 virtual ~DebugChannel() = default;
154 // no copying or moving or any kind (for simplicity sake and to prevent accidental copies)
155 DebugChannel(DebugChannel
&&) = delete;
157 /// whether we are still expecting (and buffering) early messages
158 bool collectingEarlyMessages() const { return bool(earlyMessages
); }
160 /// end early message buffering, logging any saved messages
161 void stopEarlyMessageCollection();
163 /// end early message buffering, without logging any saved messages
164 /// \returns (a possibly empty container with) saved messages or nil
165 EarlyMessages
releaseEarlyMessages() { return EarlyMessages(earlyMessages
.release()); }
167 /// Write the message to the channel if the channel accepts (such) messages.
168 /// This writing may be delayed until the channel configuration is settled.
169 void log(const DebugMessageHeader
&, const CompiledDebugMessageBody
&);
172 /// output iterator for writing CompiledDebugMessages to a given channel
176 using difference_type
= void;
177 using value_type
= void;
178 using pointer
= void;
179 using reference
= void;
180 using iterator_category
= std::output_iterator_tag
;
182 explicit Logger(DebugChannel
&ch
): channel(ch
) {}
184 Logger
&operator=(const CompiledDebugMessage
&message
)
186 if (Debug::Enabled(message
.header
.section
, message
.header
.level
))
187 channel
.get().log(message
.header
, message
.body
);
191 // These no-op operators are provided to satisfy LegacyOutputIterator requirements,
192 // as is customary for similar STL output iterators like std::ostream_iterator.
193 Logger
&operator*() { return *this; }
194 Logger
&operator++() { return *this; }
195 Logger
&operator++(int) { return *this; }
198 // wrap: output iterators must be CopyAssignable; raw references are not
199 std::reference_wrapper
<DebugChannel
> channel
; ///< output destination
202 /// whether we should write() the corresponding debugs() message now
203 /// (assumes some higher-level code applied cache.log section/level filter)
204 virtual bool shouldWrite(const DebugMessageHeader
&) const = 0;
206 /// write the corresponding debugs() message into the channel
207 virtual void write(const DebugMessageHeader
&, const CompiledDebugMessageBody
&) = 0;
209 /// stores the given early message (if possible) or forgets it (otherwise)
210 void saveMessage(const DebugMessageHeader
&, const CompiledDebugMessageBody
&);
212 /// stop saving and log() any "early" messages, in recordNumber order
213 static void StopSavingAndLog(DebugChannel
&, DebugChannel
* = nullptr);
215 /// Formats a validated debugs() record and writes it to the given FILE.
216 void writeToStream(FILE &, const DebugMessageHeader
&, const CompiledDebugMessageBody
&);
218 /// reacts to a written a debugs() message
219 void noteWritten(const DebugMessageHeader
&);
222 const char * const name
= nullptr; ///< unique channel label for debugging
224 /// the number of messages sent to the underlying channel so far
225 DebugRecordCount written
= 0;
227 /// DebugMessageHeader::recordNumber of the last message we wrote
228 DebugRecordCount lastWrittenRecordNumber
= 0;
230 /// debugs() messages waiting for the channel configuration to settle (and
231 /// the channel to open) so that their eligibility for logging can be
232 /// determined (and the messages can be actually written somewhere)
233 EarlyMessages earlyMessages
;
236 /// DebugChannel managing messages destined for the configured cache_log file
237 class CacheLogChannel
: public DebugChannel
240 CacheLogChannel(): DebugChannel("cache_log") {}
243 /* DebugChannel API */
244 bool shouldWrite(const DebugMessageHeader
&) const final
;
245 void write(const DebugMessageHeader
&, const CompiledDebugMessageBody
&) final
;
248 /// DebugChannel managing messages destined for "standard error stream" (stderr)
249 class StderrChannel
: public DebugChannel
252 StderrChannel(): DebugChannel("stderr") {}
254 /// start to take care of past/saved and future cacheLovirtual gChannel messages
255 void takeOver(CacheLogChannel
&);
257 /// stop providing a cache_log replacement (if we were providing it)
258 void stopCoveringForCacheLog();
260 /// \copydoc DebugChannel::shouldWrite()
261 bool enabled(const int messageDebugLevel
) const;
264 /* DebugChannel API */
265 bool shouldWrite(const DebugMessageHeader
&) const final
;
266 void write(const DebugMessageHeader
&, const CompiledDebugMessageBody
&) final
;
269 /// whether we are the last resort for logging debugs() messages
270 bool coveringForCacheLog
= false;
273 /// syslog DebugChannel
274 class SyslogChannel
: public DebugChannel
277 SyslogChannel(): DebugChannel("syslog") {}
279 void markOpened() { opened
= true; }
282 /* DebugChannel API */
283 bool shouldWrite(const DebugMessageHeader
&) const final
;
284 void write(const DebugMessageHeader
&, const CompiledDebugMessageBody
&) final
;
287 bool opened
= false; ///< whether openlog() was called
290 /// Manages private module state that must be available during program startup
291 /// and (especially) termination. Any non-trivial state objects must be
292 /// encapsulated here because debugs() may be called before dynamic
293 /// initialization or after the destruction of static objects in debug.cc.
299 // we provide debugging services for the entire duration of the program
300 ~DebugModule() = delete;
302 /// \copydoc Debug::PrepareToDie()
305 /// Log the given debugs() message to appropriate channel(s) (eventually).
306 /// Assumes the message has passed the global section/level filter.
307 void log(const DebugMessageHeader
&, const CompiledDebugMessageBody
&);
309 /// Start using an open cache_log file as the primary debugs() destination.
310 /// Stop using stderr as a cache_log replacement (if we were doing that).
313 /// Start using stderr as the primary debugs() destination.
314 /// Stop waiting for an open cache_log file (if we were doing that).
315 void banCacheLogUse();
318 CacheLogChannel cacheLogChannel
;
319 StderrChannel stderrChannel
;
320 SyslogChannel syslogChannel
;
323 /// Maintains the number of code paths on the current call stack that need
324 /// protection from new debugs() calls. Squid cannot _block_ re-entrant debugs()
325 /// calls, but the high-level debugs() handling code queues re-entrant logging
326 /// attempts when Busy() instead of letting them through to sensitive code.
327 class LoggingSectionGuard
330 LoggingSectionGuard();
331 ~LoggingSectionGuard();
333 /// whether new debugs() messages must be queued
334 static bool Busy() { return LoggingConcurrencyLevel
; }
337 /// the current number of protected callers
338 static size_t LoggingConcurrencyLevel
;
341 size_t LoggingSectionGuard::LoggingConcurrencyLevel
= 0;
343 /// debugs() messages postponed due to LoggingSectionGuard::Busy(). This is the
344 /// head of the invasive Context::upper FIFO list of such messages.
345 static Debug::Context
*WaitingForIdle
= nullptr;
348 /// safe during static initialization, even if it has not been constructed yet
349 /// safe during program termination, even if it has been destructed already
350 static DebugFile TheLog
;
354 return TheLog
.file() ? TheLog
.file() : stderr
;
357 /// used for the side effect: fills Debug::Levels with the given level
359 ResetSections(const int level
)
361 DidResetSections
= true;
362 for (auto §ionLevel
: Debug::Levels
)
363 sectionLevel
= level
;
366 /// optimization: formats ProcessLabel once for frequent debugs() reuse
368 LabelThisProcess(const char * const name
, const std::optional
<int> id
= std::optional
<int>())
371 assert(strlen(name
));
372 std::stringstream os
;
374 if (id
.has_value()) {
375 assert(id
.value() >= 0);
378 ProcessLabel
= os
.str();
382 Debug::NameThisHelper(const char * const name
)
384 LabelThisProcess(name
);
386 if (const auto parentProcessDebugOptions
= getenv("SQUID_DEBUG")) {
387 assert(!debugOptions
);
388 debugOptions
= xstrdup(parentProcessDebugOptions
);
391 // do not restrict helper (i.e. stderr) logging beyond debug_options
392 EnsureDefaultStderrLevel(DBG_DATA
);
394 // helpers do not write to cache.log directly; instead, ipcCreate()
395 // diverts helper stderr output to cache.log of the parent process
401 debugs(84, 2, "starting " << name
<< " with PID " << getpid());
405 Debug::NameThisKid(const int kidIdentifier
)
407 // to reduce noise and for backward compatibility, do not label kid messages
410 LabelThisProcess("kid", std::optional
<int>(kidIdentifier
));
412 ProcessLabel
.clear(); // probably already empty
415 /* LoggingSectionGuard */
417 LoggingSectionGuard::LoggingSectionGuard()
419 ++LoggingConcurrencyLevel
;
422 LoggingSectionGuard::~LoggingSectionGuard()
424 if (--LoggingConcurrencyLevel
== 0)
425 Debug::LogWaitingForIdle();
430 // Depending on DBG_CRITICAL activity and command line options, this code may
431 // run as early as static initialization during program startup or as late as
432 // the first debugs(DBG_CRITICAL) call from the main loop.
433 DebugModule::DebugModule()
435 // explicit initialization before any use by debugs() calls; see bug #2656
438 (void)std::atexit(&Debug::PrepareToDie
);
440 if (!DidResetSections
)
445 DebugModule::log(const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
447 cacheLogChannel
.log(header
, body
);
448 stderrChannel
.log(header
, body
);
449 syslogChannel
.log(header
, body
);
453 DebugModule::prepareToDie()
455 const LoggingSectionGuard sectionGuard
;
457 // Switch to stderr to improve our chances to log _early_ debugs(). However,
458 // use existing cache_log and/or stderr levels for post-open/close ones.
459 if (cacheLogChannel
.collectingEarlyMessages() && !TheLog
.file())
462 cacheLogChannel
.stopEarlyMessageCollection();
463 stderrChannel
.stopEarlyMessageCollection();
464 syslogChannel
.stopEarlyMessageCollection();
466 // Explicit last-resort call because we want to dump any pending messages
467 // (possibly including an assertion) even if another call, higher in the
468 // call stack, is currently in the sensitive section. Squid is dying, and
469 // that other caller (if any) will not get control back and, hence, will not
470 // trigger a Debug::LogWaitingForIdle() check. In most cases, we will log
471 // any pending messages successfully here. In the remaining few cases, we
472 // will lose them just like we would lose them without this call. The
473 // (small) risk here is that we might abort() or crash trying.
474 Debug::LogWaitingForIdle();
476 // Do not close/destroy channels: While the Debug module is not _guaranteed_
477 // to get control after prepareToDie(), debugs() calls are still very much
478 // _possible_, and we want to support/log them for as long as we can.
482 DebugModule::useCacheLog()
484 assert(TheLog
.file());
485 stderrChannel
.stopCoveringForCacheLog(); // in case it was covering
486 cacheLogChannel
.stopEarlyMessageCollection(); // in case it was collecting
490 DebugModule::banCacheLogUse()
492 assert(!TheLog
.file());
493 stderrChannel
.takeOver(cacheLogChannel
);
496 /// safe access to the debugging module
502 Module_
= new DebugModule();
504 // Optimization: Do not wait for others to tell us what we already know.
505 Debug::SettleSyslog();
513 ResyncDebugLog(FILE *newFile
)
515 TheLog
.file_
= newFile
;
520 DebugChannel::DebugChannel(const char * const aName
):
522 earlyMessages(new CompiledDebugMessages())
527 DebugChannel::stopEarlyMessageCollection()
530 StopSavingAndLog(*this);
531 // else already stopped
535 DebugChannel::log(const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
537 if (header
.recordNumber
<= lastWrittenRecordNumber
)
540 if (!shouldWrite(header
))
541 return saveMessage(header
, body
);
543 // We only save messages until we learn whether the channel is going to be
544 // used. We now know that it will be used. Also logs saved early messages
545 // (if they became eligible now) before lastWrittenRecordNumber blocks them.
546 stopEarlyMessageCollection();
554 auto &module
= Module();
555 (void)module
.cacheLogChannel
.releaseEarlyMessages();
556 (void)module
.stderrChannel
.releaseEarlyMessages();
557 (void)module
.syslogChannel
.releaseEarlyMessages();
561 Debug::PrepareToDie()
563 Module().prepareToDie();
567 DebugChannel::StopSavingAndLog(DebugChannel
&channelA
, DebugChannel
*channelBOrNil
)
569 const LoggingSectionGuard sectionGuard
;
571 assert(&channelA
!= channelBOrNil
);
572 const auto asOrNil
= channelA
.releaseEarlyMessages();
573 const auto bsOrNil
= channelBOrNil
? channelBOrNil
->releaseEarlyMessages() : nullptr;
574 const auto &as
= asOrNil
? *asOrNil
: CompiledDebugMessages();
575 const auto &bs
= bsOrNil
? *bsOrNil
: CompiledDebugMessages();
577 const auto writtenEarlier
= channelA
.written
;
579 std::merge(as
.begin(), as
.end(), bs
.begin(), bs
.end(), Logger(channelA
),
580 [](const CompiledDebugMessage
&mA
, const CompiledDebugMessage
&mB
) {
581 return mA
.header
.recordNumber
< mB
.header
.recordNumber
;
584 const auto writtenNow
= channelA
.written
- writtenEarlier
;
585 if (const auto totalCount
= as
.size() + bs
.size()) {
586 debugs(0, 5, "wrote " << writtenNow
<< " out of " << totalCount
<< '=' <<
587 as
.size() << '+' << bs
.size() << " early messages to " << channelA
.name
);
592 DebugChannel::saveMessage(const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
595 return; // we have stopped saving early messages
597 if (header
.level
> EarlyMessagesLevel
)
598 return; // this message is not important enough to save
600 // Given small EarlyMessagesLevel, only a Squid bug can cause so many
601 // earlyMessages. Saving/dumping excessive messages correctly is not only
602 // difficult but is more likely to complicate triage than help: It is the
603 // first earlyMessages that are going to be the most valuable. Our assert()
604 // will dump them if at all possible.
605 assert(earlyMessages
->size() < 1000);
607 earlyMessages
->emplace_back(header
, body
);
611 DebugChannel::writeToStream(FILE &destination
, const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
613 fprintf(&destination
, "%s%s| %s\n",
614 debugLogTime(header
.timestamp
),
615 ProcessLabel
.c_str(),
621 DebugChannel::noteWritten(const DebugMessageHeader
&header
)
624 lastWrittenRecordNumber
= header
.recordNumber
;
627 /* CacheLogChannel */
630 CacheLogChannel::shouldWrite(const DebugMessageHeader
&) const
632 return TheLog
.file();
636 CacheLogChannel::write(const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
638 writeToStream(*TheLog
.file(), header
, body
);
639 fflush(TheLog
.file());
645 StderrChannel::enabled(const int level
) const
648 return false; // nowhere to write
650 if (ExplicitStderrLevel
.has_value()) // explicit admin restrictions (-d)
651 return level
<= ExplicitStderrLevel
.value();
653 // whether the given level is allowed by emergency handling circumstances
654 // (coveringForCacheLog) or configuration aspects (e.g., -k or -z)
655 return coveringForCacheLog
|| level
<= DefaultStderrLevel
;
659 StderrChannel::shouldWrite(const DebugMessageHeader
&header
) const
661 return enabled(header
.level
);
665 StderrChannel::write(const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
667 writeToStream(*stderr
, header
, body
);
671 StderrChannel::takeOver(CacheLogChannel
&cacheLogChannel
)
673 if (coveringForCacheLog
)
675 coveringForCacheLog
= true;
677 StopSavingAndLog(*this, &cacheLogChannel
);
681 StderrChannel::stopCoveringForCacheLog()
683 if (!coveringForCacheLog
)
686 coveringForCacheLog
= false;
687 debugs(0, DBG_IMPORTANT
, "Resuming logging to cache_log");
691 Debug::EnsureDefaultStderrLevel(const int maxDefault
)
693 if (DefaultStderrLevel
< maxDefault
)
694 DefaultStderrLevel
= maxDefault
; // may set or increase
695 // else: somebody has already requested a more permissive maximum
699 Debug::ResetStderrLevel(const int maxLevel
)
701 ExplicitStderrLevel
= maxLevel
; // may set, increase, or decrease
705 Debug::SettleStderr()
707 auto &stderrChannel
= Module().stderrChannel
;
709 stderrChannel
.stopEarlyMessageCollection();
712 // Some users might expect -X to force -d9. Tell them what is happening.
714 stderrChannel
.enabled(DBG_DATA
) ? "; stderr will see all messages":
715 stderrChannel
.enabled(DBG_CRITICAL
) ? "; stderr will not see some messages":
716 "; stderr will see no messages";
717 if (ExplicitStderrLevel
)
718 debugs(0, DBG_CRITICAL
, "Using -X and -d" << ExplicitStderrLevel
.value() << outcome
);
720 debugs(0, DBG_CRITICAL
, "Using -X without -d" << outcome
);
725 Debug::StderrEnabled()
727 return Module().stderrChannel
.enabled(DBG_CRITICAL
);
730 /* DebugMessageHeader */
732 DebugMessageHeader::DebugMessageHeader(const DebugRecordCount aRecordNumber
, const Debug::Context
&context
):
733 recordNumber(aRecordNumber
),
734 section(context
.section
),
735 level(context
.level
),
736 forceAlert(context
.forceAlert
)
738 (void)getCurrentTime(); // update current_time
739 timestamp
= current_time
;
742 /* CompiledDebugMessage */
744 CompiledDebugMessage::CompiledDebugMessage(const Header
&aHeader
, const Body
&aBody
):
753 DebugFile::reset(FILE *newFile
, const char *newName
)
755 // callers must use nullptr instead of the used-as-the-last-resort stderr
756 assert(newFile
!= stderr
|| !stderr
);
759 fd_close(fileno(file_
));
762 file_
= newFile
; // may be nil
765 fd_open(fileno(file_
), FD_LOG
, Debug::cache_log
);
768 name
= newName
? xstrdup(newName
) : nullptr;
770 // all open files must have a name
771 // all cleared files must not have a name
772 assert(!file_
== !name
);
775 /// broadcasts debugs() message to the logging channels
777 Debug::LogMessage(const Context
&context
)
780 /* Multiple WIN32 threads may call this simultaneously */
783 HMODULE krnl_lib
= GetModuleHandle("Kernel32");
784 PFInitializeCriticalSectionAndSpinCount InitializeCriticalSectionAndSpinCount
= NULL
;
787 InitializeCriticalSectionAndSpinCount
=
788 (PFInitializeCriticalSectionAndSpinCount
) GetProcAddress(krnl_lib
,
789 "InitializeCriticalSectionAndSpinCount");
791 dbg_mutex
= static_cast<CRITICAL_SECTION
*>(xcalloc(1, sizeof(CRITICAL_SECTION
)));
793 if (InitializeCriticalSectionAndSpinCount
) {
794 /* let multiprocessor systems EnterCriticalSection() fast */
796 if (!InitializeCriticalSectionAndSpinCount(dbg_mutex
, 4000)) {
797 if (const auto logFile
= TheLog
.file()) {
798 fprintf(logFile
, "FATAL: %s: can't initialize critical section\n", __FUNCTION__
);
802 fprintf(stderr
, "FATAL: %s: can't initialize critical section\n", __FUNCTION__
);
805 InitializeCriticalSection(dbg_mutex
);
809 EnterCriticalSection(dbg_mutex
);
812 static DebugRecordCount LogMessageCalls
= 0;
813 const DebugMessageHeader
header(++LogMessageCalls
, context
);
814 Module().log(header
, context
.buf
.str());
817 LeaveCriticalSection(dbg_mutex
);
822 debugArg(const char *arg
)
827 if (!strncasecmp(arg
, "rotate=", 7)) {
829 Debug::rotateNumber
= atoi(arg
);
831 } else if (!strncasecmp(arg
, "ALL", 3)) {
836 while (*arg
&& *arg
++ != ',');
842 if (s
>= MAX_DEBUG_SECTIONS
)
843 s
= MAX_DEBUG_SECTIONS
-1;
852 Debug::Levels
[s
] = l
;
860 debugOpenLog(const char *logfile
)
864 // Bug 4423: ignore the stdio: logging module name if present
865 const char *logfilename
;
866 if (strncmp(logfile
, "stdio:",6) == 0)
867 logfilename
= logfile
+ 6;
869 logfilename
= logfile
;
871 if (auto log
= fopen(logfilename
, "a+")) {
873 setmode(fileno(log
), O_TEXT
);
875 TheLog
.reset(log
, logfilename
);
876 Module().useCacheLog();
878 const auto xerrno
= errno
;
880 Module().banCacheLogUse();
882 // report the problem after banCacheLogUse() to improve our chances of
883 // reporting earlier debugs() messages (that cannot be written after us)
884 debugs(0, DBG_CRITICAL
, "ERROR: Cannot open cache_log (" << logfilename
<< ") for writing;" <<
885 Debug::Extra
<< "fopen(3) error: " << xstrerr(xerrno
));
892 static struct syslog_facility_name
{
897 syslog_facility_names
[] = {
906 "authpriv", LOG_AUTHPRIV
1007 _db_set_syslog(const char *facility
)
1009 Debug::log_syslog
= true;
1014 syslog_facility
= LOG_DAEMON
;
1017 syslog_facility
= LOG_LOCAL4
;
1018 #endif /* LOG_DAEMON */
1022 struct syslog_facility_name
*n
;
1024 for (n
= syslog_facility_names
; n
->name
; ++n
) {
1025 if (strcmp(n
->name
, facility
) == 0) {
1026 syslog_facility
= n
->facility
;
1031 fprintf(stderr
, "unknown syslog facility '%s'\n", facility
);
1037 fprintf(stderr
, "syslog facility type not supported on your system\n");
1039 #endif /* LOG_LOCAL4 */
1045 SyslogPriority(const DebugMessageHeader
&header
)
1047 return header
.forceAlert
? LOG_ALERT
:
1048 (header
.level
== 0 ? LOG_WARNING
: LOG_NOTICE
);
1052 SyslogChannel::write(const DebugMessageHeader
&header
, const CompiledDebugMessageBody
&body
)
1054 syslog(SyslogPriority(header
), "%s", body
.c_str());
1055 noteWritten(header
);
1061 SyslogChannel::write(const DebugMessageHeader
&, const CompiledDebugMessageBody
&)
1063 assert(!"unreachable code because opened, shouldWrite() are always false");
1066 #endif /* HAVE_SYSLOG */
1069 SyslogChannel::shouldWrite(const DebugMessageHeader
&header
) const
1074 assert(Debug::log_syslog
);
1075 return header
.forceAlert
|| header
.level
<= DBG_IMPORTANT
;
1079 Debug::ConfigureSyslog(const char *facility
)
1082 _db_set_syslog(facility
);
1086 fatalf("Logging to syslog not available on this platform");
1091 Debug::parseOptions(char const *options
)
1097 debugs(0, 9, "command-line -X overrides: " << options
);
1104 p
= xstrdup(options
);
1106 for (s
= strtok(p
, w_space
); s
; s
= strtok(nullptr, w_space
))
1114 Debug::BanCacheLogUse()
1116 Debug::parseOptions(debugOptions
);
1117 Module().banCacheLogUse();
1121 Debug::UseCacheLog()
1123 Debug::parseOptions(debugOptions
);
1124 debugOpenLog(cache_log
);
1128 Debug::StopCacheLogUse()
1130 if (TheLog
.file()) {
1131 // UseCacheLog() was successful.
1132 Module().cacheLogChannel
.stopEarlyMessageCollection(); // paranoid
1135 // UseCacheLog() was not called at all or failed to open cache_log.
1136 Module().banCacheLogUse(); // may already be banned
1141 Debug::SettleSyslog()
1143 #if HAVE_SYSLOG && defined(LOG_LOCAL4)
1145 if (Debug::log_syslog
) {
1146 openlog(APP_SHORTNAME
, LOG_PID
| LOG_NDELAY
| LOG_CONS
, syslog_facility
);
1147 Module().syslogChannel
.markOpened();
1150 #endif /* HAVE_SYSLOG */
1152 Module().syslogChannel
.stopEarlyMessageCollection();
1156 _db_rotate_log(void)
1163 if (stat(TheLog
.name
, &sb
) == 0)
1164 if (S_ISREG(sb
.st_mode
) == 0)
1168 char from
[MAXPATHLEN
];
1171 char to
[MAXPATHLEN
];
1175 * NOTE: we cannot use xrename here without having it in a
1176 * separate file -- tools.c has too many dependencies to be
1177 * used everywhere debug.c is used.
1179 /* Rotate numbers 0 through N up one */
1180 for (int i
= Debug::rotateNumber
; i
> 1;) {
1182 snprintf(from
, MAXPATHLEN
, "%s.%d", TheLog
.name
, i
- 1);
1183 snprintf(to
, MAXPATHLEN
, "%s.%d", TheLog
.name
, i
);
1189 if (rename(from
, to
) == -1) {
1190 const auto saved_errno
= errno
;
1191 debugs(0, DBG_IMPORTANT
, "ERROR: log rotation failed: " << xstrerr(saved_errno
));
1195 /* Rotate the current log to .0 */
1196 if (Debug::rotateNumber
> 0) {
1197 // form file names before we may clear TheLog below
1198 snprintf(from
, MAXPATHLEN
, "%s", TheLog
.name
);
1199 snprintf(to
, MAXPATHLEN
, "%s.%d", TheLog
.name
, 0);
1203 if (remove(to
) == -1) {
1204 const auto saved_errno
= errno
;
1205 debugs(0, DBG_IMPORTANT
, "ERROR: removal of log file " << to
<< " failed: " << xstrerr(saved_errno
));
1207 TheLog
.clear(); // Windows cannot rename() open files
1210 if (rename(from
, to
) == -1) {
1211 const auto saved_errno
= errno
;
1212 debugs(0, DBG_IMPORTANT
, "ERROR: renaming file " << from
<< " to "
1213 << to
<< "failed: " << xstrerr(saved_errno
));
1217 // Close (if we have not already) and reopen the log because
1218 // it may have been renamed "manually" before HUP'ing us.
1219 debugOpenLog(Debug::cache_log
);
1223 debugLogTime(const timeval
&t
)
1225 static char buf
[128]; // arbitrary size, big enough for the below timestamp strings.
1226 static time_t last_t
= 0;
1228 if (Debug::Level() > 1) {
1229 // 4 bytes smaller than buf to ensure .NNN catenation by snprintf()
1230 // is safe and works even if strftime() fills its buffer.
1231 char buf2
[sizeof(buf
)-4];
1232 const auto tm
= localtime(&t
.tv_sec
);
1233 strftime(buf2
, sizeof(buf2
), "%Y/%m/%d %H:%M:%S", tm
);
1234 buf2
[sizeof(buf2
)-1] = '\0';
1235 const auto sz
= snprintf(buf
, sizeof(buf
), "%s.%03d", buf2
, static_cast<int>(t
.tv_usec
/ 1000));
1236 assert(0 < sz
&& sz
< static_cast<int>(sizeof(buf
)));
1237 // force buf reset for subsequent level-0/1 messages that should have no milliseconds
1239 } else if (t
.tv_sec
!= last_t
) {
1240 const auto tm
= localtime(&t
.tv_sec
);
1241 const int sz
= strftime(buf
, sizeof(buf
), "%Y/%m/%d %H:%M:%S", tm
);
1242 assert(0 < sz
&& sz
<= static_cast<int>(sizeof(buf
)));
1246 buf
[sizeof(buf
)-1] = '\0';
1250 /// Whether there are any xassert() calls in the call stack. Treat as private to
1251 /// xassert(): It is moved out only to simplify the asserting code path.
1252 static auto Asserting_
= false;
1255 xassert(const char *msg
, const char *file
, int line
)
1257 // if the non-trivial code below has itself asserted, then simplify instead
1258 // of running out of stack and complicating triage
1264 debugs(0, DBG_CRITICAL
, "FATAL: assertion failed: " << file
<< ":" << line
<< ": \"" << msg
<< "\"");
1266 Debug::PrepareToDie();
1270 Debug::Context
*Debug::Current
= nullptr;
1272 Debug::Context::Context(const int aSection
, const int aLevel
):
1275 sectionLevel(Levels
[aSection
]),
1278 waitingForIdle(false)
1283 /// Optimization: avoids new Context creation for every debugs().
1285 Debug::Context::rewind(const int aSection
, const int aLevel
)
1289 sectionLevel
= Levels
[aSection
];
1290 assert(upper
== Current
);
1291 assert(!waitingForIdle
);
1293 buf
.str(CompiledDebugMessageBody());
1295 // debugs() users are supposed to preserve format, but
1296 // some do not, so we have to waste cycles resetting it for all.
1300 /// configures default formatting for the debugging stream
1302 Debug::Context::formatStream()
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::LogWaitingForIdle()
1315 if (!WaitingForIdle
)
1316 return; // do not lock in vain because unlocking would calls us
1318 const LoggingSectionGuard sectionGuard
;
1319 while (const auto current
= WaitingForIdle
) {
1320 assert(current
->waitingForIdle
);
1321 LogMessage(*current
);
1322 WaitingForIdle
= current
->upper
;
1327 std::ostringstream
&
1328 Debug::Start(const int section
, const int level
)
1330 Context
*future
= nullptr;
1332 if (LoggingSectionGuard::Busy()) {
1333 // a very rare reentrant debugs() call that originated during Finish() and such
1334 future
= new Context(section
, level
);
1335 future
->waitingForIdle
= true;
1336 } else if (Current
) {
1337 // a rare reentrant debugs() call that originated between Start() and Finish()
1338 future
= new Context(section
, level
);
1340 // Optimization: Nearly all debugs() calls get here; avoid allocations
1341 static Context
*topContext
= new Context(1, 1);
1342 topContext
->rewind(section
, level
);
1343 future
= topContext
;
1354 const LoggingSectionGuard sectionGuard
;
1356 // TODO: #include "base/CodeContext.h" instead if doing so works well.
1357 extern std::ostream
&CurrentCodeContextDetail(std::ostream
&os
);
1358 if (Current
->level
<= DBG_IMPORTANT
)
1359 Current
->buf
<< CurrentCodeContextDetail
;
1361 if (Current
->waitingForIdle
) {
1362 const auto past
= Current
;
1363 Current
= past
->upper
;
1364 past
->upper
= nullptr;
1365 // do not delete `past` because we store it in WaitingForIdle below
1367 // waitingForIdle messages are queued here instead of Start() because
1368 // their correct order is determined by the Finish() call timing/order.
1369 // Linear search, but this list ought to be very short (usually empty).
1370 auto *last
= &WaitingForIdle
;
1372 last
= &(*last
)->upper
;
1378 LogMessage(*Current
);
1379 Current
->forceAlert
= false;
1381 Context
*past
= Current
;
1382 Current
= past
->upper
;
1385 // else it was a static topContext from Debug::Start()
1391 // the ForceAlert(ostream) manipulator should only be used inside debugs()
1393 Current
->forceAlert
= true;
1397 ForceAlert(std::ostream
& s
)
1399 Debug::ForceAlert();