Enable the system metrics in Docker environment

Story: 2003093
Task: 23185
Change-Id: I9700a6fcb650fbcf983f2a4f145b430876f12429
This commit is contained in:
Lukasz Zajaczkowski 2018-07-25 11:37:14 +02:00
parent 7b150fa352
commit f23ceda96b
9 changed files with 142 additions and 53 deletions

View File

@ -1,7 +1,11 @@
# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP
init_config:
# process_fs_path: (optional) STRING. It will set up the path of the process
# filesystem. By default it's set for: /proc directory.
# Example:
#
# process_fs_path: /rootfs/proc
instances:
# Cpu check only supports one configured instance
- name: cpu_stats

View File

@ -1,7 +1,11 @@
# (C) Copyright 2015,2016 Hewlett Packard Enterprise Development Company LP
init_config:
# process_fs_path: (optional) STRING. It will set up the path of the process
# filesystem. By default it's set for: /proc directory.
# Example:
#
# process_fs_path: /rootfs/proc
instances:
# Disk check only supports one configured instance
- name: disk_stats

View File

@ -1,7 +1,11 @@
# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP
init_config:
# process_fs_path: (optional) STRING. It will set up the path of the process
# filesystem. By default it's set for: /proc directory.
# Example:
#
# process_fs_path: /rootfs/proc
instances:
# Load check only supports one configured instance
- name: load_stats

View File

@ -1,7 +1,11 @@
# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP
init_config:
# process_fs_path: (optional) STRING. It will set up the path of the process
# filesystem. By default it's set for: /proc directory.
# Example:
#
# process_fs_path: /rootfs/proc
instances:
# Memory check only supports one configured instance
- name: memory_stats

View File

@ -370,6 +370,54 @@ This section documents all the checks that are supplied by the Agent.
## System Metrics
This section documents the system metrics that are sent by the Agent.
Docker environment:
For Docker environment you can enable the system plugins by adding cpu, disk,
memory and load yaml files to the monasca-agent-collector container (mount
plugin files to /plugins.d/cpu|disk|memory|load.yaml). Additionally you have to
specify the path of the host process filesystem. In this case mount host root
directory `/` to `/rootfs` in the container. Docker compose example:
```
volumes:
- "/:/rootfs:ro"
```
Sample configurations:
cpu.yaml
```
init_config:
process_fs_path: /rootfs/proc
instances:
- name: cpu_stats
```
disk.yaml
```
init_config:
process_fs_path: /rootfs/proc
instances:
- name: disk_stats
ignore_filesystem_types: iso9660,tmpfs,nsfs
```
memory.yaml
```
init_config:
process_fs_path: /rootfs/proc
instances:
- name: memory_stats
```
load.yaml
```
init_config:
process_fs_path: /rootfs/proc
instances:
- name: load_stats
```
### CPU
| Metric Name | Dimensions | Semantics |
| ----------- | ---------- | --------- |

View File

@ -26,6 +26,12 @@ class Cpu(checks.AgentCheck):
def __init__(self, name, init_config, agent_config):
super(Cpu, self).__init__(name, init_config, agent_config)
process_fs_path_config = init_config.get('process_fs_path', None)
if process_fs_path_config:
psutil.PROCFS_PATH = process_fs_path_config
self.log.debug('The path of the process filesystem set to %s', process_fs_path_config)
else:
self.log.debug('The process_fs_path not set. Use default path: /proc')
# psutil.cpu_percent and psutil.cpu_times_percent are called in
# __init__ because the first time these two functions are called with
# interval = 0.0 or None, it will return a meaningless 0.0 value

View File

