Skip to content

Commit

Permalink
Merge pull request #2202 from gphat/add-some-new-system-metrics
Browse files Browse the repository at this point in the history
Add "more unix" plugin with some linux metrics.
  • Loading branch information
Remi Hakim committed Jan 14, 2016
2 parents 9ad9662 + 70535e5 commit 4454b24
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
70 changes: 70 additions & 0 deletions checks.d/linux_proc_extras.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# project
from checks import AgentCheck
from utils.subprocess_output import get_subprocess_output
from collections import defaultdict

PROCESS_STATES = {
'D': 'uninterruptible',
'R': 'runnable',
'S': 'sleeping',
'T': 'stopped',
'W': 'paging',
'X': 'dead',
'Z': 'zombie',
}

PROCESS_PRIOS = {
'<': 'high',
'N': 'low',
'L': 'locked'
}

class MoreUnixCheck(AgentCheck):
def check(self, instance):
tags = instance.get('tags', [])

state_counts = defaultdict(int)

prio_counts = defaultdict(int)

with open('/proc/sys/fs/inode-nr', 'r') as inode_info:
inode_stats = inode_info.readline().split()
self.gauge('system.inodes.total', float(inode_stats[0]), tags=tags)
self.gauge('system.inodes.used', float(inode_stats[1]), tags=tags)

with open('/proc/stat', 'r') as stat_info:
lines = [line.strip() for line in stat_info.readlines()]

for line in lines:
if line.startswith('ctxt'):
ctxt_count = float(line.split(' ')[1])
self.monotonic_count('system.linux.context_switches', ctxt_count, tags=tags)
elif line.startswith('processes'):
process_count = int(line.split(' ')[1])
self.monotonic_count('system.linux.processes_created', process_count, tags=tags)
elif line.startswith('intr'):
interrupts = int(line.split(' ')[1])
self.monotonic_count('system.linux.interrupts', interrupts, tags=tags)

with open('/proc/sys/kernel/random/entropy_avail') as entropy_info:
entropy = entropy_info.readline()
self.gauge('system.entropy.available', float(entropy), tags=tags)

ps = get_subprocess_output(['ps', '--no-header', '-eo', 'stat'], self.log)
for state in ps[0]:
# Each process state is a flag in a list of characters. See ps(1) for details.
for flag in list(state):
if state in PROCESS_STATES:
state_counts[PROCESS_STATES[state]] += 1
elif state in PROCESS_PRIOS:
prio_counts[PROCESS_PRIOS[state]] += 1

for state in state_counts:
state_tags = list(tags)
state_tags.append("state:" + state)
self.gauge('system.processes.states', float(state_counts[state]), state_tags)

for prio in prio_counts:
prio_tags = list(tags)
prio_tags.append("priority:" + prio)
self.gauge('system.processes.priorities', float(prio_counts[prio]), prio_tags)
5 changes: 5 additions & 0 deletions conf.d/linux_proc_extras.yaml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# There's no configuration necessary for this check.
init_config:

instances:
- tags: []
40 changes: 40 additions & 0 deletions tests/checks/integration/test_linux_proc_extras.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# 3p
from nose.plugins.attrib import attr

# project
from tests.checks.common import AgentCheckTest

@attr('linux')
@attr(requires='linux')
class TestCheckLinuxProcExtras(AgentCheckTest):
CHECK_NAME = 'linux_proc_extras'

INODE_GAUGES = [
'system.inodes.total',
'system.inodes.used'
]

PROC_COUNTS = [
'system.linux.context_switches',
'system.linux.processes_created',
'system.linux.interrupts'
]

ENTROPY_GAUGES = [
'system.entropy.available'
]

PROCESS_STATS_GAUGES = [
'system.processes.states',
'system.processes.priorities'
]

# Really a basic check to see if all metrics are there
def test_check(self):
self.run_check({'instances': []})

# Assert metrics
for metric in self.PROC_COUNTS + self.INODE_GAUGES + self.ENTROPY_GAUGES + self.PROCESS_STATS_GAUGES:
self.assertMetric(metric, tags=[])

self.coverage_report()

0 comments on commit 4454b24

Please sign in to comment.