Skip to content
Snippets Groups Projects

UFCG plugin for Monasca

The snippet can be accessed without any authentication.
Authored by Kaio Oliveira
Edited
ufcg.py 4.22 KiB
# Copyright 2017 Distributed Systems Laboratory (LSD) - UFCG
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import logging
import re
import subprocess

import monasca_agent.collector.checks as checks
from monasca_agent.common.psutil_wrapper import psutil


log = logging.getLogger(__name__)


class UFCG(checks.AgentCheck):

    def __init__(self, name, init_config, agent_config):
        super(UFCG, self).__init__(name, init_config, agent_config)
        # 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
        # which you are supposed to ignore.
        psutil.cpu_percent(interval=None, percpu=False)
        psutil.cpu_times_percent(interval=None, percpu=False)

    def check(self, instance):
        """Capture cpu stats
        """
        dimensions = self._set_dimensions(None, instance)

        cpu_perc = psutil.cpu_percent(interval=None, percpu=False)
        cpu_dec = cpu_perc / 100
        clock = self._get_cpu_freqs()

        meta = {'cpu_freq_current': clock['current'],
                'cpu_freq_min': clock['min'],
                'cpu_freq_max': clock['max'],
                }
        power = self._get_IPMI_power()

        energy_yield = clock['current'] / power
        used_capacity = clock['current'] * cpu_dec
        effective_energy = used_capacity / energy_yield
        efficiency = effective_energy / power

        inlet = self._get_IPMI_temp_inlet()

        self.gauge('ufcg.cpu_dec', cpu_dec, dimensions)
        self.gauge('ufcg.power', power, dimensions)
        self.gauge('ufcg.clock', clock['current'], dimensions, value_meta=meta)

        self.gauge('ufcg.energy_yield', energy_yield, dimensions)
        self.gauge('ufcg.used_capacity', used_capacity, dimensions)
        self.gauge('ufcg.effective_energy', effective_energy, dimensions)
        self.gauge('ufcg.efficiency', efficiency, dimensions)

        self.gauge('ufcg.inlet_temperature', inlet, dimensions)

    def _get_cpu_freqs(self):
        try:
            lscpu_command = subprocess.Popen('lscpu', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            lscpu_output = lscpu_command.communicate()[0].decode(
                encoding='UTF-8')
            cpu_freq_output = re.search("(CPU MHz:.*?(\d+\.\d+)\n)", lscpu_output)
            cpu_freq_output_min = re.search("(CPU MHz:.*?(\d+\.\d+)\n)", lscpu_output)
            cpu_freq_output_max = re.search("(CPU MHz:.*?(\d+\.\d+)\n)", lscpu_output)
            cpu_freq = float(cpu_freq_output.group(2))
            cpu_freq_min = float(cpu_freq_output_min.group(2))
            cpu_freq_max = float(cpu_freq_output_max.group(2))
            return {'current': cpu_freq,
                    'min': cpu_freq_min,
                    'max': cpu_freq_max}
        except Exception:
            log.exception('Cannot extract CPU MHz information using lscpu')

    def _get_IPMI_power(self):
        ipmi_output = subprocess.check_output("ipmitool sdr | grep 'Power Meter'", shell=True)
        metric = ipmi_output.split("|")
        value = metric[1].split(" ")[1]
        if (value.isdigit() or self.isFloat(value)) and float(value) > 0.0:
            if "Watts" in metric[1]:
                power = int(value)
        return power

    def _get_IPMI_temp_inlet(self):
        temperature = 0

        ipmi_output = subprocess.check_output("ipmitool sdr | grep '01-Inlet Ambient'", shell=True)
        metric = ipmi_output.split("|")
        value = metric[1].split()[0]
        if value.isdigit() and float(value) > 0.0:
            temperature = int(value)

        return temperature
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment