]>
Commit | Line | Data |
---|---|---|
c59baaa8 | 1 | /* |
bf95c10a | 2 | * Copyright (C) 1996-2022 The Squid Software Foundation and contributors |
c59baaa8 EB |
3 | * |
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. | |
7 | */ | |
8 | ||
9 | /* DEBUG: section 00 Debug Routines */ | |
10 | ||
11 | #ifndef SQUID_DEBUG_MESSAGES_H | |
12 | #define SQUID_DEBUG_MESSAGES_H | |
13 | ||
14 | #include "Debug.h" | |
15 | #include "SquidConfig.h" | |
16 | ||
17 | #include <array> | |
18 | #include <limits> | |
19 | ||
20 | // XXX: Replace Debug class with namespace and use that namespace here. | |
21 | ||
22 | /// an identifier for messages supporting configuration via cache_log_message | |
23 | typedef size_t DebugMessageId; | |
24 | ||
25 | /// manages configurable aspects of a debugs() message | |
26 | class DebugMessage | |
27 | { | |
28 | public: | |
29 | /// whether the logging of this message has been customized | |
30 | bool configured() const { return id > 0; } | |
31 | ||
32 | /// whether the default logging level of this message has been altered | |
33 | bool levelled() const { return level >= 0; } | |
34 | ||
35 | /// whether the number of logging attempts have been limited | |
36 | bool limited() const { return limit < std::numeric_limits<decltype(limit)>::max(); } | |
37 | ||
38 | /// \returns appropriate debugging level for the message | |
39 | int currentLevel(const int defaultLevel) const { | |
40 | if (configured()) { | |
41 | if (count_++ < limit) | |
42 | return level; | |
43 | return (level <= DBG_IMPORTANT) ? 3 : 8; | |
44 | } | |
45 | return defaultLevel; | |
46 | } | |
47 | ||
48 | /// message identifier or, if the message has not been configured, zero | |
49 | DebugMessageId id = 0; | |
50 | ||
51 | /* all these configurable members are ignored unless configured() */ | |
52 | ||
53 | /// debugging level (i.e., the second debugs() parameter) or -1 | |
54 | int level = -1; | |
55 | ||
56 | /// logging attempts beyond this limit are logged at the DBG_DATA level | |
57 | uint64_t limit = std::numeric_limits<uint64_t>::max(); | |
58 | ||
59 | private: | |
60 | /// the total number of attempts to log this message if it was configured() | |
61 | mutable uint64_t count_ = 0; | |
62 | }; | |
63 | ||
64 | /// The maximum used DebugMessage::id plus 1. Increase as you add new IDs. | |
65 | constexpr DebugMessageId DebugMessageIdUpperBound = 65; | |
66 | ||
67 | /// a collection of DebugMessage objects (with fast access by message IDs) | |
68 | class DebugMessages | |
69 | { | |
70 | public: | |
71 | /// configurable messages indexed by their IDs | |
72 | typedef std::array<DebugMessage, DebugMessageIdUpperBound> Storage; | |
73 | Storage messages; | |
74 | }; | |
75 | ||
76 | // Using a template allows us to check message ID range at compile time. | |
77 | /// \returns configured debugging level for the given message or defaultLevel | |
78 | template <DebugMessageId id> | |
79 | inline int | |
80 | DebugMessageLevel(const int defaultLevel) | |
81 | { | |
82 | static_assert(id > 0, "debugs() message ID must be positive"); | |
83 | static_assert(id < DebugMessageIdUpperBound, "debugs() message ID must be smaller than DebugMessageIdUpperBound"); | |
84 | if (const auto configured = Config.debugMessages) | |
85 | return (configured->messages)[id].currentLevel(defaultLevel); | |
86 | return defaultLevel; | |
87 | } | |
88 | ||
89 | /* convenience macros for calling DebugMessageLevel */ | |
90 | #define Critical(id) DebugMessageLevel<id>(DBG_CRITICAL) | |
91 | #define Important(id) DebugMessageLevel<id>(DBG_IMPORTANT) | |
92 | #define Dbg(id, defaultLevel) DebugMessageLevel<id>(defaultLevel) | |
93 | ||
94 | #endif /* SQUID_DEBUG_MESSAGES_H */ | |
95 |