BDE 4.14.0 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.
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. Note
203 /// that each `MetricCollectors` instance contains all the collectors
204 /// for a single metric.
205 typedef bsl::map<const Category *,
207
208 // DATA
209 MetricRegistry *d_registry_p; // registry of ids (held, not owned)
210 Collectors d_collectors; // collectors (owned)
211 CategorizedCollectors d_categories; // map of category => collectors
212 mutable bslmt::RWMutex d_rwMutex; // data lock
213 bslma::Allocator *d_allocator_p; // allocator (held, not owned)
214
215 // NOT IMPLEMENTED
217 CollectorRepository& operator=(const CollectorRepository& );
218
219 private:
220 // PRIVATE MANIPULATORS
221
222 /// Append to the specified `records` the collected metric record
223 /// values from the collectors in this repository belonging to the
224 /// specified `category`; then reset those collectors to their default
225 /// values.
226 template <class VECTOR>
227 void collectAndResetImp(VECTOR *records,
228 const Category *category);
229
230 /// Append to the specified `records` the collected metric record
231 /// values from the collectors in this repository belonging to the
232 /// specified `category`. Note that this operation does not reset the
233 /// managed collectors, so subsequent collection operations will
234 /// effectively re-collect the current values.
235 template <class VECTOR>
236 void collectImp(VECTOR *records,
237 const Category *category);
238
239 /// Return a reference to the modifiable collectors associated with the
240 /// specified `metricId`. If a collection of collectors for the
241 /// `metricId` does not already exist, create one and add it to the map
242 /// of `Collectors` (`d_collectors`) and also the map of
243 /// `CategorizedCollectors` (`d_categories`). The behavior is undefined
244 /// unless the calling thread has a *write* *lock* to `d_rwMutex` and
245 /// `metricId` is valid.
246 MetricCollectors& getMetricCollectors(const MetricId& metricId);
247
248 public:
249 // PUBLIC TRAITS
252
253 // CREATORS
254
255 /// Create an empty collector repository that will use the specified
256 /// `registry` to identify the metrics for which it manages collectors.
257 /// Optionally specify a `basicAllocator` used to supply memory. If
258 /// `basicAllocator` is 0, the currently installed default allocator is
259 /// used. The behavior is undefined if `registry` is 0.
261 bslma::Allocator *basicAllocator = 0);
262
263 /// Free all the collectors in this repository and destroy this object.
265
266 // MANIPULATORS
268 const Category *category);
269 void collectAndReset(std::vector<MetricRecord> *records,
270 const Category *category);
271#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
272 void collectAndReset(std::pmr::vector<MetricRecord> *records,
273 const Category *category);
274#endif
275 // Append to the specified 'records' the collected metric record
276 // values from the collectors in this repository belonging to the
277 // specified 'category'; then reset those collectors to their default
278 // values.
279
281 const Category *category);
282 void collect(std::vector<MetricRecord> *records,
283 const Category *category);
284#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
285 void collect(std::pmr::vector<MetricRecord> *records,
286 const Category *category);
287#endif
288 // Append to the specified 'records' the collected metric record
289 // values from the collectors in this repository belonging to the
290 // specified 'category'. Note that this operation does not reset the
291 // managed collectors, so subsequent collection operations will
292 // effectively re-collect the current values.
293
294 /// Return the address of the modifiable default collector identified by
295 /// the specified null-terminated strings `category` and `metricName`.
296 /// If a collector for the identified metric does not already exist in
297 /// the repository, create one, add it to the repository, and return its
298 /// address. In addition, if the identified metric has not already been
299 /// registered, add the identified metric to the `metricRegistry`
300 /// supplied at construction. Note that this operation is logically
301 /// equivalent to:
302 /// @code
303 /// getDefaultCollector(registry().getId(category, metricName))
304 /// @endcode
305 Collector *getDefaultCollector(const char *category,
306 const char *metricName);
307
308 /// Return the address of the modifiable default collector identified by
309 /// the specified `metricId`. If a default collector for the identified
310 /// metric does not already exist in the repository, create one, add it
311 /// to the repository, and return its address.
313
314 /// Return the address of the modifiable default integer collector
315 /// identified by the specified `category` and `metricName`. If a
316 /// default integer collector for the identified metric does not
317 /// already exist in the repository, create one, add it to the
318 /// repository, and return its address. In addition, if the identified
319 /// metric has not already been registered, add the identified metric
320 /// to the `metricRegistry` supplied at construction. The behavior is
321 /// undefined unless `category` and `metricName` are null-terminated.
322 /// Note that this operation is logically equivalent to:
323 /// @code
324 /// getDefaultIntegerCollector(registry().getId(category, metricName))
325 /// @endcode
326 IntegerCollector *getDefaultIntegerCollector(const char *category,
327 const char *metricName);
328
329 /// Return the address of the modifiable default integer collector
330 /// identified by the specified `metricId`. If a default integer
331 /// collector for the identified metric does not already exist in the
332 /// repository, create one, add it to the repository, and return its
333 /// address.
335
336 /// Return a shared pointer to a newly-created modifiable collector
337 /// identified by the specified null-terminated strings `category` and
338 /// `metricName`, and add that collector to the repository. If is not
339 /// already registered, also add the identified metric to the
340 /// `metricRegistry` supplied at construction. Note that this operation
341 /// is logically equivalent to:
342 /// @code
343 /// addCollector(registry().getId(category, metricName))
344 /// @endcode
345 bsl::shared_ptr<Collector> addCollector(const char *category,
346 const char *metricName);
347
348 /// Return a shared pointer to a newly-created modifiable collector
349 /// identified by the specified `metricId` and add that collector to the
350 /// repository. The behavior is undefined unless `metricId` is a valid
351 /// id returned by the `MetricRepository` supplied at construction.
353
354 /// Return a shared pointer to a newly created modifiable integer
355 /// collector identified by the specified `category` and `metricName`
356 /// and add that collector to the repository. If is not already
357 /// registered, also add the identified metric to the `metricRegistry`
358 /// supplied at construction. The behavior is undefined unless
359 /// `category` and `metricName` are null-terminated. Note that this
360 /// operation is logically equivalent to:
361 /// @code
362 /// addIntegerCollector(registry().getId(category, metricName))
363 /// @endcode
365 const char *category,
366 const char *metricName);
367
368 /// Return a shared pointer to a newly-created modifiable collector
369 /// identified by the specified `metricId` and add that collector to the
370 /// repository. The behavior is undefined unless `metricId` is a valid
371 /// id returned by the `MetricRepository` supplied at construction.
373 const MetricId& metricId);
374
378 const MetricId& metricId);
380 std::vector<bsl::shared_ptr<Collector> > *collectors,
381 std::vector<bsl::shared_ptr<IntegerCollector> > *intCollectors,
382 const MetricId& metricId);
383#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
385 std::pmr::vector<bsl::shared_ptr<Collector> > *collectors,
386 std::pmr::vector<bsl::shared_ptr<IntegerCollector> > *intCollectors,
387 const MetricId& metricId);
388#endif
389 // Append to the specified 'collectors' and 'intCollectors' shared
390 // pointers to any collectors, and integer collectors, collecting
391 // values for the metrics identified by the specified 'metricId' that
392 // were added using the 'addCollector' or 'addIntegerCollector'
393 // methods, and return the combined total number of collectors and
394 // integer collectors that were found. This method does *not* count
395 // or return the default collectors for 'metricId'. The behavior is
396 // undefined unless 'metricId' is a valid id returned by the
397 // 'MetricRepository' supplied at construction.
398
399 /// Return a reference to the modifiable registry of metrics used by
400 /// this collector repository.
402
403 // ACCESSORS
404
405 /// Return a reference to the non-modifiable registry of metrics used by
406 /// this collector repository.
407 const MetricRegistry& registry() const;
408};
409
410// ============================================================================
411// INLINE DEFINITIONS
412// ============================================================================
413
414 // -------------------------
415 // class CollectorRepository
416 // -------------------------
417
418// CREATORS
419inline
420CollectorRepository::CollectorRepository(MetricRegistry *registry,
421 bslma::Allocator *basicAllocator)
422: d_registry_p(registry)
423, d_collectors(basicAllocator)
424, d_categories(basicAllocator)
425, d_rwMutex()
426, d_allocator_p(bslma::Default::allocator(basicAllocator))
427{
428}
429
430inline
434
435// MANIPULATORS
436inline
438 const char *metricName)
439{
440 return getDefaultCollector(d_registry_p->getId(category, metricName));
441}
442
443inline
445 const char *category,
446 const char *metricName)
447{
448 return getDefaultIntegerCollector(d_registry_p->getId(category,
449 metricName));
450}
451
452inline
454 const char *category,
455 const char *metricName)
456{
457 return addCollector(d_registry_p->getId(category, metricName));
458}
459
460inline
463 const char *metricName)
464{
465 return addIntegerCollector(d_registry_p->getId(category, metricName));
466}
467
468inline
470{
471 return *d_registry_p;
472}
473
474// ACCESSORS
475inline
477{
478 return *d_registry_p;
479}
480} // close package namespace
481
482
483
484#endif
485
486// ----------------------------------------------------------------------------
487// Copyright 2015 Bloomberg Finance L.P.
488//
489// Licensed under the Apache License, Version 2.0 (the "License");
490// you may not use this file except in compliance with the License.
491// You may obtain a copy of the License at
492//
493// http://www.apache.org/licenses/LICENSE-2.0
494//
495// Unless required by applicable law or agreed to in writing, software
496// distributed under the License is distributed on an "AS IS" BASIS,
497// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
498// See the License for the specific language governing permissions and
499// limitations under the License.
500// ----------------------------- END-OF-FILE ----------------------------------
501
502/** @} */
503/** @} */
504/** @} */
Definition balm_category.h:151
Definition balm_collectorrepository.h:184
Collector * getDefaultCollector(const MetricId &metricId)
MetricRegistry & registry()
Definition balm_collectorrepository.h:469
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:444
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:462
bsl::shared_ptr< Collector > addCollector(const char *category, const char *metricName)
Definition balm_collectorrepository.h:453
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:437
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:431
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:619
Definition bslstl_sharedptr.h:1830
Definition bslstl_vector.h:1025
Definition bslma_allocator.h:457
Definition bslmt_rwmutex.h:147
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition balm_bdlmmetricsadapter.h:141
Definition balxml_encoderoptions.h:68
Definition bslma_usesbslmaallocator.h:343