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
5d1802d8
Commit
5d1802d8
authored
Sep 04, 2022
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Backport process_open_fds metric
parent
5498fe5e
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
110 additions
and
24 deletions
+110
-24
libcaf_core/caf/telemetry/importer/process.hpp
libcaf_core/caf/telemetry/importer/process.hpp
+1
-0
libcaf_core/src/telemetry/importer/process.cpp
libcaf_core/src/telemetry/importer/process.cpp
+109
-24
No files found.
libcaf_core/caf/telemetry/importer/process.hpp
View file @
5d1802d8
...
...
@@ -31,6 +31,7 @@ private:
telemetry
::
int_gauge
*
rss_
=
nullptr
;
telemetry
::
int_gauge
*
vms_
=
nullptr
;
telemetry
::
dbl_gauge
*
cpu_
=
nullptr
;
telemetry
::
int_gauge
*
fds_
=
nullptr
;
};
}
// namespace caf::telemetry::importer
libcaf_core/src/telemetry/importer/process.cpp
View file @
5d1802d8
...
...
@@ -10,7 +10,7 @@
// -- detect supported platforms -----------------------------------------------
#if defined(CAF_MACOS) || defined(CAF_LINUX)
#if defined(CAF_MACOS) || defined(CAF_LINUX)
|| defined(CAF_NET_BSD)
# define CAF_HAS_PROCESS_METRICS
#endif
...
...
@@ -21,18 +21,19 @@
namespace
{
struct
sys_stats
{
int64_t
rss
;
int64_t
vms
;
double
cpu_time
;
int64_t
rss
=
0
;
int64_t
vms
=
0
;
double
cpu_time
=
0.0
;
int64_t
fds
=
0
;
};
sys_stats
read_sys_stats
();
static
constexpr
bool
platform_supported_v
=
true
;
constexpr
bool
platform_supported_v
=
true
;
template
<
class
CpuPtr
,
class
RssPtr
,
class
VmsPtr
>
template
<
class
CpuPtr
,
class
RssPtr
,
class
VmsPtr
,
class
FdsPtr
>
void
sys_stats_init
(
caf
::
telemetry
::
metric_registry
&
reg
,
RssPtr
&
rss
,
VmsPtr
&
vms
,
CpuPtr
&
cpu
)
{
VmsPtr
&
vms
,
CpuPtr
&
cpu
,
FdsPtr
&
fds
)
{
rss
=
reg
.
gauge_singleton
(
"process"
,
"resident_memory"
,
"Resident memory size."
,
"bytes"
);
vms
=
reg
.
gauge_singleton
(
"process"
,
"virtual_memory"
,
"Virtual memory size."
,
...
...
@@ -40,15 +41,19 @@ void sys_stats_init(caf::telemetry::metric_registry& reg, RssPtr& rss,
cpu
=
reg
.
gauge_singleton
<
double
>
(
"process"
,
"cpu"
,
"Total user and system CPU time spent."
,
"seconds"
,
true
);
fds
=
reg
.
gauge_singleton
(
"process"
,
"open_fds"
,
"Number of open file descriptors."
);
}
void
update_impl
(
caf
::
telemetry
::
int_gauge
*
rss_gauge
,
caf
::
telemetry
::
int_gauge
*
vms_gauge
,
caf
::
telemetry
::
dbl_gauge
*
cpu_gauge
)
{
auto
[
rss
,
vmsize
,
cpu
]
=
read_sys_stats
();
caf
::
telemetry
::
dbl_gauge
*
cpu_gauge
,
caf
::
telemetry
::
int_gauge
*
fds_gauge
)
{
auto
[
rss
,
vmsize
,
cpu
,
fds
]
=
read_sys_stats
();
rss_gauge
->
value
(
rss
);
vms_gauge
->
value
(
vmsize
);
cpu_gauge
->
value
(
cpu
);
fds_gauge
->
value
(
fds
);
}
}
// namespace
...
...
@@ -57,7 +62,7 @@ void update_impl(caf::telemetry::int_gauge* rss_gauge,
namespace
{
static
constexpr
bool
platform_supported_v
=
false
;
constexpr
bool
platform_supported_v
=
false
;
template
<
class
...
Ts
>
void
sys_stats_init
(
Ts
&&
...)
{
...
...
@@ -77,14 +82,16 @@ void update_impl(Ts&&...) {
#ifdef CAF_MACOS
# include <libproc.h>
# include <mach/mach.h>
# include <mach/task.h>
# include <sys/resource.h>
# include <unistd.h>
namespace
{
sys_stats
read_sys_stats
()
{
sys_stats
result
{
0
,
0
,
0
}
;
sys_stats
result
;
// Fetch memory usage.
{
mach_task_basic_info
info
;
...
...
@@ -110,6 +117,20 @@ sys_stats read_sys_stats() {
result
.
cpu_time
+=
ceil
(
info
.
system_time
.
microseconds
/
1000.0
)
/
1000.0
;
}
}
// Fetch open file handles.
{
// proc_pidinfo is undocumented, but this is what lsof also uses.
auto
suggested_buf_size
=
proc_pidinfo
(
getpid
(),
PROC_PIDLISTFDS
,
0
,
nullptr
,
0
);
if
(
suggested_buf_size
>
0
)
{
auto
buf_size
=
suggested_buf_size
;
auto
buf
=
malloc
(
buf_size
);
// TODO: could be thread-local
auto
res
=
proc_pidinfo
(
getpid
(),
PROC_PIDLISTFDS
,
0
,
buf
,
buf_size
);
free
(
buf
);
if
(
res
>
0
)
result
.
fds
=
res
/
sizeof
(
proc_fdinfo
);
}
}
return
result
;
}
...
...
@@ -117,19 +138,31 @@ sys_stats read_sys_stats() {
#endif // CAF_MACOS
// --
Linux-specific scraping logic -------------
-------------------------------
// --
helper for caching the result of a syscall
-------------------------------
#if
def CAF_LINUX
#if
defined(CAF_LINUX) || defined(CAF_NET_BSD)
# include <
cstdio
>
# include <
dirent.h
>
# include <unistd.h>
namespace
{
std
::
atomic
<
long
>
global_ticks_per_second
;
std
::
atomic
<
long
>
global_page_size
;
int64_t
count_entries_in_directory
(
const
char
*
path
)
{
int64_t
result
=
0
;
if
(
auto
dptr
=
opendir
(
path
);
dptr
!=
nullptr
)
{
for
(
auto
entry
=
readdir
(
dptr
);
entry
!=
nullptr
;
entry
=
readdir
(
dptr
))
{
auto
fname
=
entry
->
d_name
;
if
(
strcmp
(
"."
,
fname
)
!=
0
&&
strcmp
(
".."
,
fname
)
!=
0
)
++
result
;
}
closedir
(
dptr
);
}
return
result
;
}
/// Caches the result from a `sysconf` call in a cache variable to avoid
/// frequent syscalls. Sets `cache_var` to -1 in case of an error. Initially,
/// `cache_var` must be 0 and we assume a successful syscall would always return
/// some value > 0. If `cache_var` is > 0 then this function simply returns the
/// cached value directly.
bool
load_system_setting
(
std
::
atomic
<
long
>&
cache_var
,
long
&
var
,
int
name
,
[[
maybe_unused
]]
const
char
*
pretty_name
)
{
var
=
cache_var
.
load
();
...
...
@@ -143,9 +176,10 @@ bool load_system_setting(std::atomic<long>& cache_var, long& var, int name,
var
=
-
1
;
cache_var
=
var
;
return
false
;
}
else
{
cache_var
=
var
;
return
true
;
}
cache_var
=
var
;
return
true
;
default:
return
true
;
}
...
...
@@ -154,8 +188,23 @@ bool load_system_setting(std::atomic<long>& cache_var, long& var, int name,
# define TRY_LOAD(varname, confname) \
load_system_setting(global_##varname, varname, confname, #confname)
#endif
// -- Linux-specific scraping logic --------------------------------------------
#ifdef CAF_LINUX
# include <cstdio>
# include <dirent.h>
namespace
{
std
::
atomic
<
long
>
global_ticks_per_second
;
std
::
atomic
<
long
>
global_page_size
;
sys_stats
read_sys_stats
()
{
sys_stats
result
{
0
,
0
,
0
}
;
sys_stats
result
;
long
ticks_per_second
=
0
;
long
page_size
=
0
;
if
(
!
TRY_LOAD
(
ticks_per_second
,
_SC_CLK_TCK
)
...
...
@@ -205,6 +254,42 @@ sys_stats read_sys_stats() {
result
.
cpu_time
+=
stime_ticks
;
result
.
cpu_time
/=
ticks_per_second
;
}
result
.
fds
=
count_entries_in_directory
(
"/proc/self/fd"
);
return
result
;
}
}
// namespace
// -- NetBSD-specific scraping logic -------------------------------------------
#elif defined(CAF_NET_BSD)
# include <sys/sysctl.h>
namespace
{
std
::
atomic
<
long
>
global_page_size
;
sys_stats
read_sys_stats
()
{
auto
result
=
sys_stats
;
auto
kip2
=
kinfo_proc2
{};
auto
kip2_size
=
sizeof
(
kip2
);
int
mib
[
6
]
=
{
CTL_KERN
,
KERN_PROC2
,
KERN_PROC_PID
,
getpid
(),
static_cast
<
int
>
(
kip2_size
),
1
,
};
long
page_size
=
0
;
if
(
!
TRY_LOAD
(
page_size
,
_SC_PAGE_SIZE
))
return
result
;
if
(
sysctl
(
mib
,
6
,
&
kip2
,
&
kip2_size
,
nullptr
,
size_t
{
0
})
!=
0
)
{
CAF_LOG_ERROR
(
"failed to call sysctl in read_sys_stats"
);
global_page_size
=
-
1
;
return
result
;
}
result
.
rss
=
static_cast
<
int64_t
>
(
kip2
.
p_vm_rssize
)
*
page_size
;
result
.
vms
=
static_cast
<
int64_t
>
(
kip2
.
p_vm_vsize
)
*
page_size
;
result
.
cpu_time
=
kip2
.
p_rtime_sec
;
result
.
cpu_time
+=
static_cast
<
double
>
(
kip2
.
p_rtime_usec
)
/
1000000
;
return
result
;
}
...
...
@@ -215,7 +300,7 @@ sys_stats read_sys_stats() {
namespace
caf
::
telemetry
::
importer
{
process
::
process
(
metric_registry
&
reg
)
{
sys_stats_init
(
reg
,
rss_
,
vms_
,
cpu_
);
sys_stats_init
(
reg
,
rss_
,
vms_
,
cpu_
,
fds_
);
}
bool
process
::
platform_supported
()
noexcept
{
...
...
@@ -223,7 +308,7 @@ bool process::platform_supported() noexcept {
}
void
process
::
update
()
{
update_impl
(
rss_
,
vms_
,
cpu_
);
update_impl
(
rss_
,
vms_
,
cpu_
,
fds_
);
}
}
// namespace caf::telemetry::importer
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