BDE 4.14.0 Production release
Loading...
Searching...
No Matches
balm_category.h
Go to the documentation of this file.
1/// @file balm_category.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balm_category.h -*-C++-*-
8#ifndef INCLUDED_BALM_CATEGORY
9#define INCLUDED_BALM_CATEGORY
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: balm_category.h,v 1.4 2008/04/16 20:00:49 hversche Exp $")
13
14/// @defgroup balm_category balm_category
15/// @brief Provide a representation of a metric category.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balm
19/// @{
20/// @addtogroup balm_category
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balm_category-purpose"> Purpose</a>
25/// * <a href="#balm_category-classes"> Classes </a>
26/// * <a href="#balm_category-description"> Description </a>
27/// * <a href="#balm_category-alternative-systems-for-telemetry"> Alternative Systems for Telemetry </a>
28/// * <a href="#balm_category-thread-safety"> Thread Safety </a>
29/// * <a href="#balm_category-usage"> Usage </a>
30/// * <a href="#balm_category-example-1-basic-usage"> Example 1: Basic Usage </a>
31///
32/// # Purpose {#balm_category-purpose}
33/// Provide a representation of a metric category.
34///
35/// # Classes {#balm_category-classes}
36///
37/// - balm::Category: a representation of a metric category
38///
39/// @see balm_metricregistry, balm_metricid, balm_metricdescription
40///
41/// # Description {#balm_category-description}
42/// This component provides a class, `balm::Category`, whose values
43/// are used to categorize collected metrics. A metric "category" is an
44/// identifier (chosen by the application) that groups together one or more
45/// metrics. A `balm::Category` object contains the address of a string holding
46/// the name of the category and a boolean value indicating whether the
47/// category is currently enabled. The `balm::Category` class suppresses copy
48/// construction and assignment, and does not provide equality operators;
49/// applications should use a *single* `balm::Category` object instance per
50/// category (such as one provided by the *`balm::MetricRegistry`* component).
51///
52/// IMPORTANT: The category name, whose type is `const char *`, must remain
53/// constant and valid throughout the lifetime of the `balm::Category` object.
54///
55/// ## Alternative Systems for Telemetry {#balm_category-alternative-systems-for-telemetry}
56///
57///
58/// Bloomberg software may alternatively use the GUTS telemetry API, which is
59/// integrated into Bloomberg infrastructure.
60///
61/// ## Thread Safety {#balm_category-thread-safety}
62///
63///
64/// `balm::Category` is generally *const* *thread-safe*, meaning that accessors
65/// may be invoked concurrently from different threads, but it is not safe to
66/// access or modify a `balm::Category` in one thread while another thread
67/// modifies the same object. However, it is safe to *access* the `enabled`
68/// property on one (or more) thread(s) while the object is being modified on
69/// another thread.
70///
71/// ## Usage {#balm_category-usage}
72///
73///
74/// This section illustrates intended use of this component.
75///
76/// ### Example 1: Basic Usage {#balm_category-example-1-basic-usage}
77///
78///
79/// The following example demonstrates how to create, access, and modify a
80/// `balm::Category` object. We start by creating three category objects with
81/// different names:
82/// @code
83/// balm::Category categoryA("A", true);
84/// balm::Category categoryB("B", false);
85/// balm::Category categoryC("C");
86/// @endcode
87/// Once the category objects have been created, we can use the `name` and
88/// `enabled` methods to access their values:
89/// @code
90/// assert(0 == bsl::strcmp("A", categoryA.name()));
91/// assert(0 == bsl::strcmp("B", categoryB.name()));
92/// assert(0 == bsl::strcmp("C", categoryC.name()));
93///
94/// assert( categoryA.enabled());
95/// assert(!categoryB.enabled());
96/// assert( categoryC.enabled());
97/// @endcode
98/// Finally, we modify the enablement status of one of the categories, and then
99/// write all three categories to the console:
100/// @code
101/// categoryC.setEnabled(false);
102///
103/// bsl::cout << "categoryA: " << categoryA << bsl::endl
104/// << "categoryB: " << categoryB << bsl::endl
105/// << "categoryC: " << categoryC << bsl::endl;
106/// @endcode
107/// With the resulting console output:
108/// @code
109/// categoryA: [ A ENABLED ]
110/// categoryB: [ B DISABLED ]
111/// categoryC: [ C DISABLED ]
112/// @endcode
113/// @}
114/** @} */
115/** @} */
116
117/** @addtogroup bal
118 * @{
119 */
120/** @addtogroup balm
121 * @{
122 */
123/** @addtogroup balm_category
124 * @{
125 */
126
127#include <balscm_version.h>
128
129#include <bsls_atomic.h>
130
131#include <bsl_iosfwd.h>
132
133
134
135
136namespace balm {
137
138class CategoryHolder;
139
140 // ==============
141 // class Category
142 // ==============
143
144/// This class provides a mechanism for representing a category. A category
145/// is an identifier used to group related metrics. A `Category` object
146/// contains the address of a null-terminated string, `name`, holding the
147/// name of the category and a boolean value, `enabled`, indicating whether
148/// the category is currently enabled.
149///
150/// See @ref balm_category
151class Category {
152
153 // DATA
154 const char *d_name_p; // name of the category (held, not owned)
155
156 bsls::AtomicInt d_enabled; // whether the category is enabled
157
158 CategoryHolder *d_holders_p; // linked list of holders of this category
159
160 // NOT IMPLEMENTED
161 Category(const Category& );
162 Category& operator=(const Category& );
163
164 public:
165 // CREATORS
166
167 /// Create a category having the specified `name` address. Optionally
168 /// specify `enabledFlag`, the enabled status of the category; if
169 /// `enabledFlag` is not specified, the `enabled` status is `true`. The
170 /// behavior is undefined unless `name` remains valid and unmodified for
171 /// the lifetime of this object.
172 explicit Category(const char *name, bool enabledFlag = true);
173
174 /// Destroy this category object.
176
177 // MANIPULATORS
178
179 /// Set the name of this metric to the specified `name` address. The
180 /// behavior is undefined unless `name` remains valid and unmodified
181 /// for the lifetime of this object.
182 void setName(const char *name);
183
184 /// Set the `enabled` state of this category to the value of the
185 /// specified `enabledFlag` and update any `CategoryHolder` objects
186 /// registered with this category. Note that this operation is *not*
187 /// atomic, and other threads may simultaneously access the current
188 /// enabled value while this operation is performed. Also note that
189 /// this operation has *linear* performance with respect to the number
190 /// of registered category holders for `category`.
191 void setEnabled(bool enabledFlag);
192
193 /// Load into the specified `holder` the address of this category, its
194 /// `enabled()` status, and the address of the next holder in the
195 /// linked list of category holders maintained by this object
196 /// (prepending `holder` to this category's linked list of category
197 /// holders). This category will update `holder->enabled()` when its
198 /// enabled state changes, and will reset `holder` (i.e.,
199 /// `holder->reset()`) when this category is destroyed. The behavior
200 /// is undefined unless `holder` remains valid and *unmodified* (by the
201 /// client) for the lifetime of this object and is *not* registered
202 /// again with any category (including this one).
204
205 // ACCESSORS
206
207 /// Return the address of the non-modifiable null-terminated string
208 /// containing the name of this category.
209 const char *name() const;
210
211 /// Report whether this category is enabled. This function is fully
212 /// thread-safe.
213 bool enabled() const;
214
215 /// Return a *reference* to a const value indicating the enabled status
216 /// of this category, allowing downstream uses to minimize latency by
217 /// avoiding indirection through abstracted interfaces, albeit at some
218 /// risk of object-lifetime violations. The returned reference must not
219 /// be allowed to outlive this category object.
220 const bsls::AtomicInt& isEnabledRaw() const;
221
222 /// Print this category to the specified output `stream` in some human
223 /// readable form, and return the modifiable `stream`.
224 bsl::ostream& print(bsl::ostream& stream) const;
225};
226
227// ============================================================================
228// INLINE DEFINITIONS
229// ============================================================================
230
231// FREE OPERATORS
232
233/// Output a formatted description of the specified `rhs` category to the
234/// specified `stream`, and return the modifiable `stream`.
235inline
236bsl::ostream& operator<<(bsl::ostream& stream, const Category& rhs);
237
238 // ====================
239 // class CategoryHolder
240 // ====================
241
242/// This class, informally referred to as a "category holder" (or simply
243/// "holder"), holds a category, an enabled value, and a pointer to a
244/// "next" holder. Both the category and next pointer may be null. The
245/// intended use is as follows: (1) instances of this class are (only)
246/// declared in contexts where collecting a metric occurs; (2) if the
247/// enabled value is true, the category contains the address of a valid,
248/// enabled, category; (3) if the next pointer is non-null, then the holder
249/// pointed to holds the same category and threshold. Instances of this
250/// class must be *statically* initializable. Hence, the data members are
251/// `public`, and no constructors or destructor are defined.
252///
253/// This class should *not* be used directly by client code. It is an
254/// implementation detail of the `balm` metric collection system.
255///
256/// See @ref balm_category
258
259 // NOT IMPLEMENTED
260 CategoryHolder& operator=(const CategoryHolder& rhs);
261
262 public:
263
264 // PUBLIC DATA MEMBERS
265 bool d_enabled; // whether the category is enabled
266 const Category *d_category_p; // held category (not owned)
267 CategoryHolder *d_next_p; // next category holder in linked list
268
269 // CREATORS
270
271 // No constructors or destructors are declared in order to allow for static
272 // initialization of instances of this class.
273
274 // MANIPULATORS
275
276 /// Reset this object to its default value. The default value is:
277 /// @code
278 /// { false, 0, 0 }
279 /// @endcode
280 void reset();
281
282 /// Set the address of the category held by this holder to the specified
283 /// `category`.
284 void setCategory(const Category *category);
285
286 /// Set the `enabled` state of this category to the value of the
287 /// specified `enabledFlag`.
288 void setEnabled(bool enabledFlag);
289
290 /// Set this holder to point to the specified `holder`.
291 void setNext(CategoryHolder *holder);
292
293 // ACCESSORS
294
295 /// Return the address of the non-modifiable category held by this
296 /// holder.
297 const Category *category() const;
298
299 /// Return `true` if `category` is valid (i.e., non-null) and enabled,
300 /// and `false` otherwise.
301 bool enabled() const;
302
303 /// Return the address of the modifiable holder pointed to by this
304 /// holder.
305 CategoryHolder *next() const;
306};
307
308// ============================================================================
309// INLINE FUNCTION DEFINITIONS
310// ============================================================================
311
312 // --------------
313 // class Category
314 // --------------
315
316// CREATORS
317inline
318Category::Category(const char *name, bool enabledFlag)
319: d_name_p(name)
320, d_enabled(enabledFlag)
321, d_holders_p(0)
322{
323}
324
325// MANIPULATORS
326inline
327void Category::setName(const char *name)
328{
329 d_name_p = name;
330}
331
332// ACCESSORS
333inline
334const char *Category::name() const
335{
336 return d_name_p;
337}
338
339inline
341{
342 return d_enabled;
343}
344
345inline
347{
348 return d_enabled;
349}
350
351 // --------------------
352 // class CategoryHolder
353 // --------------------
354
355// MANIPULATORS
356inline
358{
360}
361
362inline
363void CategoryHolder::setEnabled(bool enabledFlag)
364{
365 d_enabled = enabledFlag;
366}
367
368inline
370{
371 d_next_p = holder;
372}
373
374// ACCESSORS
375inline
377{
378 return d_category_p;
379}
380
381inline
383{
384 return d_enabled;
385}
386
387inline
389{
390 return d_next_p;
391}
392} // close package namespace
393
394// FREE OPERATORS
395inline
396bsl::ostream& balm::operator<<(bsl::ostream& stream, const Category& rhs)
397{
398 return rhs.print(stream);
399}
400
401
402
403#endif
404
405// ----------------------------------------------------------------------------
406// Copyright 2015 Bloomberg Finance L.P.
407//
408// Licensed under the Apache License, Version 2.0 (the "License");
409// you may not use this file except in compliance with the License.
410// You may obtain a copy of the License at
411//
412// http://www.apache.org/licenses/LICENSE-2.0
413//
414// Unless required by applicable law or agreed to in writing, software
415// distributed under the License is distributed on an "AS IS" BASIS,
416// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
417// See the License for the specific language governing permissions and
418// limitations under the License.
419// ----------------------------- END-OF-FILE ----------------------------------
420
421/** @} */
422/** @} */
423/** @} */
Definition balm_category.h:257
CategoryHolder * next() const
Definition balm_category.h:388
const Category * category() const
Definition balm_category.h:376
void setEnabled(bool enabledFlag)
Definition balm_category.h:363
bool enabled() const
Definition balm_category.h:382
CategoryHolder * d_next_p
Definition balm_category.h:267
void setNext(CategoryHolder *holder)
Set this holder to point to the specified holder.
Definition balm_category.h:369
const Category * d_category_p
Definition balm_category.h:266
bool d_enabled
Definition balm_category.h:265
void setCategory(const Category *category)
Definition balm_category.h:357
Definition balm_category.h:151
void setName(const char *name)
Definition balm_category.h:327
void registerCategoryHolder(CategoryHolder *holder)
~Category()
Destroy this category object.
const char * name() const
Definition balm_category.h:334
bsl::ostream & print(bsl::ostream &stream) const
bool enabled() const
Definition balm_category.h:340
const bsls::AtomicInt & isEnabledRaw() const
Definition balm_category.h:346
void setEnabled(bool enabledFlag)
Definition bsls_atomic.h:743
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition balm_bdlmmetricsadapter.h:141
bsl::ostream & operator<<(bsl::ostream &stream, const Category &rhs)