BDE 4.14.0 Production release
Loading...
Searching...
No Matches
ball_loggerfunctorpayloads.h
Go to the documentation of this file.
1/// @file ball_loggerfunctorpayloads.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// ball_loggerfunctorpayloads.h -*-C++-*-
8#ifndef INCLUDED_BALL_LOGGERFUNCTORPAYLOADS
9#define INCLUDED_BALL_LOGGERFUNCTORPAYLOADS
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup ball_loggerfunctorpayloads ball_loggerfunctorpayloads
15/// @brief Provide a suite of logger manager singleton functor payloads.
16/// @addtogroup bal
17/// @{
18/// @addtogroup ball
19/// @{
20/// @addtogroup ball_loggerfunctorpayloads
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#ball_loggerfunctorpayloads-purpose"> Purpose</a>
25/// * <a href="#ball_loggerfunctorpayloads-description"> Description </a>
26/// * <a href="#ball_loggerfunctorpayloads-support-for-hierarchical-category-names"> Support for Hierarchical Category Names </a>
27/// * <a href="#ball_loggerfunctorpayloads-usage"> Usage </a>
28/// * <a href="#ball_loggerfunctorpayloads-example-basic-usage"> Example: Basic Usage </a>
29///
30/// # Purpose {#ball_loggerfunctorpayloads-purpose}
31/// Provide a suite of logger manager singleton functor payloads.
32///
33///@CLASSES
34/// ball::LoggerFunctorPayloads: namespace for logger manager functor payloads
35///
36/// @see ball_loggermanagerconfiguration, ball_loggermanager
37///
38/// # Description {#ball_loggerfunctorpayloads-description}
39/// This component provides a namespace,
40/// `ball::LoggerFunctorPayloads`, containing a suite of functions, each of
41/// which may be used as the function body "payload" of one of the various
42/// `bsl::function` functors used as callbacks in the @ref ball_loggermanager
43/// component. Each function provides a specific customization or convenience
44/// enhancement to the basic logger functionality.
45///
46/// **WARNING**: Note that all functions defined in this component are intended
47/// for use with the logger manager singleton *only*, and not with any
48/// non-singleton instances of `ball::LoggerManager`; in particular, a
49/// precondition of each of the functions is that the logger manager singleton
50/// must be initialized and not in the process of being shut down.
51///
52/// The lone function defined in `ball::LoggerFunctorPayloads` at this time,
53/// `loadParentCategoryThresholdValues`, has signature:
54/// @code
55/// (int *, int *, int *, int *, const char *, char)
56/// @endcode
57/// The initial five types in this signature match the following `typedef` from
58/// `ball::LoggerManager` (and `ball::LoggerManagerConfiguration`):
59/// @code
60/// /// `DefaultThresholdLevelsCallback` is the type of the functor that
61/// /// determines default threshold levels for categories added to the
62/// /// registry by the `setCategory(const char *)` method.
63/// typedef bsl::function<void(int *, int *, int *, int *, const char *)>
64/// DefaultThresholdLevelsCallback;
65/// @endcode
66/// The purpose of the trailing `char` argument is discussed in the following
67/// section, the Usage example, and the `loadParentCategoryThresholdValues`
68/// function-level documentation.
69///
70/// ## Support for Hierarchical Category Names {#ball_loggerfunctorpayloads-support-for-hierarchical-category-names}
71///
72///
73/// The `ball` logging toolkit does not explicitly support any structure in the
74/// registry of category names; each unique sequence of characters defines a
75/// unique category that is, from the logger's perspective, a "peer" to all
76/// other categories. The toolkit does, however, provide several callback
77/// mechanisms that facilitate customized naming conventions.
78///
79/// In particular, the `ball::LoggerManager` singleton can be configured with a
80/// `DefaultThresholdLevelsCallback` (see the `typedef` definition above) that,
81/// if not null, is invoked to populate the four threshold levels whenever the
82/// user creates a category having the "default" thresholds. This component
83/// provides the function `loadParentCategoryThresholdValues` that can be used
84/// as the payload to `DefaultThresholdLevelsCallback`.
85/// `loadParentCategoryThresholdValues` populates its four category threshold
86/// level arguments from a specified "child" category name and a `char`
87/// delimiter by searching the category registry for a name that is "the most
88/// proximate parent category", assuming a hierarchical naming convention that
89/// uses the delimiter character. If such a parent category is found, the
90/// "child" category will receive the threshold levels of the parent. If no
91/// such parent exists, the new category will receive the standard "default"
92/// thresholds that it would have gotten had the callback been null.
93///
94/// ## Usage {#ball_loggerfunctorpayloads-usage}
95///
96///
97/// This section illustrates intended use of this component.
98///
99/// ### Example: Basic Usage {#ball_loggerfunctorpayloads-example-basic-usage}
100///
101///
102/// The following code snippets illustrate how to use this component's
103/// `loadParentCategoryThresholdValues` method to allow a newly-created "child"
104/// category to inherit the logging threshold levels from its most proximate
105/// parent category (if such a category already exists). Note that the category
106/// "hierarchy" is by naming convention only, but that the callback makes it
107/// simple for the *user* to impose hierarchical meaning on names that are, from
108/// the *logger's* perspective, peers. In this example, we will choose the dot
109/// character (`.`) as the hierarchy delimiter; to the logger itself, `.` is not
110/// special.
111///
112/// To keep this example transparent, we will create and inspect several
113/// categories within `main` directly; some categories will be "declared" to be
114/// "parent" categories, and we will set the threshold levels explicitly, while
115/// other categories will act as "children", which is to say that they will
116/// obtain their threshold levels through the callback mechanism. In a more
117/// realistic example, there would be no explicit distinction between "parent"
118/// and "child" categories, but rather as categories are dynamically
119/// administered by the user, newly created categories would pick up the changes
120/// made to existing parents. As a practical matter, the beginning of the
121/// function `main` constitute the "usage" to *install* the callback; the rest
122/// of this example merely illustrates the *consequences* of that.
123///
124/// First, we load the logger manager `configuration` with the desired "payload"
125/// function, `ball::LoggerFunctorPayloads::loadParentCategoryThresholdValues`,
126/// and use the trailing `char` argument `delimiter`, set to the value `.`,
127/// which will be bound into the functor and supplied back to the payload on
128/// each invocation.
129/// @code
130/// // myapp.cpp
131/// int main()
132/// {
133/// using namespace bdlf::PlaceHolders;
134///
135/// ball::LoggerManagerConfiguration configuration;
136/// char delimiter = '.';
137/// configuration.setDefaultThresholdLevelsCallback(
138/// bdlf::BindUtil::bind(
139/// &ball::LoggerFunctorPayloads::loadParentCategoryThresholdValues,
140/// _1,
141/// _2,
142/// _3,
143/// _4,
144/// _5,
145/// delimiter));
146/// @endcode
147/// Then, we initialize the logger manager, using the configuration defined
148/// above:
149/// @code
150/// ball::LoggerManagerScopedGuard guard(configuration);
151/// @endcode
152/// The above code is all that the user needs to do to customize the logger to
153/// "inherit" thresholds from parents. The rest of this example illustrates the
154/// consequences of having installed `myCallback`. For convenience in what
155/// follows, we define a reference, `manager`, to the singleton logger manager.
156/// @code
157/// ball::LoggerManager& manager = ball::LoggerManager::singleton();
158/// @endcode
159/// We now create two "parent" categories named "EQUITY.MARKET" and
160/// "EQUITY.GRAPHICS", and give them arbitrary but distinct threshold levels.
161/// We also set the default levels to distinct values in order to be able to
162/// verify exactly where "child" levels have come from later on.
163/// @code
164/// manager.setDefaultThresholdLevels(128, 96, 64, 32);
165///
166/// manager.addCategory("EQUITY.MARKET", 127, 95, 63, 31);
167/// manager.addCategory("EQUITY.GRAPHICS", 129, 97, 65, 33);
168/// @endcode
169/// Note that the call to `addCategory`, which takes the four `int` threshold
170/// arguments, does not invoke the callback at all, but rather -- assuming that
171/// the named category does not yet exist -- sets the thresholds to the
172/// specified values directly.
173///
174/// We can use the logger manager interface to verify that the levels have been
175/// set. First, we use the `lookupCategory` method to obtain the two parent
176/// categories (here assigned `p1` and `p2`).
177/// @code
178/// const ball::Category *p1 = manager.lookupCategory("EQUITY.MARKET");
179/// const ball::Category *p2 = manager.lookupCategory("EQUITY.GRAPHICS");
180/// @endcode
181/// Next, we can use the appropriate `ball::Category` accessor methods to
182/// `assert` the expected results. Recall that the ordered sequence of levels
183/// is "Record", "Pass", "Trigger", and "TriggerAll".
184/// @code
185/// assert(127 == p1->recordLevel());
186/// assert( 95 == p1->passLevel());
187/// assert( 63 == p1->triggerLevel());
188/// assert( 31 == p1->triggerAllLevel());
189///
190/// assert(129 == p2->recordLevel());
191/// assert( 97 == p2->passLevel());
192/// assert( 65 == p2->triggerLevel());
193/// assert( 33 == p2->triggerAllLevel());
194/// @endcode
195/// Now, we will add several "child" categories using the `setCategory` method
196/// taking a single argument, the `char*` category name. This method uses the
197/// callback in determining the "default" threshold levels to use. The six
198/// statements are numbered for subsequent discussion.
199/// @code
200/// manager.setCategory("EQUITY.MARKET.NYSE"); // (1)
201/// manager.setCategory("EQUITY.MARKET.NASDAQ"); // (2)
202/// manager.setCategory("EQUITY.GRAPHICS.MATH.FACTORIAL"); // (3)
203/// manager.setCategory("EQUITY.GRAPHICS.MATH.ACKERMANN"); // (4)
204/// manager.setCategory("EQUITY.GRAPHICS.MATH"); // (5)
205/// manager.setCategory("EQUITY"); // (6)
206/// @endcode
207/// Note that all six calls to `setCategory` will succeed in adding new
208/// categories to the registry. Calls (1)-(5) will "find" their parent's names
209/// and "inherit" the parent's levels. Call (6), however, will not find a
210/// parent category, and so will receive the default threshold levels, just as
211/// if there were no callback installed.
212///
213/// Note also that, although in this "static" (i.e., unadministered) example
214/// there is no significance to the order in which the above categories are
215/// created, in general (e.g., when categories are being dynamically
216/// administered) the order of creation *does* matter. If line (5) were
217/// executed before line (4) then the call on line (4) would find the
218/// "EQUITY.GRAPHICS.MATH" category as its "parent" and inherit those threshold
219/// levels. If, before line (4) executed, the thresholds of
220/// "EQUITY.GRAPHICS.MATH" were changed, then "EQUITY.GRAPHICS.MATH.FACTORIAL"
221/// and "EQUITY.GRAPHICS.MATH.ACKERMANN" would have different threshold levels
222/// despite their equivalent standing in the category hierarchy.
223///
224/// Let us now verify some of the 24 threshold levels that have been set by the
225/// above calls. We will verify the results of lines (1), (3), and (6) above.
226/// @code
227/// const ball::Category *c1, *c3, *c6;
228///
229/// c1 = manager.lookupCategory("EQUITY.MARKET.NYSE");
230/// assert(127 == c1->recordLevel());
231/// assert( 95 == c1->passLevel());
232/// assert( 63 == c1->triggerLevel());
233/// assert( 31 == c1->triggerAllLevel());
234///
235/// c3 = manager.lookupCategory("EQUITY.GRAPHICS.MATH.FACTORIAL");
236/// assert(129 == c3->recordLevel());
237/// assert( 97 == c3->passLevel());
238/// assert( 65 == c3->triggerLevel());
239/// assert( 33 == c3->triggerAllLevel());
240///
241/// c6 = manager.lookupCategory("EQUITY");
242/// assert(128 == c6->recordLevel());
243/// assert( 96 == c6->passLevel());
244/// assert( 64 == c6->triggerLevel());
245/// assert( 32 == c6->triggerAllLevel());
246///
247/// return 0;
248/// }
249/// @endcode
250/// @}
251/** @} */
252/** @} */
253
254/** @addtogroup bal
255 * @{
256 */
257/** @addtogroup ball
258 * @{
259 */
260/** @addtogroup ball_loggerfunctorpayloads
261 * @{
262 */
263
264#include <balscm_version.h>
265
266
267namespace ball {
268
269 // ============================
270 // struct LoggerFunctorPayloads
271 // ============================
272
273/// This `struct` provides a namespace for a suite of utility functions,
274/// each of which may be used as the function body for an appropriate
275/// `bsl::function` callback functor within @ref ball_loggermanager .
276///
277/// **WARNING**: Note that all functions are intended for use with the logger
278/// manager singleton *only*, and not with any non-singleton instances of
279/// `ball::LoggerManager`.
281
282 // CLASS METHODS
283
284 /// Load into the specified `recordLevel`, `passLevel`, `triggerLevel`,
285 /// and `triggerAllLevel` the respective threshold levels of the
286 /// category in the registry of the (singleton) `ball` logger manager
287 /// that is the most proximate parent category of the category having
288 /// the specified `categoryName` among existing hierarchically named
289 /// categories in the registry, if such a parent category exists, or the
290 /// default thresholds otherwise; use the specified `delimiter` to
291 /// define hierarchical category names. The behavior is undefined
292 /// unless the logger manager singleton has been initialized and is not
293 /// in the process of being shut down.
294 static
296 int *passLevel,
297 int *triggerLevel,
298 int *triggerAllLevel,
299 const char *categoryName,
300 char delimiter);
301};
302
303} // close package namespace
304
305
306#endif
307
308// ----------------------------------------------------------------------------
309// Copyright 2015 Bloomberg Finance L.P.
310//
311// Licensed under the Apache License, Version 2.0 (the "License");
312// you may not use this file except in compliance with the License.
313// You may obtain a copy of the License at
314//
315// http://www.apache.org/licenses/LICENSE-2.0
316//
317// Unless required by applicable law or agreed to in writing, software
318// distributed under the License is distributed on an "AS IS" BASIS,
319// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
320// See the License for the specific language governing permissions and
321// limitations under the License.
322// ----------------------------- END-OF-FILE ----------------------------------
323
324/** @} */
325/** @} */
326/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition ball_administration.h:214
Definition ball_loggerfunctorpayloads.h:280
static void loadParentCategoryThresholdValues(int *recordLevel, int *passLevel, int *triggerLevel, int *triggerAllLevel, const char *categoryName, char delimiter)