BDE 4.39.x Production Release
Loading...
Searching...
No Matches
balm_collectorrepository.h
Go to the documentation of this file.
1/// @file balm_collectorrepository.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balm_collectorrepository.h -*-C++-*-
8#ifndef INCLUDED_BALM_COLLECTORREPOSITORY
9#define INCLUDED_BALM_COLLECTORREPOSITORY
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balm_collectorrepository balm_collectorrepository
15/// @brief Provide a repository for collectors.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balm
19/// @{
20/// @addtogroup balm_collectorrepository
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balm_collectorrepository-purpose"> Purpose</a>
25/// * <a href="#balm_collectorrepository-classes"> Classes </a>
26/// * <a href="#balm_collectorrepository-description"> Description </a>
27/// * <a href="#balm_collectorrepository-alternative-systems-for-telemetry"> Alternative Systems for Telemetry </a>
28/// * <a href="#balm_collectorrepository-thread-safety"> Thread Safety </a>
29/// * <a href="#balm_collectorrepository-usage"> Usage </a>
30///
31/// # Purpose {#balm_collectorrepository-purpose}
32/// Provide a repository for collectors.
33///
34/// # Classes {#balm_collectorrepository-classes}
35///
36/// - balm::CollectorRepository: a repository for collectors
37///
38/// @see balm_collector, balm_integercollector, balm_metricsmanager
39///
40/// # Description {#balm_collectorrepository-description}
41/// This component defines a class, `balm::CollectorRepository`,
42/// that serves as a repository for `balm::Collector` and
43/// `balm::IntegerCollector` objects. The collector repository supports
44/// operations to create and lookup collectors, as well as an operation to
45/// collect metric records from the collectors in the repository. Collectors
46/// are identified by a metric id, which uniquely identifies the metric for
47/// which they collect values. The `getDefaultCollector` (and
48/// `getDefaultIntegerCollector`) operations return the default collector (or
49/// integer collector) for the supplied metric. The `addCollector` (and
50/// `addIntegerCollector`) operations create and return a new collector (or
51/// integer collector) for the specified metric. Each collector instance can
52/// can safely collect values from multiple threads, however, the collector does
53/// use a mutex: Applications anticipating high contention for that lock can use
54/// `addCollector` (and `addIntegerCollector`) to obtain multiple collectors and
55/// thereby reduce contention. Finally, the `collectAndReset` operation
56/// collects and returns metric records from each of the collectors in the
57/// repository.
58///
59/// ## Alternative Systems for Telemetry {#balm_collectorrepository-alternative-systems-for-telemetry}
60///
61///
62/// Bloomberg software may alternatively use the GUTS telemetry API, which is
63/// integrated into Bloomberg infrastructure.
64///
65/// ## Thread Safety {#balm_collectorrepository-thread-safety}
66///
67///
68/// `balm::CollectorRepository` is fully *thread-safe*, meaning that all
69/// non-creator operations on a given instance can be safely invoked
70/// simultaneously from multiple threads.
71///
72/// ## Usage {#balm_collectorrepository-usage}
73///
74///
75/// The following example illustrates creating a `balm::CollectorRepository`,
76/// then looking up collectors in that repository, and finally collecting values
77/// from the repository. We start by creating a repository and looking up 2
78/// collectors and 2 integer collectors:
79/// @code
80/// bslma::Allocator *allocator = bslma::Default::allocator(0);
81/// balm::MetricRegistry metricRegistry(allocator);
82/// balm::CollectorRepository repository(&metricRegistry, allocator);
83///
84/// balm::Collector *collector1 = repository.getDefaultCollector("Test", "C1");
85/// balm::Collector *collector2 = repository.getDefaultCollector("Test", "C2");
86/// balm::IntegerCollector *intCollector1 =
87/// repository.getDefaultIntegerCollector("Test", "C3");
88/// balm::IntegerCollector *intCollector2 =
89/// repository.getDefaultIntegerCollector("Test", "C4");
90///
91/// assert(collector1 != collector2);
92/// assert(collector1 == repository.getDefaultCollector("Test", "C1"));
93/// assert(intCollector1 != intCollector2);
94/// assert(intCollector1 ==
95/// repository.getDefaultIntegerCollector("Test", "C3"));
96/// @endcode
97/// We now update the values in those collectors:
98/// @code
99/// collector1->update(1.0);
100/// collector1->update(2.0);
101/// collector2->update(4.0);
102///
103/// intCollector1->update(5);
104/// intCollector2->update(6);
105/// @endcode
106/// We can use the repository to collect recorded values from the collectors it
107/// manages. Since there are collectors for four metrics, there should be four
108/// recorded values. Note the order in which the records are returned is
109/// undefined.
110/// @code
111/// bsl::vector<balm::MetricRecord> records(allocator);
112/// repository.collectAndReset(&records, metricRegistry.getCategory("Test"));
113/// assert(4 == records.size());
114/// @endcode
115/// Finally we write the recorded values to the console:
116/// @code
117/// bsl::vector<balm::MetricRecord>::const_iterator it;
118/// for (it = records.begin(); it != records.end(); ++it) {
119/// bsl::cout << *it << bsl::endl;
120/// }
121/// @endcode
122/// The output of the for-loop should be:
123/// @code
124/// [ Test.C1: 2 3 1 2 ]
125/// [ Test.C2: 1 4 4 4 ]
126/// [ Test.C3: 1 5 5 5 ]
127/// [ Test.C4: 1 6 6 6 ]
128/// @endcode
129/// @}
130/** @} */
131/** @} */
132
133/** @addtogroup bal
134 * @{
135 */
136/** @addtogroup balm
137 * @{
138 */
139/** @addtogroup balm_collectorrepository
140 * @{
141 */
142
143#include <balscm_version.h>
144
145#include <balm_collector.h>
147#include <balm_metricid.h>
148#include <balm_metricrecord.h>
149#include <balm_metricregistry.h>
150
151#include <bslmt_rwmutex.h>
152
153#include <bslma_allocator.h>
154#include <bslma_default.h>
155
157
158#include <bsl_map.h>
159#include <bsl_memory.h>
160#include <bsl_vector.h>
161
162#include <bsls_libraryfeatures.h>
163
164#include <vector> // 'std::vector', 'std::pmr::vector'
165
166
167namespace balm {
168
169class Category;
170class CollectorRepository_MetricCollectors; // defined in implementation
171
172 // =========================
173 // class CollectorRepository
174 // =========================
175
176/// This class defines a fully thread-safe repository mechanism for
177/// `Collector` and `IntegerCollector` objects. Collectors are identified
178/// in the repository by a `MetricId` object and also grouped together
179/// according to the category of the metric. This repository supports
180/// operations to create, find, and collect metric records from the
181/// collectors in the repository.
182///
183/// See @ref balm_collectorrepository
185
186 // PRIVATE TYPES
187
188 /// `MetricCollectors` is an alias for the (private) implementation type
189 /// that contains the collectors and integer collectors for a single
190 /// metric id.
191 typedef CollectorRepository_MetricCollectors MetricCollectors;
192
193 /// `MetricCollectorsPtr` is an alias for a shared pointer to a
194 /// `MetricRepository_MetricCollectors` object.
195 typedef bsl::shared_ptr<MetricCollectors> MetricCollectorsSPtr;
196
197 /// `Collectors` is an alias for a map from a `MetricId` object to the
198 /// collectors and integer collectors for that metric.
200
201 /// `CategorizedCollectors` is an alias for a map from a category to
202 /// the list of metric collectors belonging to that category.
203 ///
204 /// \note Note that each `MetricCollectors` instance contains all the collectors
205 /// for a single metric.
206 typedef bsl::map<const Category *,
208
209 // DATA
210 MetricRegistry *d_registry_p; // registry of ids (held, not owned)
211 Collectors d_collectors; // collectors (owned)
212 CategorizedCollectors d_categories; // map of category => collectors
213 mutable bslmt::RWMutex d_rwMutex; // data lock
214 bslma::Allocator *d_allocator_p; // allocator (held, not owned)
215
216 private:
217 // NOT IMPLEMENTED
219 CollectorRepository& operator=(const CollectorRepository& );
220
221 private:
222 // PRIVATE MANIPULATORS
223
224 /// Append to the specified `records` the collected metric record
225 /// values from the collectors in this repository belonging to the
226 /// specified `category`; then reset those collectors to their default
227 /// values.
228 template <class VECTOR>
229 void collectAndResetImp(VECTOR *records,
230 const Category *category);
231
232 /// Append to the specified `records` the collected metric record
233 /// values from the collectors in this repository belonging to the specified `category`.
234 ///
235 /// \note Note that this operation does not reset the
236 /// managed collectors, so subsequent collection operations will
237 /// effectively re-collect the current values.
238 template <class VECTOR>
239 void collectImp(VECTOR *records,
240 const Category *category);
241
242 /// Return a reference to the modifiable collectors associated with the
243 /// specified `metricId`. If a collection of collectors for the
244 /// `metricId` does not already exist, create one and add it to the map
245 /// of `Collectors` (`d_collectors`) and also the map of
246 /// `CategorizedCollectors` (`d_categories`).
247 ///
248 /// \pre The behavior is undefined unless the calling thread has a *write* *lock* to `d_rwMutex` and
249 /// `metricId` is valid.
250 MetricCollectors& getMetricCollectors(const MetricId& metricId);
251
252 public:
253 // PUBLIC TRAITS
256
257 // CREATORS
258
259 /// Create an empty collector repository that will use the specified
260 /// `registry` to identify the metrics for which it manages collectors.
261 /// Optionally specify a `basicAllocator` used to supply memory. If
262 /// `basicAllocator` is 0, the currently installed default allocator is used.
263 ///
264 /// \pre The behavior is undefined if `registry` is 0.
266 bslma::Allocator *basicAllocator = 0);
267
268 /// Free all the collectors in this repository and destroy this object.
270
271 // MANIPULATORS
273 const Category *category);
274 void collectAndReset(std::vector<MetricRecord> *records,
275 const Category *category);
276#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
277 void collectAndReset(std::pmr::vector<MetricRecord> *records,
278 const Category *category);
279#endif
280 // Append to the specified 'records' the collected metric record
281 // values from the collectors in this repository belonging to the
282 // specified 'category'; then reset those collectors to their default
283 // values.
284
286 const Category *category);
287 void collect(std::vector<MetricRecord> *records,
288 const Category *category);
289#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
290 void collect(std::pmr::vector<MetricRecord> *records,
291 const Category *category);
292#endif
293 // Append to the specified 'records' the collected metric record
294 // values from the collectors in this repository belonging to the
295 // specified 'category'. Note that this operation does not reset the
296 // managed collectors, so subsequent collection operations will
297 // effectively re-collect the current values.
298
299 /// Return the address of the modifiable default collector identified by
300 /// the specified null-terminated strings `category` and `metricName`.
301 /// If a collector for the identified metric does not already exist in
302 /// the repository, create one, add it to the repository, and return its
303 /// address. In addition, if the identified metric has not already been
304 /// registered, add the identified metric to the `metricRegistry` supplied at construction.
305 ///
306 /// \note Note that this operation is logically
307 /// equivalent to:
308 /// @code
309 /// getDefaultCollector(registry().getId(category, metricName))
310 /// @endcode
311 Collector *getDefaultCollector(const char *category,
312 const char *metricName);
313
314 /// Return the address of the modifiable default collector identified by
315 /// the specified `metricId`. If a default collector for the identified
316 /// metric does not already exist in the repository, create one, add it
317 /// to the repository, and return its address.
319
320 /// Return the address of the modifiable default integer collector
321 /// identified by the specified `category` and `metricName`. If a
322 /// default integer collector for the identified metric does not
323 /// already exist in the repository, create one, add it to the
324 /// repository, and return its address. In addition, if the identified
325 /// metric has not already been registered, add the identified metric
326 /// to the `metricRegistry` supplied at construction.
327 ///
328 /// \pre The behavior is undefined unless `category` and `metricName` are null-terminated.
329 ///
330 /// \note Note that this operation is logically equivalent to:
331 /// @code
332 /// getDefaultIntegerCollector(registry().getId(category, metricName))
333 /// @endcode
334 IntegerCollector *getDefaultIntegerCollector(const char *category,
335 const char *metricName);
336
337 /// Return the address of the modifiable default integer collector
338 /// identified by the specified `metricId`. If a default integer
339 /// collector for the identified metric does not already exist in the
340 /// repository, create one, add it to the repository, and return its
341 /// address.
343
344 /// Return a shared pointer to a newly-created modifiable collector
345 /// identified by the specified null-terminated strings `category` and
346 /// `metricName`, and add that collector to the repository. If is not
347 /// already registered, also add the identified metric to the `metricRegistry` supplied at construction.
348 ///
349 /// \note Note that this operation
350 /// is logically equivalent to:
351 /// @code
352 /// addCollector(registry().getId(category, metricName))
353 /// @endcode
354 bsl::shared_ptr<Collector> addCollector(const char *category,
355 const char *metricName);
356
357 /// Return a shared pointer to a newly-created modifiable collector
358 /// identified by the specified `metricId` and add that collector to the repository.
359 ///
360 /// \pre The behavior is undefined unless `metricId` is a valid
361 /// id returned by the `MetricRepository` supplied at construction.
363
364 /// Return a shared pointer to a newly created modifiable integer
365 /// collector identified by the specified `category` and `metricName`
366 /// and add that collector to the repository. If is not already
367 /// registered, also add the identified metric to the `metricRegistry` supplied at construction.
368 ///
369 /// \pre The behavior is undefined unless `category` and `metricName` are null-terminated.
370 ///
371 /// \note Note that this
372 /// operation is logically equivalent to:
373 /// @code
374 /// addIntegerCollector(registry().getId(category, metricName))
375 /// @endcode
377 const char *category,
378 const char *metricName);
379
380 /// Return a shared pointer to a newly-created modifiable collector
381 /// identified by the specified `metricId` and add that collector to the repository.
382 ///
383 /// \pre The behavior is undefined unless `metricId` is a valid
384 /// id returned by the `MetricRepository` supplied at construction.
386 const MetricId& metricId);
387
391 const MetricId& metricId);
393 std::vector<bsl::shared_ptr<Collector> > *collectors,
394 std::vector<bsl::shared_ptr<IntegerCollector> > *intCollectors,
395 const MetricId& metricId);
396#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
398 std::pmr::vector<bsl::shared_ptr<Collector> > *collectors,
399 std::pmr::vector<bsl::shared_ptr<IntegerCollector> > *intCollectors,
400 const MetricId& metricId);
401#endif
402 // Append to the specified 'collectors' and 'intCollectors' shared
403 // pointers to any collectors, and integer collectors, collecting
404 // values for the metrics identified by the specified 'metricId' that
405 // were added using the 'addCollector' or 'addIntegerCollector'
406 // methods, and return the combined total number of collectors and
407 // integer collectors that were found. This method does *not* count
408 // or return the default collectors for 'metricId'. The behavior is
409 // undefined unless 'metricId' is a valid id returned by the
410 // 'MetricRepository' supplied at construction.
411
412 /// Return a reference to the modifiable registry of metrics used by
413 /// this collector repository.
415
416 // ACCESSORS
417
418 /// Return a reference to the non-modifiable registry of metrics used by
419 /// this collector repository.
420 const MetricRegistry& registry() const;
421};
422
423// ============================================================================
424// INLINE DEFINITIONS
425// ============================================================================
426
427 // -------------------------
428 // class CollectorRepository
429 // -------------------------
430
431// CREATORS
432inline
433CollectorRepository::CollectorRepository(MetricRegistry *registry,
434 bslma::Allocator *basicAllocator)
435: d_registry_p(registry)
436, d_collectors(basicAllocator)
437, d_categories(basicAllocator)
438, d_rwMutex()
439, d_allocator_p(bslma::Default::allocator(basicAllocator))
440{
441}
442
443inline
447
448// MANIPULATORS
449inline
451 const char *metricName)
452{
453 return getDefaultCollector(d_registry_p->getId(category, metricName));
454}
455
456inline
458 const char *category,
459 const char *metricName)
460{
461 return getDefaultIntegerCollector(d_registry_p->getId(category,
462 metricName));
463}
464
465inline
467 const char *category,
468 const char *metricName)
469{
470 return addCollector(d_registry_p->getId(category, metricName));
471}
472
473inline
476 const char *metricName)
477{
478 return addIntegerCollector(d_registry_p->getId(category, metricName));
479}
480
481inline
483{
484 return *d_registry_p;
485}
486
487// ACCESSORS
488inline
490{
491 return *d_registry_p;
492}
493} // close package namespace
494
495
496
497#endif
498
499// ----------------------------------------------------------------------------
500// Copyright 2015 Bloomberg Finance L.P.
501//
502// Licensed under the Apache License, Version 2.0 (the "License");
503// you may not use this file except in compliance with the License.
504// You may obtain a copy of the License at
505//
506// http://www.apache.org/licenses/LICENSE-2.0
507//
508// Unless required by applicable law or agreed to in writing, software
509// distributed under the License is distributed on an "AS IS" BASIS,
510// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
511// See the License for the specific language governing permissions and
512// limitations under the License.
513// ----------------------------- END-OF-FILE ----------------------------------
514
515/** @} */
516/** @} */
517/** @} */
Definition balm_category.h:152
Definition balm_collectorrepository.h:184
Collector * getDefaultCollector(const MetricId &metricId)
MetricRegistry & registry()
Definition balm_collectorrepository.h:482
int getAddedCollectors(bsl::vector< bsl::shared_ptr< Collector > > *collectors, bsl::vector< bsl::shared_ptr< IntegerCollector > > *intCollectors, const MetricId &metricId)
IntegerCollector * getDefaultIntegerCollector(const char *category, const char *metricName)
Definition balm_collectorrepository.h:457
int getAddedCollectors(std::vector< bsl::shared_ptr< Collector > > *collectors, std::vector< bsl::shared_ptr< IntegerCollector > > *intCollectors, const MetricId &metricId)
bsl::shared_ptr< Collector > addCollector(const MetricId &metricId)
void collect(bsl::vector< MetricRecord > *records, const Category *category)
IntegerCollector * getDefaultIntegerCollector(const MetricId &metricId)
bsl::shared_ptr< IntegerCollector > addIntegerCollector(const char *category, const char *metricName)
Definition balm_collectorrepository.h:475
bsl::shared_ptr< Collector > addCollector(const char *category, const char *metricName)
Definition balm_collectorrepository.h:466
bsl::shared_ptr< IntegerCollector > addIntegerCollector(const MetricId &metricId)
void collectAndReset(bsl::vector< MetricRecord > *records, const Category *category)
Collector * getDefaultCollector(const char *category, const char *metricName)
Definition balm_collectorrepository.h:450
void collectAndReset(std::vector< MetricRecord > *records, const Category *category)
~CollectorRepository()
Free all the collectors in this repository and destroy this object.
Definition balm_collectorrepository.h:444
BSLMF_NESTED_TRAIT_DECLARATION(CollectorRepository, bslma::UsesBslmaAllocator)
void collect(std::vector< MetricRecord > *records, const Category *category)
Definition balm_collector.h:152
Definition balm_integercollector.h:151
Definition balm_metricid.h:162
Definition balm_metricregistry.h:180
MetricId getId(const char *category, const char *name)
Definition bslstl_map.h:653
Definition bslstl_sharedptr.h:1838
Definition bslstl_vector.h:1120
Definition bslma_allocator.h:545
Definition bslmt_rwmutex.h:148
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition balm_bdlmmetricsadapter.h:142
Definition baljsn_encoder_testtypes.h:76
Definition bslma_usesbslmaallocator.h:344