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
94e59124
Commit
94e59124
authored
Jun 15, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement process metrics on Linux
parent
025fd322
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
124 additions
and
36 deletions
+124
-36
libcaf_io/src/detail/prometheus_broker.cpp
libcaf_io/src/detail/prometheus_broker.cpp
+124
-36
No files found.
libcaf_io/src/detail/prometheus_broker.cpp
View file @
94e59124
...
...
@@ -24,6 +24,16 @@
#include "caf/telemetry/dbl_gauge.hpp"
#include "caf/telemetry/int_gauge.hpp"
namespace
{
struct
[[
maybe_unused
]]
sys_stats
{
int64_t
rss
;
int64_t
vmsize
;
double
cpu_time
;
};
}
// namespace
#ifdef CAF_MACOS
# include <mach/mach.h>
# include <mach/task.h>
...
...
@@ -31,31 +41,33 @@
# define HAS_PROCESS_METRICS
namespace
{
std
::
pair
<
int64_t
,
int64_t
>
get_mem_usage
()
{
mach_task_basic_info
info
;
mach_msg_type_number_t
count
=
MACH_TASK_BASIC_INFO_COUNT
;
if
(
task_info
(
mach_task_self
(),
MACH_TASK_BASIC_INFO
,
(
task_info_t
)
&
info
,
&
count
)
!=
KERN_SUCCESS
)
{
return
{
0
,
0
};
sys_stats
read_sys_stats
()
{
sys_stats
result
{
0
,
0
,
0
};
// Fetch memory usage.
{
mach_task_basic_info
info
;
mach_msg_type_number_t
count
=
MACH_TASK_BASIC_INFO_COUNT
;
if
(
task_info
(
mach_task_self
(),
MACH_TASK_BASIC_INFO
,
(
task_info_t
)
&
info
,
&
count
)
==
KERN_SUCCESS
)
{
result
.
rss
=
info
.
resident_size
;
result
.
vmsize
=
info
.
virtual_size
;
}
}
// Fetch CPU time.
{
task_thread_times_info
info
;
mach_msg_type_number_t
count
=
TASK_THREAD_TIMES_INFO_COUNT
;
if
(
task_info
(
mach_task_self
(),
TASK_THREAD_TIMES_INFO
,
(
task_info_t
)
&
info
,
&
count
)
==
KERN_SUCCESS
)
{
// Round to milliseconds.
result
.
cpu_time
+=
info
.
user_time
.
seconds
;
result
.
cpu_time
+=
ceil
(
info
.
user_time
.
microseconds
/
1000.0
)
/
1000.0
;
result
.
cpu_time
+=
info
.
system_time
.
seconds
;
result
.
cpu_time
+=
ceil
(
info
.
system_time
.
microseconds
/
1000.0
)
/
1000.0
;
}
}
return
{
static_cast
<
int64_t
>
(
info
.
resident_size
),
static_cast
<
int64_t
>
(
info
.
virtual_size
)};
}
double
get_cpu_time
()
{
task_thread_times_info
info
;
mach_msg_type_number_t
count
=
TASK_THREAD_TIMES_INFO_COUNT
;
if
(
task_info
(
mach_task_self
(),
TASK_THREAD_TIMES_INFO
,
(
task_info_t
)
&
info
,
&
count
)
!=
KERN_SUCCESS
)
return
0
;
// Round to milliseconds.
double
result
=
0
;
result
+=
info
.
user_time
.
seconds
;
result
+=
ceil
(
info
.
user_time
.
microseconds
/
1000.0
)
/
1000.0
;
result
+=
info
.
system_time
.
seconds
;
result
+=
ceil
(
info
.
system_time
.
microseconds
/
1000.0
)
/
1000.0
;
return
result
;
}
...
...
@@ -63,17 +75,93 @@ double get_cpu_time() {
#endif // CAF_MACOS
#ifdef CAF_LINUX
# include <sys/resource.h>
# include <cstdio>
# include <unistd.h>
# define HAS_PROCESS_METRICS
std
::
pair
<
int64_t
,
int64_t
>
get_mem_usage
()
{
return
{
0
,
0
};
namespace
{
std
::
atomic
<
long
>
global_ticks_per_second
;
std
::
atomic
<
long
>
global_page_size
;
bool
load_system_setting
(
std
::
atomic
<
long
>&
cache_var
,
long
&
var
,
int
name
,
[[
maybe_unused
]]
const
char
*
pretty_name
)
{
var
=
cache_var
.
load
();
switch
(
var
)
{
case
-
1
:
return
false
;
case
0
:
var
=
sysconf
(
name
);
if
(
var
<=
0
)
{
CAF_LOG_ERROR
(
"failed to read"
<<
pretty_name
<<
"from sysconf"
);
var
=
-
1
;
cache_var
=
var
;
return
false
;
}
cache_var
=
var
;
return
true
;
default:
return
true
;
}
}
int64_t
get_cpu_time
()
{
rusage
usage
;
if
(
getrusage
(
RUSAGE_SELF
,
&
usage
)
!=
0
)
return
0
;
return
static_cast
<
int64_t
>
(
usage
.
ru_utime
.
tv_sec
+
usage
.
ru_stime
.
tv_sec
);
# define TRY_LOAD(varname, confname) \
load_system_setting(global_##varname, varname, confname, #confname)
sys_stats
read_sys_stats
()
{
sys_stats
result
{
0
,
0
,
0
};
long
ticks_per_second
=
0
;
long
page_size
=
0
;
if
(
!
TRY_LOAD
(
ticks_per_second
,
_SC_CLK_TCK
)
||
!
TRY_LOAD
(
page_size
,
_SC_PAGE_SIZE
))
return
result
;
if
(
auto
f
=
fopen
(
"/proc/self/stat"
,
"r"
))
{
long
unsigned
utime_ticks
=
0
;
long
unsigned
stime_ticks
=
0
;
long
unsigned
vmsize_bytes
=
0
;
long
rss_pages
=
0
;
auto
rd
=
fscanf
(
f
,
"%*d "
// 1. PID
"%*s "
// 2. Executable
"%*c "
// 3. State
"%*d "
// 4. Parent PID
"%*d "
// 5. Process group ID
"%*d "
// 6. Session ID
"%*d "
// 7. Controlling terminal
"%*d "
// 8. Foreground process group ID
"%*u "
// 9. Flags
"%*u "
// 10. Number of minor faults
"%*u "
// 11. Number of minor faults of waited-for children
"%*u "
// 12. Number of major faults
"%*u "
// 13. Number of major faults of waited-for children
"%lu "
// 14. CPU user time in ticks
"%lu "
// 15. CPU kernel time in ticks
"%*d "
// 16. CPU user time of waited-for children
"%*d "
// 17. CPU kernel time of waited-for children
"%*d "
// 18. Priority
"%*d "
// 19. Nice value
"%*d "
// 20. Num threads
"%*d "
// 21. Obsolete since 2.6
"%*u "
// 22. Time the process started after system boot
"%lu "
// 23. Virtual memory size in bytes
"%ld"
,
// 24. Resident set size in pages
&
utime_ticks
,
&
stime_ticks
,
&
vmsize_bytes
,
&
rss_pages
);
fclose
(
f
);
if
(
rd
!=
4
)
{
CAF_LOG_ERROR
(
"failed to read content of /proc/self/stat"
);
global_ticks_per_second
=
-
1
;
global_page_size
=
-
1
;
return
result
;
}
result
.
rss
=
static_cast
<
int64_t
>
(
rss_pages
)
*
page_size
;
result
.
vmsize
=
static_cast
<
int64_t
>
(
vmsize_bytes
);
result
.
cpu_time
=
utime_ticks
;
result
.
cpu_time
+=
stime_ticks
;
result
.
cpu_time
/=
ticks_per_second
;
}
return
result
;
}
}
// namespace
#endif // CAF_LINUX
namespace
caf
::
detail
{
...
...
@@ -193,10 +281,10 @@ void prometheus_broker::scrape() {
if
(
last_scrape_
>=
now
)
return
;
last_scrape_
=
now
;
cpu_time_
->
value
(
get_cpu_time
()
);
auto
[
res
,
virt
]
=
get_mem_usage
(
);
mem_size_
->
value
(
res
);
virt_mem_size_
->
value
(
virt
);
auto
[
rss
,
vmsize
,
cpu_time
]
=
read_sys_stats
(
);
mem_size_
->
value
(
rss
);
virt_mem_size_
->
value
(
vmsize
);
cpu_time_
->
value
(
cpu_time
);
#endif // HAS_PROCESS_METRICS
}
...
...
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