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
e1557797
Commit
e1557797
authored
Jun 16, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement histogram metrics
parent
94e59124
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
271 additions
and
6 deletions
+271
-6
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+1
-0
libcaf_core/caf/fwd.hpp
libcaf_core/caf/fwd.hpp
+30
-0
libcaf_core/caf/telemetry/dbl_gauge.hpp
libcaf_core/caf/telemetry/dbl_gauge.hpp
+12
-0
libcaf_core/caf/telemetry/gauge.hpp
libcaf_core/caf/telemetry/gauge.hpp
+25
-0
libcaf_core/caf/telemetry/histogram.hpp
libcaf_core/caf/telemetry/histogram.hpp
+114
-0
libcaf_core/caf/telemetry/int_gauge.hpp
libcaf_core/caf/telemetry/int_gauge.hpp
+17
-5
libcaf_core/caf/telemetry/metric_registry.hpp
libcaf_core/caf/telemetry/metric_registry.hpp
+8
-0
libcaf_core/caf/telemetry/metric_type.hpp
libcaf_core/caf/telemetry/metric_type.hpp
+3
-1
libcaf_core/test/telemetry/histogram.cpp
libcaf_core/test/telemetry/histogram.cpp
+61
-0
No files found.
libcaf_core/CMakeLists.txt
View file @
e1557797
...
...
@@ -310,6 +310,7 @@ caf_add_test_suites(caf-core-test
sum_type
telemetry.collector.prometheus
telemetry.dbl_gauge
telemetry.histogram
telemetry.int_gauge
telemetry.label
telemetry.metric_registry
...
...
libcaf_core/caf/fwd.hpp
View file @
e1557797
...
...
@@ -250,6 +250,36 @@ class metric_family_impl;
template
<
class
Type
>
class
metric_impl
;
template
<
class
ValueType
>
class
histogram
;
using
dbl_histogram
=
histogram
<
double
>
;
using
int_histogram
=
histogram
<
int64_t
>
;
}
// namespace telemetry
namespace
detail
{
template
<
class
>
struct
gauge_oracle
;
template
<
>
struct
gauge_oracle
<
double
>
{
using
type
=
telemetry
::
dbl_gauge
;
};
template
<
>
struct
gauge_oracle
<
int64_t
>
{
using
type
=
telemetry
::
int_gauge
;
};
}
// namespace detail
namespace
telemetry
{
template
<
class
ValueType
>
using
gauge
=
typename
detail
::
gauge_oracle
<
ValueType
>::
type
;
}
// namespace telemetry
// -- I/O classes --------------------------------------------------------------
...
...
libcaf_core/caf/telemetry/dbl_gauge.hpp
View file @
e1557797
...
...
@@ -31,8 +31,16 @@ namespace caf::telemetry {
/// and down.
class
CAF_CORE_EXPORT
dbl_gauge
{
public:
// -- member types -----------------------------------------------------------
using
value_type
=
double
;
// -- constants --------------------------------------------------------------
static
constexpr
metric_type
runtime_type
=
metric_type
::
dbl_gauge
;
// -- constructors, destructors, and assignment operators --------------------
dbl_gauge
()
noexcept
:
value_
(
0
)
{
// nop
}
...
...
@@ -41,6 +49,8 @@ public:
// nop
}
// -- modifiers --------------------------------------------------------------
/// Increments the gauge by 1.
void
inc
()
noexcept
{
inc
(
1.0
);
...
...
@@ -70,6 +80,8 @@ public:
value_
.
store
(
x
);
}
// -- observers --------------------------------------------------------------
/// Returns the current value of the gauge.
double
value
()
const
noexcept
{
return
value_
.
load
();
...
...
libcaf_core/caf/telemetry/gauge.hpp
0 → 100644
View file @
e1557797
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
// convenience header for including all gauge types
#include "caf/fwd.hpp"
#include "caf/telemetry/dbl_gauge.hpp"
#include "caf/telemetry/int_gauge.hpp"
libcaf_core/caf/telemetry/histogram.hpp
0 → 100644
View file @
e1557797
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <algorithm>
#include <type_traits>
#include "caf/config.hpp"
#include "caf/fwd.hpp"
#include "caf/span.hpp"
#include "caf/telemetry/gauge.hpp"
#include "caf/telemetry/metric_type.hpp"
namespace
caf
::
telemetry
{
/// Represent aggregatable distributions of events.
template
<
class
ValueType
>
class
histogram
{
public:
// -- member types -----------------------------------------------------------
using
value_type
=
ValueType
;
using
gauge_type
=
gauge
<
value_type
>
;
struct
bucket_type
{
value_type
upper_bound
;
gauge_type
gauge
;
};
// -- constants --------------------------------------------------------------
static
constexpr
metric_type
runtime_type
=
std
::
is_same
<
value_type
,
double
>::
value
?
metric_type
::
dbl_histogram
:
metric_type
::
int_histogram
;
// -- constructors, destructors, and assignment operators --------------------
histogram
(
span
<
const
value_type
>
upper_bounds
)
{
using
limits
=
std
::
numeric_limits
<
value_type
>
;
CAF_ASSERT
(
std
::
is_sorted
(
upper_bounds
.
begin
(),
upper_bounds
.
end
()));
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
();
}
histogram
(
std
::
initializer_list
<
value_type
>
upper_bounds
)
:
histogram
(
make_span
(
upper_bounds
.
begin
(),
upper_bounds
.
size
()))
{
// nop
}
~
histogram
()
{
delete
[]
buckets_
;
}
// -- modifiers --------------------------------------------------------------
void
observe
(
value_type
value
)
{
// The last bucket has an upper bound of +inf or int_max, so we'll always
// find a bucket and increment the gauges.
for
(
size_t
index
=
0
;;
++
index
)
{
auto
&
[
upper_bound
,
gauge
]
=
buckets_
[
index
];
if
(
value
<=
upper_bound
)
{
gauge
.
inc
();
sum_
.
inc
(
value
);
return
;
}
}
}
// -- observers --------------------------------------------------------------
span
<
const
bucket_type
>
buckets
()
const
noexcept
{
return
{
buckets_
,
num_buckets_
};
}
value_type
sum
()
const
noexcept
{
return
sum_
.
value
();
}
private:
size_t
num_buckets_
;
bucket_type
*
buckets_
;
gauge_type
sum_
;
};
///
using
dbl_histogram
=
histogram
<
double
>
;
using
int_histogram
=
histogram
<
int64_t
>
;
}
// namespace caf::telemetry
libcaf_core/caf/telemetry/int_gauge.hpp
View file @
e1557797
...
...
@@ -31,8 +31,16 @@ namespace caf::telemetry {
/// and down.
class
CAF_CORE_EXPORT
int_gauge
{
public:
// -- member types -----------------------------------------------------------
using
value_type
=
int64_t
;
// -- constants --------------------------------------------------------------
static
constexpr
metric_type
runtime_type
=
metric_type
::
int_gauge
;
// -- constructors, destructors, and assignment operators --------------------
int_gauge
()
noexcept
:
value_
(
0
)
{
// nop
}
...
...
@@ -41,6 +49,8 @@ public:
// nop
}
// -- modifiers --------------------------------------------------------------
/// Increments the gauge by 1.
void
inc
()
noexcept
{
++
value_
;
...
...
@@ -66,11 +76,6 @@ public:
value_
.
store
(
x
);
}
/// Returns the current value of the gauge.
int64_t
value
()
const
noexcept
{
return
value_
.
load
();
}
/// Increments the gauge by 1.
/// @returns The new value of the gauge.
int64_t
operator
++
()
noexcept
{
...
...
@@ -83,6 +88,13 @@ public:
return
--
value_
;
}
// -- observers --------------------------------------------------------------
/// Returns the current value of the gauge.
int64_t
value
()
const
noexcept
{
return
value_
.
load
();
}
private:
std
::
atomic
<
int64_t
>
value_
;
};
...
...
libcaf_core/caf/telemetry/metric_registry.hpp
View file @
e1557797
...
...
@@ -33,16 +33,22 @@ namespace caf::telemetry {
/// Manages a collection of metric families.
class
CAF_CORE_EXPORT
metric_registry
{
public:
// -- member types -----------------------------------------------------------
template
<
class
Type
>
using
metric_family_ptr
=
std
::
unique_ptr
<
metric_family_impl
<
Type
>>
;
template
<
class
Type
>
using
metric_family_container
=
std
::
vector
<
metric_family_ptr
<
Type
>>
;
// -- constructors, destructors, and assignment operators --------------------
metric_registry
();
~
metric_registry
();
// -- factories --------------------------------------------------------------
/// Returns a metric family. 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
...
...
@@ -112,6 +118,8 @@ public:
return
fptr
->
get_or_add
({});
}
// -- observers --------------------------------------------------------------
template
<
class
Collector
>
void
collect
(
Collector
&
collector
)
const
{
std
::
unique_lock
<
std
::
mutex
>
guard
{
families_mx_
};
...
...
libcaf_core/caf/telemetry/metric_type.hpp
View file @
e1557797
...
...
@@ -21,8 +21,10 @@
namespace
caf
::
telemetry
{
enum
class
metric_type
:
uint8_t
{
int_gauge
,
dbl_gauge
,
int_gauge
,
dbl_histogram
,
int_histogram
,
};
}
// namespace caf::telemetry
libcaf_core/test/telemetry/histogram.cpp
0 → 100644
View file @
e1557797
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#define CAF_SUITE telemetry.histogram
#include "caf/telemetry/histogram.hpp"
#include "caf/test/dsl.hpp"
#include <cmath>
#include <limits>
#include "caf/telemetry/gauge.hpp"
using
namespace
caf
;
using
namespace
caf
::
telemetry
;
CAF_TEST
(
double
histograms
use
infinity
for
the
last
bucket
)
{
dbl_histogram
h1
{
.1
,
.2
,
.4
,
.8
};
CAF_CHECK_EQUAL
(
h1
.
buckets
().
size
(),
5u
);
CAF_CHECK_EQUAL
(
h1
.
buckets
().
front
().
upper_bound
,
.1
);
CAF_CHECK
(
std
::
isinf
(
h1
.
buckets
().
back
().
upper_bound
));
CAF_CHECK_EQUAL
(
h1
.
sum
(),
0.0
);
}
CAF_TEST
(
integer
histograms
use
int_max
for
the
last
bucket
)
{
using
limits
=
std
::
numeric_limits
<
int64_t
>
;
int_histogram
h1
{
1
,
2
,
4
,
8
};
CAF_CHECK_EQUAL
(
h1
.
buckets
().
size
(),
5u
);
CAF_CHECK_EQUAL
(
h1
.
buckets
().
front
().
upper_bound
,
1
);
CAF_CHECK_EQUAL
(
h1
.
buckets
().
back
().
upper_bound
,
limits
::
max
());
CAF_CHECK_EQUAL
(
h1
.
sum
(),
0
);
}
CAF_TEST
(
histograms
aggregate
to
buckets
and
keep
a
sum
)
{
int_histogram
h1
{
2
,
4
,
8
};
for
(
int64_t
value
=
1
;
value
<
11
;
++
value
)
h1
.
observe
(
value
);
auto
buckets
=
h1
.
buckets
();
CAF_REQUIRE_EQUAL
(
buckets
.
size
(),
4u
);
CAF_CHECK_EQUAL
(
buckets
[
0
].
gauge
.
value
(),
2
);
// 1, 2
CAF_CHECK_EQUAL
(
buckets
[
1
].
gauge
.
value
(),
2
);
// 3, 4
CAF_CHECK_EQUAL
(
buckets
[
2
].
gauge
.
value
(),
4
);
// 5, 6, 7, 8
CAF_CHECK_EQUAL
(
buckets
[
3
].
gauge
.
value
(),
2
);
// 9, 10
CAF_CHECK_EQUAL
(
h1
.
sum
(),
55
);
}
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