Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
50d010ca
Commit
50d010ca
authored
Jun 18, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make histogram buckets configurable per label
parent
c6d2df52
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
450 additions
and
90 deletions
+450
-90
libcaf_core/caf/actor_system.hpp
libcaf_core/caf/actor_system.hpp
+3
-3
libcaf_core/caf/telemetry/counter.hpp
libcaf_core/caf/telemetry/counter.hpp
+3
-1
libcaf_core/caf/telemetry/dbl_gauge.hpp
libcaf_core/caf/telemetry/dbl_gauge.hpp
+5
-0
libcaf_core/caf/telemetry/histogram.hpp
libcaf_core/caf/telemetry/histogram.hpp
+40
-13
libcaf_core/caf/telemetry/int_gauge.hpp
libcaf_core/caf/telemetry/int_gauge.hpp
+7
-0
libcaf_core/caf/telemetry/metric.hpp
libcaf_core/caf/telemetry/metric.hpp
+1
-1
libcaf_core/caf/telemetry/metric_family_impl.hpp
libcaf_core/caf/telemetry/metric_family_impl.hpp
+21
-2
libcaf_core/caf/telemetry/metric_impl.hpp
libcaf_core/caf/telemetry/metric_impl.hpp
+2
-2
libcaf_core/caf/telemetry/metric_registry.hpp
libcaf_core/caf/telemetry/metric_registry.hpp
+259
-59
libcaf_core/src/actor_system.cpp
libcaf_core/src/actor_system.cpp
+1
-0
libcaf_core/src/telemetry/metric_registry.cpp
libcaf_core/src/telemetry/metric_registry.cpp
+75
-1
libcaf_core/test/telemetry/collector/prometheus.cpp
libcaf_core/test/telemetry/collector/prometheus.cpp
+1
-2
libcaf_core/test/telemetry/metric_registry.cpp
libcaf_core/test/telemetry/metric_registry.cpp
+32
-6
No files found.
libcaf_core/caf/actor_system.hpp
View file @
50d010ca
...
@@ -599,9 +599,6 @@ private:
...
@@ -599,9 +599,6 @@ private:
// -- member variables -------------------------------------------------------
// -- member variables -------------------------------------------------------
/// Manages all metrics collected by the system.
telemetry
::
metric_registry
metrics_
;
/// Provides system-wide callbacks for several actor operations.
/// Provides system-wide callbacks for several actor operations.
actor_profiler
*
profiler_
;
actor_profiler
*
profiler_
;
...
@@ -647,6 +644,9 @@ private:
...
@@ -647,6 +644,9 @@ private:
/// The system-wide, user-provided configuration.
/// The system-wide, user-provided configuration.
actor_system_config
&
cfg_
;
actor_system_config
&
cfg_
;
/// Manages all metrics collected by the system.
telemetry
::
metric_registry
metrics_
;
/// Stores whether the logger has run its destructor and stopped any thread,
/// Stores whether the logger has run its destructor and stopped any thread,
/// file handle, etc.
/// file handle, etc.
std
::
atomic
<
bool
>
logger_dtor_done_
;
std
::
atomic
<
bool
>
logger_dtor_done_
;
...
...
libcaf_core/caf/telemetry/counter.hpp
View file @
50d010ca
...
@@ -22,7 +22,9 @@
...
@@ -22,7 +22,9 @@
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/span.hpp"
#include "caf/telemetry/gauge.hpp"
#include "caf/telemetry/gauge.hpp"
#include "caf/telemetry/label.hpp"
namespace
caf
::
telemetry
{
namespace
caf
::
telemetry
{
...
@@ -50,7 +52,7 @@ public:
...
@@ -50,7 +52,7 @@ public:
// nop
// nop
}
}
explicit
counter
(
const
std
::
vector
<
label
>&
)
noexcept
{
explicit
counter
(
span
<
const
label
>
)
noexcept
{
// nop
// nop
}
}
...
...
libcaf_core/caf/telemetry/dbl_gauge.hpp
View file @
50d010ca
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
#include <atomic>
#include <atomic>
#include <cstdint>
#include <cstdint>
#include "caf/telemetry/label.hpp"
#include "caf/telemetry/metric_type.hpp"
#include "caf/telemetry/metric_type.hpp"
namespace
caf
::
telemetry
{
namespace
caf
::
telemetry
{
...
@@ -51,6 +52,10 @@ public:
...
@@ -51,6 +52,10 @@ public:
// nop
// nop
}
}
explicit
dbl_gauge
(
span
<
const
label
>
)
noexcept
:
value_
(
0
)
{
// nop
}
// -- modifiers --------------------------------------------------------------
// -- modifiers --------------------------------------------------------------
/// Increments the gauge by 1.
/// Increments the gauge by 1.
...
...
libcaf_core/caf/telemetry/histogram.hpp
View file @
50d010ca
...
@@ -23,9 +23,11 @@
...
@@ -23,9 +23,11 @@
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/settings.hpp"
#include "caf/span.hpp"
#include "caf/span.hpp"
#include "caf/telemetry/counter.hpp"
#include "caf/telemetry/counter.hpp"
#include "caf/telemetry/gauge.hpp"
#include "caf/telemetry/gauge.hpp"
#include "caf/telemetry/label.hpp"
#include "caf/telemetry/metric_type.hpp"
#include "caf/telemetry/metric_type.hpp"
namespace
caf
::
telemetry
{
namespace
caf
::
telemetry
{
...
@@ -57,22 +59,15 @@ public:
...
@@ -57,22 +59,15 @@ public:
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
explicit
histogram
(
span
<
const
value_type
>
upper_bounds
)
{
histogram
(
span
<
const
label
>
labels
,
const
settings
*
cfg
,
using
limits
=
std
::
numeric_limits
<
value_type
>
;
span
<
const
value_type
>
upper_bounds
)
{
CAF_ASSERT
(
std
::
is_sorted
(
upper_bounds
.
begin
(),
upper_bounds
.
end
()));
if
(
!
init_buckets_from_config
(
labels
,
cfg
))
num_buckets_
=
upper_bounds
.
size
()
+
1
;
init_buckets
(
upper_bounds
);
buckets_
=
new
bucket_type
[
num_buckets_
];
size_t
index
=
0
;
for
(;
index
<
upper_bounds
.
size
();
++
index
)
buckets_
[
index
].
upper_bound
=
upper_bounds
[
index
];
if
constexpr
(
limits
::
has_infinity
)
buckets_
[
index
].
upper_bound
=
limits
::
infinity
();
else
buckets_
[
index
].
upper_bound
=
limits
::
max
();
}
}
explicit
histogram
(
std
::
initializer_list
<
value_type
>
upper_bounds
)
explicit
histogram
(
std
::
initializer_list
<
value_type
>
upper_bounds
)
:
histogram
(
make_span
(
upper_bounds
.
begin
(),
upper_bounds
.
size
()))
{
:
histogram
({},
nullptr
,
make_span
(
upper_bounds
.
begin
(),
upper_bounds
.
size
()))
{
// nop
// nop
}
}
...
@@ -86,6 +81,8 @@ public:
...
@@ -86,6 +81,8 @@ public:
// -- modifiers --------------------------------------------------------------
// -- modifiers --------------------------------------------------------------
/// Increments the bucket where the observed value falls into and increments
/// the sum of all observed values.
void
observe
(
value_type
value
)
{
void
observe
(
value_type
value
)
{
// The last bucket has an upper bound of +inf or int_max, so we'll always
// The last bucket has an upper bound of +inf or int_max, so we'll always
// find a bucket and increment the counters.
// find a bucket and increment the counters.
...
@@ -101,15 +98,45 @@ public:
...
@@ -101,15 +98,45 @@ public:
// -- observers --------------------------------------------------------------
// -- observers --------------------------------------------------------------
/// Returns the ``counter`` objects with the configured upper bounds.
span
<
const
bucket_type
>
buckets
()
const
noexcept
{
span
<
const
bucket_type
>
buckets
()
const
noexcept
{
return
{
buckets_
,
num_buckets_
};
return
{
buckets_
,
num_buckets_
};
}
}
/// Returns the sum of all observed values.
value_type
sum
()
const
noexcept
{
value_type
sum
()
const
noexcept
{
return
sum_
.
value
();
return
sum_
.
value
();
}
}
private:
private:
void
init_buckets
(
span
<
const
value_type
>
upper_bounds
)
{
CAF_ASSERT
(
std
::
is_sorted
(
upper_bounds
.
begin
(),
upper_bounds
.
end
()));
using
limits
=
std
::
numeric_limits
<
value_type
>
;
num_buckets_
=
upper_bounds
.
size
()
+
1
;
buckets_
=
new
bucket_type
[
num_buckets_
];
size_t
index
=
0
;
for
(;
index
<
upper_bounds
.
size
();
++
index
)
buckets_
[
index
].
upper_bound
=
upper_bounds
[
index
];
if
constexpr
(
limits
::
has_infinity
)
buckets_
[
index
].
upper_bound
=
limits
::
infinity
();
else
buckets_
[
index
].
upper_bound
=
limits
::
max
();
}
bool
init_buckets_from_config
(
span
<
const
label
>
labels
,
const
settings
*
cfg
)
{
if
(
cfg
==
nullptr
||
labels
.
empty
())
return
false
;
for
(
const
auto
&
lbl
:
labels
)
{
if
(
auto
ptr
=
get_if
<
settings
>
(
cfg
,
lbl
.
str
()))
{
if
(
auto
bounds
=
get_if
<
std
::
vector
<
value_type
>>
(
ptr
,
"buckets"
))
{
init_buckets
(
*
bounds
);
return
true
;
}
}
}
return
false
;
}
size_t
num_buckets_
;
size_t
num_buckets_
;
bucket_type
*
buckets_
;
bucket_type
*
buckets_
;
gauge_type
sum_
;
gauge_type
sum_
;
...
...
libcaf_core/caf/telemetry/int_gauge.hpp
View file @
50d010ca
...
@@ -23,6 +23,9 @@
...
@@ -23,6 +23,9 @@
#include <atomic>
#include <atomic>
#include <cstdint>
#include <cstdint>
#include "caf/fwd.hpp"
#include "caf/span.hpp"
#include "caf/telemetry/label.hpp"
#include "caf/telemetry/metric_type.hpp"
#include "caf/telemetry/metric_type.hpp"
namespace
caf
::
telemetry
{
namespace
caf
::
telemetry
{
...
@@ -51,6 +54,10 @@ public:
...
@@ -51,6 +54,10 @@ public:
// nop
// nop
}
}
explicit
int_gauge
(
span
<
const
label
>
)
noexcept
:
value_
(
0
)
{
// nop
}
// -- modifiers --------------------------------------------------------------
// -- modifiers --------------------------------------------------------------
/// Increments the gauge by 1.
/// Increments the gauge by 1.
...
...
libcaf_core/caf/telemetry/metric.hpp
View file @
50d010ca
...
@@ -45,7 +45,7 @@ public:
...
@@ -45,7 +45,7 @@ public:
return
labels_
;
return
labels_
;
}
}
pr
ivate
:
pr
otected
:
// -- member variables -------------------------------------------------------
// -- member variables -------------------------------------------------------
std
::
vector
<
label
>
labels_
;
std
::
vector
<
label
>
labels_
;
...
...
libcaf_core/caf/telemetry/metric_family_impl.hpp
View file @
50d010ca
...
@@ -42,6 +42,19 @@ public:
...
@@ -42,6 +42,19 @@ public:
using
extra_setting_type
=
typename
impl_type
::
family_setting
;
using
extra_setting_type
=
typename
impl_type
::
family_setting
;
template
<
class
...
Ts
>
metric_family_impl
(
const
settings
*
config
,
std
::
string
prefix
,
std
::
string
name
,
std
::
vector
<
std
::
string
>
label_names
,
std
::
string
helptext
,
std
::
string
unit
,
bool
is_sum
,
Ts
&&
...
xs
)
:
super
(
Type
::
runtime_type
,
std
::
move
(
prefix
),
std
::
move
(
name
),
std
::
move
(
label_names
),
std
::
move
(
helptext
),
std
::
move
(
unit
),
is_sum
),
config_
(
config
),
extra_setting_
(
std
::
forward
<
Ts
>
(
xs
)...)
{
// nop
}
template
<
class
...
Ts
>
template
<
class
...
Ts
>
metric_family_impl
(
std
::
string
prefix
,
std
::
string
name
,
metric_family_impl
(
std
::
string
prefix
,
std
::
string
name
,
std
::
vector
<
std
::
string
>
label_names
,
std
::
string
helptext
,
std
::
vector
<
std
::
string
>
label_names
,
std
::
string
helptext
,
...
@@ -49,6 +62,7 @@ public:
...
@@ -49,6 +62,7 @@ public:
:
super
(
Type
::
runtime_type
,
std
::
move
(
prefix
),
std
::
move
(
name
),
:
super
(
Type
::
runtime_type
,
std
::
move
(
prefix
),
std
::
move
(
name
),
std
::
move
(
label_names
),
std
::
move
(
helptext
),
std
::
move
(
unit
),
std
::
move
(
label_names
),
std
::
move
(
helptext
),
std
::
move
(
unit
),
is_sum
),
is_sum
),
config_
(
nullptr
),
extra_setting_
(
std
::
forward
<
Ts
>
(
xs
)...)
{
extra_setting_
(
std
::
forward
<
Ts
>
(
xs
)...)
{
// nop
// nop
}
}
...
@@ -68,7 +82,7 @@ public:
...
@@ -68,7 +82,7 @@ public:
if
constexpr
(
std
::
is_same
<
extra_setting_type
,
unit_t
>::
value
)
if
constexpr
(
std
::
is_same
<
extra_setting_type
,
unit_t
>::
value
)
ptr
.
reset
(
new
impl_type
(
std
::
move
(
cpy
)));
ptr
.
reset
(
new
impl_type
(
std
::
move
(
cpy
)));
else
else
ptr
.
reset
(
new
impl_type
(
std
::
move
(
cpy
),
extra_setting_
));
ptr
.
reset
(
new
impl_type
(
std
::
move
(
cpy
),
config_
,
extra_setting_
));
m
=
metrics_
.
emplace
(
m
,
std
::
move
(
ptr
));
m
=
metrics_
.
emplace
(
m
,
std
::
move
(
ptr
));
}
}
return
std
::
addressof
(
m
->
get
()
->
impl
());
return
std
::
addressof
(
m
->
get
()
->
impl
());
...
@@ -80,10 +94,14 @@ public:
...
@@ -80,10 +94,14 @@ public:
// -- properties --
// -- properties --
const
auto
&
extra_setting
()
const
noexcept
{
const
extra_setting_type
&
extra_setting
()
const
noexcept
{
return
extra_setting_
;
return
extra_setting_
;
}
}
const
settings
*
config
()
const
noexcept
{
return
config_
;
}
template
<
class
Collector
>
template
<
class
Collector
>
void
collect
(
Collector
&
collector
)
const
{
void
collect
(
Collector
&
collector
)
const
{
std
::
unique_lock
<
std
::
mutex
>
guard
{
mx_
};
std
::
unique_lock
<
std
::
mutex
>
guard
{
mx_
};
...
@@ -92,6 +110,7 @@ public:
...
@@ -92,6 +110,7 @@ public:
}
}
private:
private:
const
settings
*
config_
;
extra_setting_type
extra_setting_
;
extra_setting_type
extra_setting_
;
mutable
std
::
mutex
mx_
;
mutable
std
::
mutex
mx_
;
std
::
vector
<
std
::
unique_ptr
<
impl_type
>>
metrics_
;
std
::
vector
<
std
::
unique_ptr
<
impl_type
>>
metrics_
;
...
...
libcaf_core/caf/telemetry/metric_impl.hpp
View file @
50d010ca
...
@@ -34,8 +34,8 @@ public:
...
@@ -34,8 +34,8 @@ public:
using
family_setting
=
typename
Type
::
family_setting
;
using
family_setting
=
typename
Type
::
family_setting
;
template
<
class
...
Ts
>
template
<
class
...
Ts
>
metric_impl
(
std
::
vector
<
label
>
labels
,
Ts
&&
...
xs
)
explicit
metric_impl
(
std
::
vector
<
label
>
labels
,
Ts
&&
...
xs
)
:
metric
(
std
::
move
(
labels
)),
impl_
(
std
::
forward
<
Ts
>
(
xs
)...)
{
:
metric
(
std
::
move
(
labels
)),
impl_
(
this
->
labels_
,
std
::
forward
<
Ts
>
(
xs
)...)
{
// nop
// nop
}
}
...
...
libcaf_core/caf/telemetry/metric_registry.hpp
View file @
50d010ca
...
@@ -38,10 +38,25 @@ namespace caf::telemetry {
...
@@ -38,10 +38,25 @@ namespace caf::telemetry {
/// Manages a collection of metric families.
/// Manages a collection of metric families.
class
CAF_CORE_EXPORT
metric_registry
{
class
CAF_CORE_EXPORT
metric_registry
{
public:
public:
// -- member types -----------------------------------------------------------
/// Forces the compiler to use the type `span<const T>` instead of trying to
/// match paremeters to a `span`.
template
<
class
T
>
struct
span_type
{
using
type
=
span
<
const
T
>
;
};
/// Convenience alias to safe some typing.
template
<
class
T
>
using
span_t
=
typename
span_type
<
T
>::
type
;
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
metric_registry
();
metric_registry
();
explicit
metric_registry
(
const
actor_system_config
&
cfg
);
~
metric_registry
();
~
metric_registry
();
// -- factories --------------------------------------------------------------
// -- factories --------------------------------------------------------------
...
@@ -53,7 +68,7 @@ public:
...
@@ -53,7 +68,7 @@ public:
/// as well as prefixes starting with an underscore are
/// as well as prefixes starting with an underscore are
/// reserved.
/// reserved.
/// @param name The human-readable name of the metric, e.g., `requests`.
/// @param name The human-readable name of the metric, e.g., `requests`.
/// @param label
_name
s Names for all label dimensions of the metric.
/// @param labels Names for all label dimensions of the metric.
/// @param helptext Short explanation of the metric.
/// @param helptext Short explanation of the metric.
/// @param unit Unit of measurement. Please use base units such as `bytes` or
/// @param unit Unit of measurement. Please use base units such as `bytes` or
/// `seconds` (prefer lowercase). The pseudo-unit `1` identifies
/// `seconds` (prefer lowercase). The pseudo-unit `1` identifies
...
@@ -63,19 +78,18 @@ public:
...
@@ -63,19 +78,18 @@ public:
/// interest. For example, the total number of HTTP requests.
/// interest. For example, the total number of HTTP requests.
template
<
class
ValueType
=
int64_t
>
template
<
class
ValueType
=
int64_t
>
metric_family_impl
<
gauge
<
ValueType
>>*
metric_family_impl
<
gauge
<
ValueType
>>*
gauge_family
(
string_view
prefix
,
string_view
name
,
gauge_family
(
string_view
prefix
,
string_view
name
,
span_t
<
string_view
>
labels
,
s
pan
<
const
string_view
>
label_names
,
string_view
helptext
,
s
tring_view
helptext
,
string_view
unit
=
"1"
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
bool
is_sum
=
false
)
{
using
gauge_type
=
gauge
<
ValueType
>
;
using
gauge_type
=
gauge
<
ValueType
>
;
using
family_type
=
metric_family_impl
<
gauge_type
>
;
using
family_type
=
metric_family_impl
<
gauge_type
>
;
std
::
unique_lock
<
std
::
mutex
>
guard
{
families_mx_
};
std
::
unique_lock
<
std
::
mutex
>
guard
{
families_mx_
};
if
(
auto
ptr
=
fetch
(
prefix
,
name
))
{
if
(
auto
ptr
=
fetch
(
prefix
,
name
))
{
assert_properties
(
ptr
,
gauge_type
::
runtime_type
,
label_names
,
unit
,
assert_properties
(
ptr
,
gauge_type
::
runtime_type
,
labels
,
unit
,
is_sum
);
is_sum
);
return
static_cast
<
family_type
*>
(
ptr
);
return
static_cast
<
family_type
*>
(
ptr
);
}
}
auto
ptr
=
std
::
make_unique
<
family_type
>
(
to_string
(
prefix
),
to_string
(
name
),
auto
ptr
=
std
::
make_unique
<
family_type
>
(
to_string
(
prefix
),
to_string
(
name
),
to_sorted_vec
(
label
_name
s
),
to_sorted_vec
(
labels
),
to_string
(
helptext
),
to_string
(
helptext
),
to_string
(
unit
),
is_sum
);
to_string
(
unit
),
is_sum
);
auto
result
=
ptr
.
get
();
auto
result
=
ptr
.
get
();
...
@@ -87,14 +101,96 @@ public:
...
@@ -87,14 +101,96 @@ public:
template
<
class
ValueType
=
int64_t
>
template
<
class
ValueType
=
int64_t
>
metric_family_impl
<
gauge
<
ValueType
>>*
metric_family_impl
<
gauge
<
ValueType
>>*
gauge_family
(
string_view
prefix
,
string_view
name
,
gauge_family
(
string_view
prefix
,
string_view
name
,
std
::
initializer_list
<
string_view
>
label_names
,
std
::
initializer_list
<
string_view
>
labels
,
string_view
helptext
,
string_view
helptext
,
string_view
unit
=
"1"
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
bool
is_sum
=
false
)
{
auto
lbl_span
=
make_span
(
labels
.
begin
(),
labels
.
size
());
auto
lbl_span
=
make_span
(
label_names
.
begin
(),
label_names
.
size
());
return
gauge_family
<
ValueType
>
(
prefix
,
name
,
lbl_span
,
helptext
,
unit
,
return
gauge_family
<
ValueType
>
(
prefix
,
name
,
lbl_span
,
helptext
,
unit
,
is_sum
);
is_sum
);
}
}
/// @copydoc gauge_family
template
<
class
ValueType
=
int64_t
>
metric_family_impl
<
gauge
<
ValueType
>>*
gauge_family
(
string_view
prefix
,
string_view
name
,
span_t
<
label_view
>
labels
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
using
gauge_type
=
gauge
<
ValueType
>
;
using
family_type
=
metric_family_impl
<
gauge_type
>
;
std
::
unique_lock
<
std
::
mutex
>
guard
{
families_mx_
};
if
(
auto
ptr
=
fetch
(
prefix
,
name
))
{
assert_properties
(
ptr
,
gauge_type
::
runtime_type
,
labels
,
unit
,
is_sum
);
return
static_cast
<
family_type
*>
(
ptr
);
}
auto
ptr
=
std
::
make_unique
<
family_type
>
(
to_string
(
prefix
),
to_string
(
name
),
to_sorted_vec
(
labels
),
to_string
(
helptext
),
to_string
(
unit
),
is_sum
);
auto
result
=
ptr
.
get
();
families_
.
emplace_back
(
std
::
move
(
ptr
));
return
result
;
}
/// Returns a gauge. Creates all objects lazily if necessary, but fails if the
/// full name already belongs to a different family.
/// @param prefix The prefix (namespace) this family belongs to. Usually the
/// application or protocol name, e.g., `http`. The prefix `caf`
/// as well as prefixes starting with an underscore are
/// reserved.
/// @param name The human-readable name of the metric, e.g., `requests`.
/// @param labels Values for all label dimensions of the metric.
/// @param helptext Short explanation of the metric.
/// @param unit Unit of measurement. Please use base units such as `bytes` or
/// `seconds` (prefer lowercase). The pseudo-unit `1` identifies
/// dimensionless counts.
/// @param is_sum Setting this to `true` indicates that this metric adds
/// something up to a total, where only the total value is of
/// interest. For example, the total number of HTTP requests.
template
<
class
ValueType
=
int64_t
>
gauge
<
ValueType
>*
gauge_instance
(
string_view
prefix
,
string_view
name
,
span_t
<
label_view
>
labels
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
auto
fptr
=
gauge_family
<
ValueType
>
(
prefix
,
name
,
labels
,
helptext
,
unit
,
is_sum
);
return
fptr
->
get_or_add
(
labels
);
}
/// @copydoc gauge_instance
template
<
class
ValueType
=
int64_t
>
gauge
<
ValueType
>*
gauge_instance
(
string_view
prefix
,
string_view
name
,
std
::
initializer_list
<
label_view
>
labels
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
span_t
<
label_view
>
lbls
{
labels
.
begin
(),
labels
.
size
()};
return
gauge_instance
<
ValueType
>
(
prefix
,
name
,
lbls
,
helptext
,
unit
,
is_sum
);
}
/// Returns a gauge metric singleton, i.e., the single instance of a family
/// without label dimensions. Creates all objects lazily if necessary, but
/// fails if the full name already belongs to a different family.
/// @param prefix The prefix (namespace) this family belongs to. Usually the
/// application or protocol name, e.g., `http`. The prefix `caf`
/// as well as prefixes starting with an underscore are
/// reserved.
/// @param name The human-readable name of the metric, e.g., `requests`.
/// @param helptext Short explanation of the metric.
/// @param unit Unit of measurement. Please use base units such as `bytes` or
/// `seconds` (prefer lowercase). The pseudo-unit `1` identifies
/// dimensionless counts.
/// @param is_sum Setting this to `true` indicates that this metric adds
/// something up to a total, where only the total value is of
/// interest. For example, the total number of HTTP requests.
template
<
class
ValueType
=
int64_t
>
gauge
<
ValueType
>*
gauge_singleton
(
string_view
prefix
,
string_view
name
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
span_t
<
string_view
>
lbls
;
auto
fptr
=
gauge_family
<
ValueType
>
(
prefix
,
name
,
lbls
,
helptext
,
unit
,
is_sum
);
return
fptr
->
get_or_add
({});
}
/// Returns a counter metric family. Creates the family lazily if necessary,
/// Returns a counter metric family. Creates the family lazily if necessary,
/// but fails if the full name already belongs to a different family.
/// but fails if the full name already belongs to a different family.
/// @param prefix The prefix (namespace) this family belongs to. Usually the
/// @param prefix The prefix (namespace) this family belongs to. Usually the
...
@@ -102,7 +198,7 @@ public:
...
@@ -102,7 +198,7 @@ public:
/// as well as prefixes starting with an underscore are
/// as well as prefixes starting with an underscore are
/// reserved.
/// reserved.
/// @param name The human-readable name of the metric, e.g., `requests`.
/// @param name The human-readable name of the metric, e.g., `requests`.
/// @param label
_name
s Names for all label dimensions of the metric.
/// @param labels Names for all label dimensions of the metric.
/// @param helptext Short explanation of the metric.
/// @param helptext Short explanation of the metric.
/// @param unit Unit of measurement. Please use base units such as `bytes` or
/// @param unit Unit of measurement. Please use base units such as `bytes` or
/// `seconds` (prefer lowercase). The pseudo-unit `1` identifies
/// `seconds` (prefer lowercase). The pseudo-unit `1` identifies
...
@@ -113,18 +209,17 @@ public:
...
@@ -113,18 +209,17 @@ public:
template
<
class
ValueType
=
int64_t
>
template
<
class
ValueType
=
int64_t
>
metric_family_impl
<
counter
<
ValueType
>>*
metric_family_impl
<
counter
<
ValueType
>>*
counter_family
(
string_view
prefix
,
string_view
name
,
counter_family
(
string_view
prefix
,
string_view
name
,
span
<
const
string_view
>
label_name
s
,
string_view
helptext
,
span
_t
<
string_view
>
label
s
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
using
counter_type
=
counter
<
ValueType
>
;
using
counter_type
=
counter
<
ValueType
>
;
using
family_type
=
metric_family_impl
<
counter_type
>
;
using
family_type
=
metric_family_impl
<
counter_type
>
;
std
::
unique_lock
<
std
::
mutex
>
guard
{
families_mx_
};
std
::
unique_lock
<
std
::
mutex
>
guard
{
families_mx_
};
if
(
auto
ptr
=
fetch
(
prefix
,
name
))
{
if
(
auto
ptr
=
fetch
(
prefix
,
name
))
{
assert_properties
(
ptr
,
counter_type
::
runtime_type
,
label_names
,
unit
,
assert_properties
(
ptr
,
counter_type
::
runtime_type
,
labels
,
unit
,
is_sum
);
is_sum
);
return
static_cast
<
family_type
*>
(
ptr
);
return
static_cast
<
family_type
*>
(
ptr
);
}
}
auto
ptr
=
std
::
make_unique
<
family_type
>
(
to_string
(
prefix
),
to_string
(
name
),
auto
ptr
=
std
::
make_unique
<
family_type
>
(
to_string
(
prefix
),
to_string
(
name
),
to_sorted_vec
(
label
_name
s
),
to_sorted_vec
(
labels
),
to_string
(
helptext
),
to_string
(
helptext
),
to_string
(
unit
),
is_sum
);
to_string
(
unit
),
is_sum
);
auto
result
=
ptr
.
get
();
auto
result
=
ptr
.
get
();
...
@@ -136,15 +231,74 @@ public:
...
@@ -136,15 +231,74 @@ public:
template
<
class
ValueType
=
int64_t
>
template
<
class
ValueType
=
int64_t
>
metric_family_impl
<
counter
<
ValueType
>>*
metric_family_impl
<
counter
<
ValueType
>>*
counter_family
(
string_view
prefix
,
string_view
name
,
counter_family
(
string_view
prefix
,
string_view
name
,
std
::
initializer_list
<
string_view
>
label
_name
s
,
std
::
initializer_list
<
string_view
>
labels
,
string_view
helptext
,
string_view
unit
=
"1"
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
bool
is_sum
=
false
)
{
auto
lbl_span
=
make_span
(
label
_names
.
begin
(),
label_name
s
.
size
());
auto
lbl_span
=
make_span
(
label
s
.
begin
(),
label
s
.
size
());
return
counter_family
<
ValueType
>
(
prefix
,
name
,
lbl_span
,
helptext
,
unit
,
return
counter_family
<
ValueType
>
(
prefix
,
name
,
lbl_span
,
helptext
,
unit
,
is_sum
);
is_sum
);
}
}
/// Returns a gauge metric singleton, i.e., the single instance of a family
/// @copydoc counter_family
template
<
class
ValueType
=
int64_t
>
metric_family_impl
<
counter
<
ValueType
>>*
counter_family
(
string_view
prefix
,
string_view
name
,
span_t
<
label_view
>
labels
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
using
counter_type
=
counter
<
ValueType
>
;
using
family_type
=
metric_family_impl
<
counter_type
>
;
std
::
unique_lock
<
std
::
mutex
>
guard
{
families_mx_
};
if
(
auto
ptr
=
fetch
(
prefix
,
name
))
{
assert_properties
(
ptr
,
counter_type
::
runtime_type
,
labels
,
unit
,
is_sum
);
return
static_cast
<
family_type
*>
(
ptr
);
}
auto
ptr
=
std
::
make_unique
<
family_type
>
(
to_string
(
prefix
),
to_string
(
name
),
to_sorted_vec
(
labels
),
to_string
(
helptext
),
to_string
(
unit
),
is_sum
);
auto
result
=
ptr
.
get
();
families_
.
emplace_back
(
std
::
move
(
ptr
));
return
result
;
}
/// Returns a counter. Creates all objects lazily if necessary, but fails if
/// the full name already belongs to a different family.
/// @param prefix The prefix (namespace) this family belongs to. Usually the
/// application or protocol name, e.g., `http`. The prefix `caf`
/// as well as prefixes starting with an underscore are
/// reserved.
/// @param name The human-readable name of the metric, e.g., `requests`.
/// @param labels Values for all label dimensions of the metric.
/// @param helptext Short explanation of the metric.
/// @param unit Unit of measurement. Please use base units such as `bytes` or
/// `seconds` (prefer lowercase). The pseudo-unit `1` identifies
/// dimensionless counts.
/// @param is_sum Setting this to `true` indicates that this metric adds
/// something up to a total, where only the total value is of
/// interest. For example, the total number of HTTP requests.
template
<
class
ValueType
=
int64_t
>
counter
<
ValueType
>*
counter_instance
(
string_view
prefix
,
string_view
name
,
span_t
<
label_view
>
labels
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
auto
fptr
=
counter_family
<
ValueType
>
(
prefix
,
name
,
labels
,
helptext
,
unit
,
is_sum
);
return
fptr
->
get_or_add
(
labels
);
}
/// @copydoc counter_instance
template
<
class
ValueType
=
int64_t
>
counter
<
ValueType
>*
counter_instance
(
string_view
prefix
,
string_view
name
,
std
::
initializer_list
<
label_view
>
labels
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
span_t
<
label_view
>
lbls
{
labels
.
begin
(),
labels
.
size
()};
return
counter_instance
<
ValueType
>
(
prefix
,
name
,
lbls
,
helptext
,
unit
,
is_sum
);
}
/// Returns a counter metric singleton, i.e., the single instance of a family
/// without label dimensions. Creates all objects lazily if necessary, but
/// without label dimensions. Creates all objects lazily if necessary, but
/// fails if the full name already belongs to a different family.
/// fails if the full name already belongs to a different family.
/// @param prefix The prefix (namespace) this family belongs to. Usually the
/// @param prefix The prefix (namespace) this family belongs to. Usually the
...
@@ -160,12 +314,12 @@ public:
...
@@ -160,12 +314,12 @@ public:
/// something up to a total, where only the total value is of
/// something up to a total, where only the total value is of
/// interest. For example, the total number of HTTP requests.
/// interest. For example, the total number of HTTP requests.
template
<
class
ValueType
=
int64_t
>
template
<
class
ValueType
=
int64_t
>
gauge
<
ValueType
>*
counter
<
ValueType
>*
gauge
_singleton
(
string_view
prefix
,
string_view
name
,
string_view
helptext
,
counter
_singleton
(
string_view
prefix
,
string_view
name
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
span
<
const
string_view
>
lbls
;
span
_t
<
string_view
>
lbls
;
auto
fptr
=
gauge
_family
<
ValueType
>
(
prefix
,
name
,
lbls
,
helptext
,
unit
,
auto
fptr
=
counter
_family
<
ValueType
>
(
prefix
,
name
,
lbls
,
helptext
,
unit
,
is_sum
);
is_sum
);
return
fptr
->
get_or_add
({});
return
fptr
->
get_or_add
({});
}
}
...
@@ -178,8 +332,6 @@ public:
...
@@ -178,8 +332,6 @@ public:
/// @param name The human-readable name of the metric, e.g., `requests`.
/// @param name The human-readable name of the metric, e.g., `requests`.
/// @param label_names Names for all label dimensions of the metric.
/// @param label_names Names for all label dimensions of the metric.
/// @param default_upper_bounds Upper bounds for the metric buckets.
/// @param default_upper_bounds Upper bounds for the metric buckets.
/// @param metrics_settings Runtime parameters that may override
/// `default_upper_bounds`. May be `nullptr`.
/// @param helptext Short explanation of the metric.
/// @param helptext Short explanation of the metric.
/// @param unit Unit of measurement. Please use base units such as `bytes` or
/// @param unit Unit of measurement. Please use base units such as `bytes` or
/// `seconds` (prefer lowercase). The pseudo-unit `1` identifies
/// `seconds` (prefer lowercase). The pseudo-unit `1` identifies
...
@@ -190,12 +342,13 @@ public:
...
@@ -190,12 +342,13 @@ public:
/// @note The first call wins when calling this function multiple times with
/// @note The first call wins when calling this function multiple times with
/// different bucket settings. Later calls skip checking the bucket
/// different bucket settings. Later calls skip checking the bucket
/// settings, mainly because this check would be rather expensive.
/// settings, mainly because this check would be rather expensive.
/// @note The actor system config may override `upper_bounds`.
template
<
class
ValueType
=
int64_t
>
template
<
class
ValueType
=
int64_t
>
metric_family_impl
<
histogram
<
ValueType
>>*
histogram_family
(
metric_family_impl
<
histogram
<
ValueType
>>*
string_view
prefix
,
string_view
name
,
span
<
const
string_view
>
label_names
,
histogram_family
(
string_view
prefix
,
string_view
name
,
span
<
const
typename
histogram
<
ValueType
>::
value_type
>
default_upper_bound
s
,
span_t
<
string_view
>
label_name
s
,
const
settings
*
metrics_setting
s
,
string_view
helptext
,
span_t
<
ValueType
>
default_upper_bound
s
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
using
histogram_type
=
histogram
<
ValueType
>
;
using
histogram_type
=
histogram
<
ValueType
>
;
using
family_type
=
metric_family_impl
<
histogram_type
>
;
using
family_type
=
metric_family_impl
<
histogram_type
>
;
using
upper_bounds_list
=
std
::
vector
<
ValueType
>
;
using
upper_bounds_list
=
std
::
vector
<
ValueType
>
;
...
@@ -207,18 +360,20 @@ public:
...
@@ -207,18 +360,20 @@ public:
is_sum
);
is_sum
);
return
static_cast
<
family_type
*>
(
ptr
);
return
static_cast
<
family_type
*>
(
ptr
);
}
}
const
settings
*
sub_settings
=
nullptr
;
upper_bounds_list
upper_bounds
;
upper_bounds_list
upper_bounds
;
if
(
metrics_settings
!=
nullptr
)
if
(
config_
!=
nullptr
)
if
(
auto
grp
=
get_if
<
settings
>
(
metrics_settings
,
name
))
if
(
auto
grp
=
get_if
<
settings
>
(
config_
,
prefix
))
if
(
auto
var
=
get_if
<
settings
>
(
grp
,
name
)
)
if
(
sub_settings
=
get_if
<
settings
>
(
grp
,
name
);
sub_settings
!=
nullptr
)
if
(
auto
lst
=
get_if
<
upper_bounds_list
>
(
var
,
"buckets"
))
if
(
auto
lst
=
get_if
<
upper_bounds_list
>
(
sub_settings
,
"buckets"
))
upper_bounds
=
std
::
move
(
*
lst
);
upper_bounds
=
std
::
move
(
*
lst
);
if
(
upper_bounds
.
empty
())
if
(
upper_bounds
.
empty
())
upper_bounds
.
assign
(
default_upper_bounds
.
begin
(),
upper_bounds
.
assign
(
default_upper_bounds
.
begin
(),
default_upper_bounds
.
end
());
default_upper_bounds
.
end
());
auto
ptr
=
std
::
make_unique
<
family_type
>
(
auto
ptr
=
std
::
make_unique
<
family_type
>
(
to_string
(
prefix
),
to_string
(
name
),
to_sorted_vec
(
label_names
),
sub_settings
,
to_string
(
prefix
),
to_string
(
name
),
to_string
(
helptext
),
to_string
(
unit
),
is_sum
,
std
::
move
(
upper_bounds
));
to_sorted_vec
(
label_names
),
to_string
(
helptext
),
to_string
(
unit
),
is_sum
,
std
::
move
(
upper_bounds
));
auto
result
=
ptr
.
get
();
auto
result
=
ptr
.
get
();
families_
.
emplace_back
(
std
::
move
(
ptr
));
families_
.
emplace_back
(
std
::
move
(
ptr
));
return
result
;
return
result
;
...
@@ -226,16 +381,57 @@ public:
...
@@ -226,16 +381,57 @@ public:
/// @copydoc gauge_family
/// @copydoc gauge_family
template
<
class
ValueType
=
int64_t
>
template
<
class
ValueType
=
int64_t
>
metric_family_impl
<
histogram
<
ValueType
>>*
histogram_family
(
metric_family_impl
<
histogram
<
ValueType
>>*
string_view
prefix
,
string_view
name
,
histogram_family
(
string_view
prefix
,
string_view
name
,
std
::
initializer_list
<
string_view
>
label_names
,
std
::
initializer_list
<
string_view
>
label_names
,
span
<
const
typename
histogram
<
ValueType
>::
value_type
>
upper_bounds
,
span_t
<
ValueType
>
upper_bounds
,
string_view
helptext
,
const
settings
*
metrics_settings
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
auto
lbl_span
=
make_span
(
label_names
.
begin
(),
label_names
.
size
());
auto
lbl_span
=
make_span
(
label_names
.
begin
(),
label_names
.
size
());
return
histogram_family
<
ValueType
>
(
prefix
,
name
,
lbl_span
,
upper_bounds
,
return
histogram_family
<
ValueType
>
(
prefix
,
name
,
lbl_span
,
upper_bounds
,
metrics_settings
,
helptext
,
unit
,
helptext
,
unit
,
is_sum
);
is_sum
);
}
/// Returns a histogram. Creates the family lazily if necessary, but fails if
/// the full name already belongs to a different family.
/// @param prefix The prefix (namespace) this family belongs to. Usually the
/// application or protocol name, e.g., `http`. The prefix `caf`
/// as well as prefixes starting with an underscore are
/// reserved.
/// @param name The human-readable name of the metric, e.g., `requests`.
/// @param label_names Names for all label dimensions of the metric.
/// @param default_upper_bounds Upper bounds for the metric buckets.
/// @param helptext Short explanation of the metric.
/// @param unit Unit of measurement. Please use base units such as `bytes` or
/// `seconds` (prefer lowercase). The pseudo-unit `1` identifies
/// dimensionless counts.
/// @param is_sum Setting this to `true` indicates that this metric adds
/// something up to a total, where only the total value is of
/// interest. For example, the total number of HTTP requests.
/// @note The first call wins when calling this function multiple times with
/// different bucket settings. Later calls skip checking the bucket
/// settings, mainly because this check would be rather expensive.
/// @note The actor system config may override `upper_bounds`.
template
<
class
ValueType
=
int64_t
>
histogram
<
ValueType
>*
histogram_instance
(
string_view
prefix
,
string_view
name
,
span_t
<
label_view
>
labels
,
span_t
<
ValueType
>
upper_bounds
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
auto
fptr
=
histogram_family
<
ValueType
>
(
prefix
,
name
,
labels
,
upper_bounds
,
helptext
,
unit
,
is_sum
);
return
fptr
->
get_or_add
(
labels
);
}
/// @copdoc histogram_instance
template
<
class
ValueType
=
int64_t
>
histogram
<
ValueType
>*
histogram_instance
(
string_view
prefix
,
string_view
name
,
std
::
initializer_list
<
label_view
>
labels
,
span_t
<
ValueType
>
upper_bounds
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
span_t
<
label_view
>
lbls
{
labels
.
begin
(),
labels
.
size
()};
return
histogram_instance
(
prefix
,
name
,
lbls
,
upper_bounds
,
helptext
,
unit
,
is_sum
);
}
}
/// Returns a histogram metric singleton, i.e., the single instance of a
/// Returns a histogram metric singleton, i.e., the single instance of a
...
@@ -253,17 +449,23 @@ public:
...
@@ -253,17 +449,23 @@ public:
/// @param is_sum Setting this to `true` indicates that this metric adds
/// @param is_sum Setting this to `true` indicates that this metric adds
/// something up to a total, where only the total value is of
/// something up to a total, where only the total value is of
/// interest. For example, the total number of HTTP requests.
/// interest. For example, the total number of HTTP requests.
/// @note The actor system config may override `upper_bounds`.
template
<
class
ValueType
=
int64_t
>
template
<
class
ValueType
=
int64_t
>
histogram
<
ValueType
>*
histogram
<
ValueType
>*
histogram_singleton
(
string_view
prefix
,
string_view
name
,
histogram_singleton
(
string_view
prefix
,
string_view
name
,
string_view
helptext
,
span
<
const
ValueType
>
upper_bounds
,
string_view
helptext
,
span
_t
<
ValueType
>
upper_bounds
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
span
<
const
string_view
>
lbls
;
span
_t
<
string_view
>
lbls
;
auto
fptr
=
histogram_family
<
ValueType
>
(
prefix
,
name
,
lbls
,
upper_bounds
,
auto
fptr
=
histogram_family
<
ValueType
>
(
prefix
,
name
,
lbls
,
upper_bounds
,
helptext
,
unit
,
is_sum
);
helptext
,
unit
,
is_sum
);
return
fptr
->
get_or_add
({});
return
fptr
->
get_or_add
({});
}
}
/// @internal
void
config
(
const
settings
*
ptr
)
{
config_
=
ptr
;
}
// -- observers --------------------------------------------------------------
// -- observers --------------------------------------------------------------
template
<
class
Collector
>
template
<
class
Collector
>
...
@@ -278,16 +480,9 @@ private:
...
@@ -278,16 +480,9 @@ private:
/// @pre `families_mx_` is locked.
/// @pre `families_mx_` is locked.
metric_family
*
fetch
(
const
string_view
&
prefix
,
const
string_view
&
name
);
metric_family
*
fetch
(
const
string_view
&
prefix
,
const
string_view
&
name
);
static
std
::
vector
<
std
::
string
>
to_sorted_vec
(
span
<
const
string_view
>
xs
)
{
static
std
::
vector
<
std
::
string
>
to_sorted_vec
(
span_t
<
string_view
>
xs
);
std
::
vector
<
std
::
string
>
result
;
if
(
!
xs
.
empty
())
{
static
std
::
vector
<
std
::
string
>
to_sorted_vec
(
span_t
<
label_view
>
xs
);
result
.
reserve
(
xs
.
size
());
for
(
auto
x
:
xs
)
result
.
emplace_back
(
to_string
(
x
));
std
::
sort
(
result
.
begin
(),
result
.
end
());
}
return
result
;
}
template
<
class
F
>
template
<
class
F
>
static
auto
visit_family
(
F
&
f
,
const
metric_family
*
ptr
)
{
static
auto
visit_family
(
F
&
f
,
const
metric_family
*
ptr
)
{
...
@@ -309,11 +504,16 @@ private:
...
@@ -309,11 +504,16 @@ private:
}
}
void
assert_properties
(
const
metric_family
*
ptr
,
metric_type
type
,
void
assert_properties
(
const
metric_family
*
ptr
,
metric_type
type
,
span
<
const
string_view
>
label_names
,
string_view
unit
,
span_t
<
string_view
>
label_names
,
string_view
unit
,
bool
is_sum
);
void
assert_properties
(
const
metric_family
*
ptr
,
metric_type
type
,
span_t
<
label_view
>
label_names
,
string_view
unit
,
bool
is_sum
);
bool
is_sum
);
mutable
std
::
mutex
families_mx_
;
mutable
std
::
mutex
families_mx_
;
std
::
vector
<
std
::
unique_ptr
<
metric_family
>>
families_
;
std
::
vector
<
std
::
unique_ptr
<
metric_family
>>
families_
;
const
caf
::
settings
*
config_
;
};
};
}
// namespace caf::telemetry
}
// namespace caf::telemetry
libcaf_core/src/actor_system.cpp
View file @
50d010ca
...
@@ -226,6 +226,7 @@ actor_system::actor_system(actor_system_config& cfg)
...
@@ -226,6 +226,7 @@ actor_system::actor_system(actor_system_config& cfg)
await_actors_before_shutdown_
(
true
),
await_actors_before_shutdown_
(
true
),
detached_
(
0
),
detached_
(
0
),
cfg_
(
cfg
),
cfg_
(
cfg
),
metrics_
(
cfg
),
logger_dtor_done_
(
false
),
logger_dtor_done_
(
false
),
tracing_context_
(
cfg
.
tracing_context
)
{
tracing_context_
(
cfg
.
tracing_context
)
{
CAF_SET_LOGGER_SYS
(
this
);
CAF_SET_LOGGER_SYS
(
this
);
...
...
libcaf_core/src/telemetry/metric_registry.cpp
View file @
50d010ca
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
#include "caf/telemetry/metric_registry.hpp"
#include "caf/telemetry/metric_registry.hpp"
#include "caf/actor_system_config.hpp"
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/telemetry/dbl_gauge.hpp"
#include "caf/telemetry/dbl_gauge.hpp"
#include "caf/telemetry/int_gauge.hpp"
#include "caf/telemetry/int_gauge.hpp"
...
@@ -36,10 +37,14 @@ bool equals(Range1&& xs, Range2&& ys) {
...
@@ -36,10 +37,14 @@ bool equals(Range1&& xs, Range2&& ys) {
namespace
caf
::
telemetry
{
namespace
caf
::
telemetry
{
metric_registry
::
metric_registry
()
{
metric_registry
::
metric_registry
()
:
config_
(
nullptr
)
{
// nop
// nop
}
}
metric_registry
::
metric_registry
(
const
actor_system_config
&
cfg
)
{
config_
=
get_if
<
settings
>
(
&
cfg
,
"metrics"
);
}
metric_registry
::~
metric_registry
()
{
metric_registry
::~
metric_registry
()
{
// nop
// nop
}
}
...
@@ -55,6 +60,30 @@ metric_family* metric_registry::fetch(const string_view& prefix,
...
@@ -55,6 +60,30 @@ metric_family* metric_registry::fetch(const string_view& prefix,
return
nullptr
;
return
nullptr
;
}
}
std
::
vector
<
std
::
string
>
metric_registry
::
to_sorted_vec
(
span
<
const
string_view
>
xs
)
{
std
::
vector
<
std
::
string
>
result
;
if
(
!
xs
.
empty
())
{
result
.
reserve
(
xs
.
size
());
for
(
auto
x
:
xs
)
result
.
emplace_back
(
to_string
(
x
));
std
::
sort
(
result
.
begin
(),
result
.
end
());
}
return
result
;
}
std
::
vector
<
std
::
string
>
metric_registry
::
to_sorted_vec
(
span
<
const
label_view
>
xs
)
{
std
::
vector
<
std
::
string
>
result
;
if
(
!
xs
.
empty
())
{
result
.
reserve
(
xs
.
size
());
for
(
auto
x
:
xs
)
result
.
emplace_back
(
to_string
(
x
.
name
()));
std
::
sort
(
result
.
begin
(),
result
.
end
());
}
return
result
;
}
void
metric_registry
::
assert_properties
(
const
metric_family
*
ptr
,
void
metric_registry
::
assert_properties
(
const
metric_family
*
ptr
,
metric_type
type
,
metric_type
type
,
span
<
const
string_view
>
label_names
,
span
<
const
string_view
>
label_names
,
...
@@ -76,4 +105,49 @@ void metric_registry::assert_properties(const metric_family* ptr,
...
@@ -76,4 +105,49 @@ void metric_registry::assert_properties(const metric_family* ptr,
CAF_RAISE_ERROR
(
"full name with different is-sum flag found"
);
CAF_RAISE_ERROR
(
"full name with different is-sum flag found"
);
}
}
namespace
{
struct
label_name_eq
{
bool
operator
()(
string_view
x
,
string_view
y
)
const
noexcept
{
return
x
==
y
;
}
bool
operator
()(
string_view
x
,
const
label_view
&
y
)
const
noexcept
{
return
x
==
y
.
name
();
}
bool
operator
()(
const
label_view
&
x
,
string_view
y
)
const
noexcept
{
return
x
.
name
()
==
y
;
}
bool
operator
()(
label_view
x
,
label_view
y
)
const
noexcept
{
return
x
==
y
;
}
};
}
// namespace
void
metric_registry
::
assert_properties
(
const
metric_family
*
ptr
,
metric_type
type
,
span
<
const
label_view
>
labels
,
string_view
unit
,
bool
is_sum
)
{
auto
labels_match
=
[
&
]
{
const
auto
&
xs
=
ptr
->
label_names
();
const
auto
&
ys
=
labels
;
label_name_eq
eq
;
return
std
::
is_sorted
(
ys
.
begin
(),
ys
.
end
())
?
std
::
equal
(
xs
.
begin
(),
xs
.
end
(),
ys
.
begin
(),
ys
.
end
(),
eq
)
:
std
::
is_permutation
(
xs
.
begin
(),
xs
.
end
(),
ys
.
begin
(),
ys
.
end
(),
eq
);
};
if
(
ptr
->
type
()
!=
type
)
CAF_RAISE_ERROR
(
"full name with different metric type found"
);
if
(
!
labels_match
())
CAF_RAISE_ERROR
(
"full name with different label dimensions found"
);
if
(
ptr
->
unit
()
!=
unit
)
CAF_RAISE_ERROR
(
"full name with different unit found"
);
if
(
ptr
->
is_sum
()
!=
is_sum
)
CAF_RAISE_ERROR
(
"full name with different is-sum flag found"
);
}
}
// namespace caf::telemetry
}
// namespace caf::telemetry
libcaf_core/test/telemetry/collector/prometheus.cpp
View file @
50d010ca
...
@@ -49,8 +49,7 @@ CAF_TEST(the Prometheus collector generates text output) {
...
@@ -49,8 +49,7 @@ CAF_TEST(the Prometheus collector generates text output) {
auto
ov
=
registry
.
gauge_family
(
"other"
,
"value"
,
{
"x"
},
""
,
"seconds"
,
true
);
auto
ov
=
registry
.
gauge_family
(
"other"
,
"value"
,
{
"x"
},
""
,
"seconds"
,
true
);
std
::
vector
<
int64_t
>
upper_bounds
{
1
,
2
,
4
};
std
::
vector
<
int64_t
>
upper_bounds
{
1
,
2
,
4
};
auto
sr
=
registry
.
histogram_family
(
"some"
,
"request-duration"
,
{
"x"
},
auto
sr
=
registry
.
histogram_family
(
"some"
,
"request-duration"
,
{
"x"
},
upper_bounds
,
nullptr
,
"Some help."
,
upper_bounds
,
"Some help."
,
"seconds"
);
"seconds"
);
fb
->
get_or_add
({})
->
value
(
123
);
fb
->
get_or_add
({})
->
value
(
123
);
sv
->
get_or_add
({{
"a"
,
"1"
},
{
"b"
,
"2"
}})
->
value
(
12
);
sv
->
get_or_add
({{
"a"
,
"1"
},
{
"b"
,
"2"
}})
->
value
(
12
);
sv
->
get_or_add
({{
"b"
,
"1"
},
{
"a"
,
"2"
}})
->
value
(
21
);
sv
->
get_or_add
({{
"b"
,
"1"
},
{
"a"
,
"2"
}})
->
value
(
21
);
...
...
libcaf_core/test/telemetry/metric_registry.cpp
View file @
50d010ca
...
@@ -108,8 +108,7 @@ CAF_TEST(registries lazily create metrics) {
...
@@ -108,8 +108,7 @@ CAF_TEST(registries lazily create metrics) {
auto
f
=
registry
.
gauge_family
(
"caf"
,
"running-actors"
,
{
"var1"
,
"var2"
},
auto
f
=
registry
.
gauge_family
(
"caf"
,
"running-actors"
,
{
"var1"
,
"var2"
},
"How many actors are currently running?"
);
"How many actors are currently running?"
);
auto
g
=
registry
.
histogram_family
(
"caf"
,
"response-time"
,
{
"var1"
,
"var2"
},
auto
g
=
registry
.
histogram_family
(
"caf"
,
"response-time"
,
{
"var1"
,
"var2"
},
upper_bounds
,
nullptr
,
upper_bounds
,
"How long take requests?"
);
"How long take requests?"
);
std
::
vector
<
label_view
>
v1
{{
"var1"
,
"foo"
},
{
"var2"
,
"bar"
}};
std
::
vector
<
label_view
>
v1
{{
"var1"
,
"foo"
},
{
"var2"
,
"bar"
}};
std
::
vector
<
label_view
>
v1_reversed
{{
"var2"
,
"bar"
},
{
"var1"
,
"foo"
}};
std
::
vector
<
label_view
>
v1_reversed
{{
"var2"
,
"bar"
},
{
"var1"
,
"foo"
}};
std
::
vector
<
label_view
>
v2
{{
"var1"
,
"bar"
},
{
"var2"
,
"foo"
}};
std
::
vector
<
label_view
>
v2
{{
"var1"
,
"bar"
},
{
"var2"
,
"foo"
}};
...
@@ -171,14 +170,41 @@ caf.mailbox-size{name="parser"} 12)");
...
@@ -171,14 +170,41 @@ caf.mailbox-size{name="parser"} 12)");
}
}
CAF_TEST
(
buckets
for
histograms
are
configurable
via
runtime
settings
){
CAF_TEST
(
buckets
for
histograms
are
configurable
via
runtime
settings
){
auto
bounds
=
[](
auto
&&
buckets
)
{
std
::
vector
<
int64_t
>
result
;
for
(
auto
&&
bucket
:
buckets
)
result
.
emplace_back
(
bucket
.
upper_bound
);
result
.
pop_back
();
return
result
;
};
settings
cfg
;
settings
cfg
;
std
::
vector
<
int64_t
>
default_upper_bounds
{
1
,
2
,
4
,
8
};
std
::
vector
<
int64_t
>
default_upper_bounds
{
1
,
2
,
4
,
8
};
std
::
vector
<
int64_t
>
upper_bounds
{
1
,
2
,
3
,
5
,
7
};
std
::
vector
<
int64_t
>
upper_bounds
{
1
,
2
,
3
,
5
,
7
};
std
::
vector
<
int64_t
>
alternative_upper_bounds
{
10
,
20
,
30
};
put
(
cfg
,
"caf.response-time.buckets"
,
upper_bounds
);
put
(
cfg
,
"caf.response-time.buckets"
,
upper_bounds
);
auto
h
=
registry
.
histogram_family
(
"caf"
,
"response-time"
,
{
"var1"
,
"var2"
},
put
(
cfg
,
"caf.response-time.var1=foo.buckets"
,
alternative_upper_bounds
);
upper_bounds
,
&
cfg
,
registry
.
config
(
&
cfg
);
"How long take requests?"
);
auto
hf
=
registry
.
histogram_family
(
"caf"
,
"response-time"
,
{
"var1"
,
"var2"
},
CAF_CHECK_EQUAL
(
h
->
extra_setting
(),
upper_bounds
);
default_upper_bounds
,
"How long take requests?"
);
CAF_CHECK_EQUAL
(
hf
->
config
(),
get_if
<
settings
>
(
&
cfg
,
"caf.response-time"
));
CAF_CHECK_EQUAL
(
hf
->
extra_setting
(),
upper_bounds
);
auto
h1
=
hf
->
get_or_add
({{
"var1"
,
"bar"
},
{
"var2"
,
"baz"
}});
CAF_CHECK_EQUAL
(
bounds
(
h1
->
buckets
()),
upper_bounds
);
auto
h2
=
hf
->
get_or_add
({{
"var1"
,
"foo"
},
{
"var2"
,
"bar"
}});
CAF_CHECK_NOT_EQUAL
(
h1
,
h2
);
CAF_CHECK_EQUAL
(
bounds
(
h2
->
buckets
()),
alternative_upper_bounds
);
}
CAF_TEST
(
counter_instance
is
a
shortcut
for
using
the
family
manually
)
{
auto
fptr
=
registry
.
counter_family
(
"http"
,
"requests"
,
{
"method"
},
"Number of HTTP requests."
,
"seconds"
,
true
);
auto
count
=
fptr
->
get_or_add
({{
"method"
,
"put"
}});
auto
count2
=
registry
.
counter_instance
(
"http"
,
"requests"
,
{{
"method"
,
"put"
}},
"Number of HTTP requests."
,
"seconds"
,
true
);
CAF_CHECK_EQUAL
(
count
,
count2
);
}
}
CAF_TEST_FIXTURE_SCOPE_END
()
CAF_TEST_FIXTURE_SCOPE_END
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment