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
f20b13b0
Commit
f20b13b0
authored
Jun 12, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revise the metric family API
parent
6b1bd132
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
166 additions
and
182 deletions
+166
-182
libcaf_core/caf/telemetry/collector/prometheus.hpp
libcaf_core/caf/telemetry/collector/prometheus.hpp
+2
-1
libcaf_core/caf/telemetry/int_gauge.hpp
libcaf_core/caf/telemetry/int_gauge.hpp
+8
-4
libcaf_core/caf/telemetry/metric_family.hpp
libcaf_core/caf/telemetry/metric_family.hpp
+2
-0
libcaf_core/caf/telemetry/metric_family_impl.hpp
libcaf_core/caf/telemetry/metric_family_impl.hpp
+19
-9
libcaf_core/caf/telemetry/metric_registry.hpp
libcaf_core/caf/telemetry/metric_registry.hpp
+49
-41
libcaf_core/src/actor_registry.cpp
libcaf_core/src/actor_registry.cpp
+1
-1
libcaf_core/src/telemetry/metric_registry.cpp
libcaf_core/src/telemetry/metric_registry.cpp
+25
-64
libcaf_core/test/telemetry/collector/prometheus.cpp
libcaf_core/test/telemetry/collector/prometheus.cpp
+13
-12
libcaf_core/test/telemetry/int_gauge.cpp
libcaf_core/test/telemetry/int_gauge.cpp
+4
-4
libcaf_core/test/telemetry/metric_registry.cpp
libcaf_core/test/telemetry/metric_registry.cpp
+43
-46
No files found.
libcaf_core/caf/telemetry/collector/prometheus.hpp
View file @
f20b13b0
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
#include <unordered_map>
#include <unordered_map>
#include <vector>
#include <vector>
#include "caf/detail/core_export.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/string_view.hpp"
#include "caf/string_view.hpp"
...
@@ -29,7 +30,7 @@ namespace caf::telemetry::collector {
...
@@ -29,7 +30,7 @@ namespace caf::telemetry::collector {
/// Collects system metrics and exports them to the text-based Prometheus
/// Collects system metrics and exports them to the text-based Prometheus
/// format. For a documentation of the format, see: https://git.io/fjgDD.
/// format. For a documentation of the format, see: https://git.io/fjgDD.
class
prometheus
{
class
CAF_CORE_EXPORT
prometheus
{
public:
public:
// -- member types -----------------------------------------------------------
// -- member types -----------------------------------------------------------
...
...
libcaf_core/caf/telemetry/int_gauge.hpp
View file @
f20b13b0
...
@@ -23,12 +23,16 @@
...
@@ -23,12 +23,16 @@
#include <atomic>
#include <atomic>
#include <cstdint>
#include <cstdint>
#include "caf/telemetry/metric_type.hpp"
namespace
caf
::
telemetry
{
namespace
caf
::
telemetry
{
/// A metric that represents a single integer value that can arbitrarily go up
/// A metric that represents a single integer value that can arbitrarily go up
/// and down.
/// and down.
class
CAF_CORE_EXPORT
int_gauge
{
class
CAF_CORE_EXPORT
int_gauge
{
public:
public:
static
constexpr
metric_type
runtime_type
=
metric_type
::
int_gauge
;
int_gauge
()
noexcept
:
value_
(
0
)
{
int_gauge
()
noexcept
:
value_
(
0
)
{
// nop
// nop
}
}
...
@@ -38,22 +42,22 @@ public:
...
@@ -38,22 +42,22 @@ public:
}
}
/// Increments the gauge by 1.
/// Increments the gauge by 1.
void
inc
rement
()
noexcept
{
void
inc
()
noexcept
{
++
value_
;
++
value_
;
}
}
/// Increments the gauge by `amount`.
/// Increments the gauge by `amount`.
void
inc
rement
(
int64_t
amount
)
noexcept
{
void
inc
(
int64_t
amount
)
noexcept
{
value_
.
fetch_add
(
amount
);
value_
.
fetch_add
(
amount
);
}
}
/// Decrements the gauge by 1.
/// Decrements the gauge by 1.
void
dec
rement
()
noexcept
{
void
dec
()
noexcept
{
--
value_
;
--
value_
;
}
}
/// Decrements the gauge by `amount`.
/// Decrements the gauge by `amount`.
void
dec
rement
(
int64_t
amount
)
noexcept
{
void
dec
(
int64_t
amount
)
noexcept
{
value_
.
fetch_sub
(
amount
);
value_
.
fetch_sub
(
amount
);
}
}
...
...
libcaf_core/caf/telemetry/metric_family.hpp
View file @
f20b13b0
...
@@ -77,6 +77,8 @@ public:
...
@@ -77,6 +77,8 @@ public:
return
is_sum_
;
return
is_sum_
;
}
}
virtual
metric_type
type
()
const
noexcept
=
0
;
private:
private:
std
::
string
prefix_
;
std
::
string
prefix_
;
std
::
string
name_
;
std
::
string
name_
;
...
...
libcaf_core/caf/telemetry/metric_family_impl.hpp
View file @
f20b13b0
...
@@ -19,9 +19,12 @@
...
@@ -19,9 +19,12 @@
#pragma once
#pragma once
#include <algorithm>
#include <algorithm>
#include <initializer_list>
#include <memory>
#include <memory>
#include <mutex>
#include <mutex>
#include "caf/span.hpp"
#include "caf/string_view.hpp"
#include "caf/telemetry/label.hpp"
#include "caf/telemetry/label.hpp"
#include "caf/telemetry/label_view.hpp"
#include "caf/telemetry/label_view.hpp"
#include "caf/telemetry/metric.hpp"
#include "caf/telemetry/metric.hpp"
...
@@ -33,27 +36,34 @@ namespace caf::telemetry {
...
@@ -33,27 +36,34 @@ namespace caf::telemetry {
template
<
class
Type
>
template
<
class
Type
>
class
metric_family_impl
:
public
metric_family
{
class
metric_family_impl
:
public
metric_family
{
public:
public:
using
metric
_type
=
metric_impl
<
Type
>
;
using
impl
_type
=
metric_impl
<
Type
>
;
using
metric_family
::
metric_family
;
using
metric_family
::
metric_family
;
Type
*
get_or_add
(
const
std
::
vector
<
label_view
>&
labels
)
{
metric_type
type
()
const
noexcept
override
{
auto
has_label_values
=
[
&
labels
](
const
auto
&
metric_ptr
)
{
return
Type
::
runtime_type
;
}
Type
*
get_or_add
(
span
<
const
label_view
>
labels
)
{
auto
has_label_values
=
[
labels
](
const
auto
&
metric_ptr
)
{
const
auto
&
metric_labels
=
metric_ptr
->
labels
();
const
auto
&
metric_labels
=
metric_ptr
->
labels
();
for
(
size_t
index
=
0
;
index
<
labels
.
size
();
++
index
)
return
std
::
is_permutation
(
metric_labels
.
begin
(),
metric_labels
.
end
(),
if
(
labels
[
index
].
value
()
!=
metric_labels
[
index
].
value
())
labels
.
begin
(),
labels
.
end
());
return
false
;
return
true
;
};
};
std
::
unique_lock
<
std
::
mutex
>
guard
{
mx_
};
std
::
unique_lock
<
std
::
mutex
>
guard
{
mx_
};
auto
m
=
std
::
find_if
(
metrics_
.
begin
(),
metrics_
.
end
(),
has_label_values
);
auto
m
=
std
::
find_if
(
metrics_
.
begin
(),
metrics_
.
end
(),
has_label_values
);
if
(
m
==
metrics_
.
end
())
{
if
(
m
==
metrics_
.
end
())
{
std
::
vector
<
label
>
cpy
{
labels
.
begin
(),
labels
.
end
()};
std
::
vector
<
label
>
cpy
{
labels
.
begin
(),
labels
.
end
()};
m
=
metrics_
.
emplace
(
m
,
std
::
make_unique
<
metric_type
>
(
std
::
move
(
cpy
)));
std
::
sort
(
cpy
.
begin
(),
cpy
.
end
());
m
=
metrics_
.
emplace
(
m
,
std
::
make_unique
<
impl_type
>
(
std
::
move
(
cpy
)));
}
}
return
std
::
addressof
(
m
->
get
()
->
impl
());
return
std
::
addressof
(
m
->
get
()
->
impl
());
}
}
Type
*
get_or_add
(
std
::
initializer_list
<
label_view
>
labels
)
{
return
get_or_add
(
span
<
const
label_view
>
{
labels
.
begin
(),
labels
.
size
()});
}
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_
};
...
@@ -63,7 +73,7 @@ public:
...
@@ -63,7 +73,7 @@ public:
private:
private:
mutable
std
::
mutex
mx_
;
mutable
std
::
mutex
mx_
;
std
::
vector
<
std
::
unique_ptr
<
metric
_type
>>
metrics_
;
std
::
vector
<
std
::
unique_ptr
<
impl
_type
>>
metrics_
;
};
};
}
// namespace caf::telemetry
}
// namespace caf::telemetry
libcaf_core/caf/telemetry/metric_registry.hpp
View file @
f20b13b0
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
#pragma once
#pragma once
#include <initializer_list>
#include <map>
#include <map>
#include <memory>
#include <memory>
#include <mutex>
#include <mutex>
...
@@ -42,26 +43,8 @@ public:
...
@@ -42,26 +43,8 @@ public:
~
metric_registry
();
~
metric_registry
();
/// Adds a new metric family to the registry.
/// Returns a metric family. Creates the family lazily if necessary, but fails
/// @param type The kind of the metric, e.g. gauge or count.
/// 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 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.
void
add_family
(
metric_type
type
,
std
::
string
prefix
,
std
::
string
name
,
std
::
vector
<
std
::
string
>
label_names
,
std
::
string
helptext
,
std
::
string
unit
=
"1"
,
bool
is_sum
=
false
);
/// Adds a new metric family to the registry.
/// @param prefix The prefix (namespace) this family belongs to. Usually the
/// @param prefix The prefix (namespace) this family belongs to. Usually the
/// application or protocol name, e.g., `http`. The prefix `caf`
/// application or protocol name, e.g., `http`. The prefix `caf`
/// as well as prefixes starting with an underscore are
/// as well as prefixes starting with an underscore are
...
@@ -76,25 +59,40 @@ public:
...
@@ -76,25 +59,40 @@ 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
Type
>
template
<
class
Type
>
metric_family_impl
<
Type
>*
metric_family_impl
<
Type
>*
family
(
string_view
prefix
,
string_view
name
,
add_family
(
std
::
string
prefix
,
std
::
string
name
,
span
<
const
string_view
>
label_names
,
std
::
vector
<
std
::
string
>
label_names
,
std
::
string
helptext
,
string_view
helptext
,
string_view
unit
=
"1"
,
std
::
string
unit
=
"1"
,
bool
is_sum
=
false
)
{
bool
is_sum
=
false
)
{
using
family_type
=
metric_family_impl
<
Type
>
;
using
family_type
=
metric_family_impl
<
Type
>
;
std
::
sort
(
label_names
.
begin
(),
label_names
.
end
());
auto
ptr
=
std
::
make_unique
<
family_type
>
(
std
::
move
(
prefix
),
std
::
move
(
name
),
std
::
move
(
label_names
),
std
::
move
(
helptext
),
std
::
move
(
unit
),
is_sum
);
std
::
unique_lock
<
std
::
mutex
>
guard
{
families_mx_
};
std
::
unique_lock
<
std
::
mutex
>
guard
{
families_mx_
};
assert_unregistered
(
ptr
->
prefix
(),
ptr
->
name
());
if
(
auto
ptr
=
fetch
(
prefix
,
name
))
{
assert_properties
(
ptr
,
Type
::
runtime_type
,
label_names
,
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
(
label_names
),
to_string
(
helptext
),
to_string
(
unit
),
is_sum
);
auto
&
families
=
container_by_type
<
Type
>
();
auto
&
families
=
container_by_type
<
Type
>
();
families
.
emplace_back
(
std
::
move
(
ptr
));
families
.
emplace_back
(
std
::
move
(
ptr
));
return
families
.
back
().
get
();
return
families
.
back
().
get
();
}
}
/// Adds a new metric singleton, i.e., a family without label dimensions and
/// @copydoc family
/// thus exactly one metric instance.
template
<
class
Type
>
metric_family_impl
<
Type
>*
family
(
string_view
prefix
,
string_view
name
,
std
::
initializer_list
<
string_view
>
label_names
,
string_view
helptext
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
return
family
<
Type
>
(
prefix
,
name
,
span
<
const
string_view
>
{
label_names
.
begin
(),
label_names
.
size
()},
helptext
,
unit
,
is_sum
);
}
/// Returns a 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
/// @param prefix The prefix (namespace) this family belongs to. Usually the
/// application or protocol name, e.g., `http`. The prefix `caf`
/// application or protocol name, e.g., `http`. The prefix `caf`
/// as well as prefixes starting with an underscore are
/// as well as prefixes starting with an underscore are
...
@@ -108,17 +106,12 @@ public:
...
@@ -108,17 +106,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
Type
>
template
<
class
Type
>
Type
*
add_singleton
(
std
::
string
prefix
,
std
::
string
name
,
Type
*
singleton
(
string_view
prefix
,
string_view
name
,
string_view
helptext
,
std
::
string
helptext
,
std
::
string
unit
=
"1"
,
string_view
unit
=
"1"
,
bool
is_sum
=
false
)
{
bool
is_sum
=
false
)
{
auto
fptr
=
family
<
Type
>
(
prefix
,
name
,
{},
helptext
,
unit
,
is_sum
);
auto
fptr
=
add_family
<
Type
>
(
std
::
move
(
prefix
),
std
::
move
(
name
),
{},
std
::
move
(
helptext
),
std
::
move
(
unit
),
is_sum
);
return
fptr
->
get_or_add
({});
return
fptr
->
get_or_add
({});
}
}
telemetry
::
int_gauge
*
int_gauge
(
string_view
prefix
,
string_view
name
,
std
::
vector
<
label_view
>
labels
);
template
<
class
Collector
>
template
<
class
Collector
>
void
collect
(
Collector
&
collector
)
const
{
void
collect
(
Collector
&
collector
)
const
{
std
::
unique_lock
<
std
::
mutex
>
guard
{
families_mx_
};
std
::
unique_lock
<
std
::
mutex
>
guard
{
families_mx_
};
...
@@ -128,7 +121,22 @@ public:
...
@@ -128,7 +121,22 @@ public:
private:
private:
/// @pre `families_mx_` is locked.
/// @pre `families_mx_` is locked.
void
assert_unregistered
(
const
std
::
string
&
prefix
,
const
std
::
string
&
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
)
{
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
;
}
void
assert_properties
(
metric_family
*
ptr
,
metric_type
type
,
span
<
const
string_view
>
label_names
,
string_view
unit
,
bool
is_sum
);
template
<
class
Type
>
template
<
class
Type
>
metric_family_container
<
Type
>&
container_by_type
();
metric_family_container
<
Type
>&
container_by_type
();
...
...
libcaf_core/src/actor_registry.cpp
View file @
f20b13b0
...
@@ -49,7 +49,7 @@ actor_registry::~actor_registry() {
...
@@ -49,7 +49,7 @@ actor_registry::~actor_registry() {
}
}
actor_registry
::
actor_registry
(
actor_system
&
sys
)
:
system_
(
sys
)
{
actor_registry
::
actor_registry
(
actor_system
&
sys
)
:
system_
(
sys
)
{
running_
=
sys
.
telemetry
().
add_
singleton
<
telemetry
::
int_gauge
>
(
running_
=
sys
.
telemetry
().
singleton
<
telemetry
::
int_gauge
>
(
"caf"
,
"running_actors"
,
"Number of currently running actors."
);
"caf"
,
"running_actors"
,
"Number of currently running actors."
);
}
}
...
...
libcaf_core/src/telemetry/metric_registry.cpp
View file @
f20b13b0
...
@@ -35,74 +35,35 @@ metric_registry::~metric_registry() {
...
@@ -35,74 +35,35 @@ metric_registry::~metric_registry() {
// nop
// nop
}
}
telemetry
::
int_gauge
*
metric_family
*
metric_registry
::
fetch
(
const
string_view
&
prefix
,
metric_registry
::
int_gauge
(
string_view
prefix
,
string_view
name
,
const
string_view
&
name
)
{
std
::
vector
<
label_view
>
labels
)
{
auto
matches
=
[
&
](
const
auto
&
ptr
)
{
// Make sure labels are sorted by name.
return
ptr
->
prefix
()
==
prefix
&&
ptr
->
name
()
==
name
;
auto
cmp
=
[](
const
label_view
&
x
,
const
label_view
&
y
)
{
return
x
.
name
()
<
y
.
name
();
};
std
::
sort
(
labels
.
begin
(),
labels
.
end
(),
cmp
);
// Fetch the family.
auto
matches
=
[
&
](
const
auto
&
family
)
{
auto
lbl_cmp
=
[](
const
label_view
&
lbl
,
string_view
name
)
{
return
lbl
.
name
()
==
name
;
};
return
family
->
prefix
()
==
prefix
&&
family
->
name
()
==
name
&&
std
::
equal
(
labels
.
begin
(),
labels
.
end
(),
family
->
label_names
().
begin
(),
family
->
label_names
().
end
(),
lbl_cmp
);
};
};
using
family_type
=
metric_family_impl
<
telemetry
::
int_gauge
>
;
if
(
auto
i
=
std
::
find_if
(
int_gauges_
.
begin
(),
int_gauges_
.
end
(),
matches
);
family_type
*
fptr
;
i
!=
int_gauges_
.
end
())
{
return
i
->
get
();
std
::
unique_lock
<
std
::
mutex
>
guard
{
families_mx_
};
return
nullptr
;
auto
i
=
std
::
find_if
(
int_gauges_
.
begin
(),
int_gauges_
.
end
(),
matches
);
if
(
i
==
int_gauges_
.
end
())
{
std
::
string
prefix_str
{
prefix
.
begin
(),
prefix
.
end
()};
std
::
string
name_str
{
name
.
begin
(),
name
.
end
()};
assert_unregistered
(
prefix_str
,
name_str
);
std
::
vector
<
std
::
string
>
label_names
;
label_names
.
reserve
(
labels
.
size
());
for
(
auto
&
lbl
:
labels
)
{
auto
lbl_name
=
lbl
.
name
();
label_names
.
emplace_back
(
std
::
string
{
lbl_name
.
begin
(),
lbl_name
.
end
()});
}
auto
ptr
=
std
::
make_unique
<
family_type
>
(
std
::
move
(
prefix_str
),
std
::
move
(
name_str
),
std
::
move
(
label_names
),
""
,
"1"
,
false
);
i
=
int_gauges_
.
emplace
(
i
,
std
::
move
(
ptr
));
}
fptr
=
i
->
get
();
}
return
fptr
->
get_or_add
(
labels
);
}
}
void
metric_registry
::
add_family
(
metric_type
type
,
std
::
string
prefix
,
void
metric_registry
::
assert_properties
(
metric_family
*
ptr
,
metric_type
type
,
std
::
string
name
,
span
<
const
string_view
>
label_names
,
std
::
vector
<
std
::
string
>
label_names
,
string_view
unit
,
bool
is_sum
)
{
std
::
string
helptext
,
std
::
string
unit
,
auto
labels_match
=
[
&
]
{
bool
is_sum
)
{
const
auto
&
xs
=
ptr
->
label_names
();
namespace
t
=
caf
::
telemetry
;
const
auto
&
ys
=
label_names
;
switch
(
type
)
{
return
std
::
is_sorted
(
ys
.
begin
(),
ys
.
end
())
case
metric_type
:
:
int_gauge
:
?
std
::
equal
(
xs
.
begin
(),
xs
.
end
(),
ys
.
begin
(),
ys
.
end
())
add_family
<
t
::
int_gauge
>
(
std
::
move
(
prefix
),
std
::
move
(
name
),
:
std
::
is_permutation
(
xs
.
begin
(),
xs
.
end
(),
ys
.
begin
(),
ys
.
end
());
std
::
move
(
label_names
),
std
::
move
(
helptext
),
std
::
move
(
unit
),
is_sum
);
break
;
default:
CAF_RAISE_ERROR
(
"invalid metric type"
);
}
}
void
metric_registry
::
assert_unregistered
(
const
std
::
string
&
prefix
,
const
std
::
string
&
name
)
{
auto
matches
=
[
&
](
const
auto
&
ptr
)
{
return
ptr
->
prefix
()
==
prefix
&&
ptr
->
name
()
==
name
;
};
};
if
(
std
::
any_of
(
int_gauges_
.
begin
(),
int_gauges_
.
end
(),
matches
))
if
(
ptr
->
type
()
!=
type
)
CAF_RAISE_ERROR
(
"prefix and name already belong to an int gauge family"
);
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 @
f20b13b0
...
@@ -32,6 +32,7 @@ using namespace caf::telemetry;
...
@@ -32,6 +32,7 @@ using namespace caf::telemetry;
namespace
{
namespace
{
struct
fixture
{
struct
fixture
{
using
ig
=
int_gauge
;
collector
::
prometheus
exporter
;
collector
::
prometheus
exporter
;
metric_registry
registry
;
metric_registry
registry
;
};
};
...
@@ -41,21 +42,21 @@ struct fixture {
...
@@ -41,21 +42,21 @@ struct fixture {
CAF_TEST_FIXTURE_SCOPE
(
prometheus_tests
,
fixture
)
CAF_TEST_FIXTURE_SCOPE
(
prometheus_tests
,
fixture
)
CAF_TEST
(
the
Prometheus
collector
generates
text
output
)
{
CAF_TEST
(
the
Prometheus
collector
generates
text
output
)
{
registry
.
add_family
(
metric_type
::
int_gauge
,
"foo"
,
"bar"
,
{}
,
auto
fb
=
registry
.
family
<
ig
>
(
"foo"
,
"bar"
,
{},
"Some value without labels."
,
"Just some value without labels."
,
"seconds"
);
"seconds"
);
registry
.
add_family
(
metric_type
::
int_gauge
,
"some"
,
"value"
,
{
"a"
,
"b"
},
auto
sv
=
registry
.
family
<
ig
>
(
"some"
,
"value"
,
{
"a"
,
"b"
},
"Just some (total) value with two labels."
,
"1"
,
true
);
"Some (total) value with two labels."
,
"1"
,
registry
.
add_family
(
metric_type
::
int_gauge
,
"other"
,
"value"
,
{
"x"
},
""
,
true
);
"seconds"
,
true
);
auto
ov
=
registry
.
family
<
ig
>
(
"other"
,
"value"
,
{
"x"
},
""
,
"seconds"
,
true
);
registry
.
int_gauge
(
"foo"
,
"bar"
,
{})
->
value
(
123
);
fb
->
get_or_add
(
{})
->
value
(
123
);
registry
.
int_gauge
(
"some"
,
"value"
,
{{
"a"
,
"1"
},
{
"b"
,
"2"
}})
->
value
(
12
);
sv
->
get_or_add
(
{{
"a"
,
"1"
},
{
"b"
,
"2"
}})
->
value
(
12
);
registry
.
int_gauge
(
"some"
,
"value"
,
{{
"b"
,
"1"
},
{
"a"
,
"2"
}})
->
value
(
21
);
sv
->
get_or_add
(
{{
"b"
,
"1"
},
{
"a"
,
"2"
}})
->
value
(
21
);
registry
.
int_gauge
(
"other"
,
"value"
,
{{
"x"
,
"true"
}})
->
value
(
31337
);
ov
->
get_or_add
(
{{
"x"
,
"true"
}})
->
value
(
31337
);
CAF_CHECK_EQUAL
(
exporter
.
collect_from
(
registry
,
42
),
CAF_CHECK_EQUAL
(
exporter
.
collect_from
(
registry
,
42
),
R"(# HELP foo_bar_seconds
Just s
ome value without labels.
R"(# HELP foo_bar_seconds
S
ome value without labels.
# TYPE foo_bar_seconds gauge
# TYPE foo_bar_seconds gauge
foo_bar_seconds 123 42
foo_bar_seconds 123 42
# HELP some_value_total
Just s
ome (total) value with two labels.
# HELP some_value_total
S
ome (total) value with two labels.
# TYPE some_value_total gauge
# TYPE some_value_total gauge
some_value_total{a="1",b="2"} 12 42
some_value_total{a="1",b="2"} 12 42
some_value_total{a="2",b="1"} 21 42
some_value_total{a="2",b="1"} 21 42
...
...
libcaf_core/test/telemetry/int_gauge.cpp
View file @
f20b13b0
...
@@ -29,12 +29,12 @@ CAF_TEST(integer gauges can increment and decrement) {
...
@@ -29,12 +29,12 @@ CAF_TEST(integer gauges can increment and decrement) {
CAF_MESSAGE
(
"gauges start at 0"
);
CAF_MESSAGE
(
"gauges start at 0"
);
CAF_CHECK_EQUAL
(
g
.
value
(),
0
);
CAF_CHECK_EQUAL
(
g
.
value
(),
0
);
CAF_MESSAGE
(
"gauges are incrementable"
);
CAF_MESSAGE
(
"gauges are incrementable"
);
g
.
inc
rement
();
g
.
inc
();
g
.
inc
rement
(
2
);
g
.
inc
(
2
);
CAF_CHECK_EQUAL
(
g
.
value
(),
3
);
CAF_CHECK_EQUAL
(
g
.
value
(),
3
);
CAF_MESSAGE
(
"gauges are decrementable"
);
CAF_MESSAGE
(
"gauges are decrementable"
);
g
.
dec
rement
();
g
.
dec
();
g
.
dec
rement
(
5
);
g
.
dec
(
5
);
CAF_CHECK_EQUAL
(
g
.
value
(),
-
3
);
CAF_CHECK_EQUAL
(
g
.
value
(),
-
3
);
CAF_MESSAGE
(
"gauges allow setting values"
);
CAF_MESSAGE
(
"gauges allow setting values"
);
g
.
value
(
42
);
g
.
value
(
42
);
...
...
libcaf_core/test/telemetry/metric_registry.cpp
View file @
f20b13b0
...
@@ -32,7 +32,7 @@ using namespace caf::telemetry;
...
@@ -32,7 +32,7 @@ using namespace caf::telemetry;
namespace
{
namespace
{
struct
collector
{
struct
test_
collector
{
std
::
string
result
;
std
::
string
result
;
void
operator
()(
const
metric_family
*
family
,
const
metric
*
instance
,
void
operator
()(
const
metric_family
*
family
,
const
metric
*
instance
,
...
@@ -70,19 +70,9 @@ struct collector {
...
@@ -70,19 +70,9 @@ struct collector {
};
};
struct
fixture
{
struct
fixture
{
using
ig
=
int_gauge
;
metric_registry
registry
;
metric_registry
registry
;
test_collector
collector
;
auto
bind
(
string_view
prefix
,
string_view
name
)
{
struct
bound
{
fixture
*
self_
;
string_view
prefix_
;
string_view
name_
;
auto
int_gauge
(
std
::
vector
<
label_view
>
labels
)
{
return
self_
->
registry
.
int_gauge
(
prefix_
,
name_
,
std
::
move
(
labels
));
}
};
return
bound
{
this
,
prefix
,
name
};
}
};
};
}
// namespace
}
// namespace
...
@@ -90,46 +80,53 @@ struct fixture {
...
@@ -90,46 +80,53 @@ struct fixture {
CAF_TEST_FIXTURE_SCOPE
(
metric_registry_tests
,
fixture
)
CAF_TEST_FIXTURE_SCOPE
(
metric_registry_tests
,
fixture
)
CAF_TEST
(
registries
lazily
create
metrics
)
{
CAF_TEST
(
registries
lazily
create
metrics
)
{
registry
.
add_family
(
metric_type
::
int_gauge
,
"caf"
,
"running_actors"
,
auto
f
=
registry
.
family
<
ig
>
(
"caf"
,
"running_actors"
,
{
"var1"
,
"var2"
},
{
"var1"
,
"var2"
},
"How many actors are currently running?"
);
"How many actors are currently running?"
);
auto
var
=
bind
(
"caf"
,
"running_actors"
);
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"
}};
std
::
vector
<
label_view
>
v2_reversed
{{
"var2"
,
"foo"
},
{
"var1"
,
"bar"
}};
std
::
vector
<
label_view
>
v2_reversed
{{
"var2"
,
"foo"
},
{
"var1"
,
"bar"
}};
var
.
int_gauge
(
v1
)
->
value
(
42
);
f
->
get_or_add
(
v1
)
->
value
(
42
);
var
.
int_gauge
(
v2
)
->
value
(
23
);
f
->
get_or_add
(
v2
)
->
value
(
23
);
CAF_CHECK_EQUAL
(
var
.
int_gauge
(
v1
)
->
value
(),
42
);
CAF_CHECK_EQUAL
(
f
->
get_or_add
(
v1
)
->
value
(),
42
);
CAF_CHECK_EQUAL
(
var
.
int_gauge
(
v1_reversed
)
->
value
(),
42
);
CAF_CHECK_EQUAL
(
f
->
get_or_add
(
v1_reversed
)
->
value
(),
42
);
CAF_CHECK_EQUAL
(
var
.
int_gauge
(
v2
)
->
value
(),
23
);
CAF_CHECK_EQUAL
(
f
->
get_or_add
(
v2
)
->
value
(),
23
);
CAF_CHECK_EQUAL
(
var
.
int_gauge
(
v2_reversed
)
->
value
(),
23
);
CAF_CHECK_EQUAL
(
f
->
get_or_add
(
v2_reversed
)
->
value
(),
23
);
}
}
CAF_TEST
(
registries
allow
users
to
collect
all
registered
metrics
)
{
CAF_TEST
(
registries
allow
users
to
collect
all
registered
metrics
)
{
registry
.
add_family
(
metric_type
::
int_gauge
,
"foo"
,
"bar"
,
{},
auto
fb
=
registry
.
family
<
ig
>
(
"foo"
,
"bar"
,
{},
"Some value without labels."
,
"Just some value without labels."
,
"seconds"
);
"seconds"
);
registry
.
add_family
(
metric_type
::
int_gauge
,
"some"
,
"value"
,
{
"a"
,
"b"
},
auto
sv
=
registry
.
family
<
ig
>
(
"some"
,
"value"
,
{
"a"
,
"b"
},
"Just some (total) value with two labels."
,
"1"
,
true
);
"Some (total) value with two labels."
,
"1"
,
registry
.
add_family
(
metric_type
::
int_gauge
,
"other"
,
"value"
,
{
"x"
},
true
);
"Just some (total) seconds value with a labels."
,
auto
ov
=
registry
.
family
<
ig
>
(
"other"
,
"value"
,
{
"x"
},
"seconds"
,
true
);
"Some (total) seconds with one label."
,
registry
.
add_family
(
metric_type
::
int_gauge
,
"caf"
,
"running_actors"
,
{
"node"
},
"seconds"
,
true
);
"How many actors are currently running?"
);
auto
ra
=
registry
.
family
<
ig
>
(
"caf"
,
"running_actors"
,
{
"node"
},
registry
.
int_gauge
(
"foo"
,
"bar"
,
{})
->
value
(
123
);
"How many actors are running?"
);
registry
.
int_gauge
(
"some"
,
"value"
,
{{
"a"
,
"1"
},
{
"b"
,
"2"
}})
->
value
(
12
);
auto
ms
=
registry
.
family
<
ig
>
(
"caf"
,
"mailbox_size"
,
{
"name"
},
registry
.
int_gauge
(
"some"
,
"value"
,
{{
"b"
,
"1"
},
{
"a"
,
"2"
}})
->
value
(
21
);
"How full is the mailbox?"
);
registry
.
int_gauge
(
"other"
,
"value"
,
{{
"x"
,
"true"
}})
->
value
(
31337
);
CAF_MESSAGE
(
"the registry always returns the same family object"
);
auto
running_actors
=
bind
(
"caf"
,
"running_actors"
);
CAF_CHECK_EQUAL
(
fb
,
registry
.
family
<
ig
>
(
"foo"
,
"bar"
,
{},
""
,
"seconds"
));
running_actors
.
int_gauge
({{
"node"
,
"localhost"
}})
->
value
(
42
);
CAF_CHECK_EQUAL
(
sv
,
registry
.
family
<
ig
>
(
"some"
,
"value"
,
{
"a"
,
"b"
},
""
,
"1"
,
// Note: not registering caf_mailbox_size previously forces CAF to create it
true
));
// lazily when adding the first gauge.
CAF_CHECK_EQUAL
(
sv
,
registry
.
family
<
ig
>
(
"some"
,
"value"
,
{
"b"
,
"a"
},
""
,
"1"
,
auto
mailbox_size
=
bind
(
"caf"
,
"mailbox_size"
);
true
));
mailbox_size
.
int_gauge
({{
"name"
,
"printer"
}})
->
value
(
3
);
CAF_MESSAGE
(
"families always return the same metric object for given labels"
);
mailbox_size
.
int_gauge
({{
"name"
,
"parser"
}})
->
value
(
12
);
CAF_CHECK_EQUAL
(
fb
->
get_or_add
({}),
fb
->
get_or_add
({}));
collector
c
;
CAF_CHECK_EQUAL
(
sv
->
get_or_add
({{
"a"
,
"1"
},
{
"b"
,
"2"
}}),
registry
.
collect
(
c
);
sv
->
get_or_add
({{
"b"
,
"2"
},
{
"a"
,
"1"
}}));
CAF_CHECK_EQUAL
(
c
.
result
,
R"(
CAF_MESSAGE
(
"collectors can observe all metrics in the registry"
);
fb
->
get_or_add
({})
->
inc
(
123
);
sv
->
get_or_add
({{
"a"
,
"1"
},
{
"b"
,
"2"
}})
->
value
(
12
);
sv
->
get_or_add
({{
"b"
,
"1"
},
{
"a"
,
"2"
}})
->
value
(
21
);
ov
->
get_or_add
({{
"x"
,
"true"
}})
->
value
(
31337
);
ra
->
get_or_add
({{
"node"
,
"localhost"
}})
->
value
(
42
);
ms
->
get_or_add
({{
"name"
,
"printer"
}})
->
value
(
3
);
ms
->
get_or_add
({{
"name"
,
"parser"
}})
->
value
(
12
);
registry
.
collect
(
collector
);
CAF_CHECK_EQUAL
(
collector
.
result
,
R"(
foo_bar_seconds 123
foo_bar_seconds 123
some_value_total{a="1",b="2"} 12
some_value_total{a="1",b="2"} 12
some_value_total{a="2",b="1"} 21
some_value_total{a="2",b="1"} 21
...
...
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