@ -27,6 +27,12 @@ class Disk(checks.AgentCheck):
self._partition_error = set()
super(Disk, self).__init__(name, init_config, agent_config)
process_fs_path_config = init_config.get('process_fs_path', None)
if process_fs_path_config:
psutil.PROCFS_PATH = process_fs_path_config
self.log.debug('The path of the process filesystem set to %s', process_fs_path_config)
else:
self.log.debug('The process_fs_path not set. Use default path: /proc')
def _log_once_per_day(self, message):
if message in self._partition_error:
@ -65,60 +71,60 @@ class Disk(checks.AgentCheck):
if partition.fstype not in fs_types_to_ignore \
and (not device_blacklist_re
or not device_blacklist_re.match(partition.device)):
try:
device_name = self._get_device_name(partition.device)
disk_usage = psutil.disk_usage(partition.mountpoint)
total_capacity += disk_usage.total
total_used += disk_usage.used
st = os.statvfs(partition.mountpoint)
except Exception as ex:
exception_name = ex.__class__.__name__
self._log_once_per_day('Unable to access partition {} '
'with error: {}'.format(partition,
exception_name))
continue
try:
device_name = self._get_device_name(partition.device)
disk_usage = psutil.disk_usage(partition.mountpoint)
total_capacity += disk_usage.total
total_used += disk_usage.used
st = os.statvfs(partition.mountpoint)
except Exception as ex:
exception_name = ex.__class__.__name__
self._log_once_per_day('Unable to access partition {} '
'with error: {}'.format(partition,
exception_name))
continue
if use_mount:
dimensions.update({'mount_point': partition.mountpoint})
self.gauge("disk.space_used_perc",
disk_usage.percent,
if use_mount:
dimensions.update({'mount_point': partition.mountpoint})
self.gauge("disk.space_used_perc",
disk_usage.percent,
device_name=device_name,
dimensions=dimensions)
disk_count += 1
if st.f_files > 0:
self.gauge("disk.inode_used_perc",
round((float(st.f_files - st.f_ffree) / st.f_files) * 100, 2),
device_name=device_name,
dimensions=dimensions)
disk_count += 1
if st.f_files > 0:
self.gauge("disk.inode_used_perc",
round((float(st.f_files - st.f_ffree) / st.f_files) * 100, 2),
device_name=device_name,
dimensions=dimensions)
disk_count += 1
log.debug('Collected {0} disk usage metrics for partition {1}'.format(
disk_count,
partition.mountpoint))
disk_count = 0
if send_io_stats:
try:
stats = disk_stats[device_name]
self.rate("io.read_req_sec", round(float(stats.read_count), 2),
device_name=device_name, dimensions=dimensions)
self.rate("io.write_req_sec", round(float(stats.write_count), 2),
device_name=device_name, dimensions=dimensions)
self.rate("io.read_kbytes_sec",
round(float(stats.read_bytes / 1024), 2),
device_name=device_name, dimensions=dimensions)
self.rate("io.write_kbytes_sec",
round(float(stats.write_bytes / 1024), 2),
device_name=device_name, dimensions=dimensions)
self.rate("io.read_time_sec", round(float(stats.read_time / 1000), 2),
device_name=device_name, dimensions=dimensions)
self.rate("io.write_time_sec", round(float(stats.write_time / 1000), 2),
device_name=device_name, dimensions=dimensions)
log.debug('Collected {0} disk usage metrics for partition {1}'.format(
disk_count,
partition.mountpoint))
disk_count = 0
if send_io_stats:
try:
stats = disk_stats[device_name]
self.rate("io.read_req_sec", round(float(stats.read_count), 2),
device_name=device_name, dimensions=dimensions)
self.rate("io.write_req_sec", round(float(stats.write_count), 2),
device_name=device_name, dimensions=dimensions)
self.rate("io.read_kbytes_sec",
round(float(stats.read_bytes / 1024), 2),
device_name=device_name, dimensions=dimensions)
self.rate("io.write_kbytes_sec",
round(float(stats.write_bytes / 1024), 2),
device_name=device_name, dimensions=dimensions)
self.rate("io.read_time_sec", round(float(stats.read_time / 1000), 2),
device_name=device_name, dimensions=dimensions)
self.rate("io.write_time_sec", round(float(stats.write_time / 1000), 2),
device_name=device_name, dimensions=dimensions)
log.debug('Collected 6 disk I/O metrics for'
'partition {0}'.format(partition.mountpoint))
except KeyError:
log.debug('No Disk I/O metrics available for'
' {0}...Skipping'.format(device_name))
log.debug('Collected 6 disk I/O metrics for'
'partition {0}'.format(partition.mountpoint))
except KeyError:
log.debug('No Disk I/O metrics available for'
' {0}...Skipping'.format(device_name))
if send_rollup_stats:
self.gauge("disk.total_space_mb",

View File

@ -28,6 +28,7 @@ class Load(checks.AgentCheck):
def __init__(self, name, init_config, agent_config):
super(Load, self).__init__(name, init_config, agent_config)
self.process_fs_path_config = init_config.get('process_fs_path', None)
def check(self, instance):
"""Capture load stats
@ -38,7 +39,13 @@ class Load(checks.AgentCheck):
if util.Platform.is_linux():
try:
loadAvrgProc = open('/proc/loadavg', 'r')
if self.process_fs_path_config:
log.debug(
'The path of the process filesystem set to %s',
self.process_fs_path_config)
loadAvrgProc = open(self.process_fs_path_config + '/loadavg', 'r')
else:
loadAvrgProc = open('/proc/loadavg', 'r')
uptime = loadAvrgProc.readlines()
loadAvrgProc.close()
except Exception:

View File

@ -23,6 +23,12 @@ class Memory(checks.AgentCheck):
def __init__(self, name, init_config, agent_config):
super(Memory, self).__init__(name, init_config, agent_config)
process_fs_path_config = init_config.get('process_fs_path', None)
if process_fs_path_config:
psutil.PROCFS_PATH = process_fs_path_config
self.log.debug('The path of the process filesystem set to %s', process_fs_path_config)
else:
self.log.debug('The process_fs_path not set. Use default path: /proc')
def check(self, instance):
"""Capture memory stats