monasca-agent/monagent/collector/checks_d/directory.py

84 lines
3.3 KiB
Python

from fnmatch import fnmatch
from os import stat
from os import walk
from os.path import abspath
from os.path import exists
from os.path import join
import time
from monagent.collector.checks import AgentCheck
class DirectoryCheck(AgentCheck):
"""This check is for monitoring and reporting metrics on the files for a provided directory
WARNING: the user/group that dd-agent runs as must have access to stat the files in the desired directory
Config options:
"directory" - string, the directory to gather stats for. required
"name" - string, the name to use when tagging the metrics. defaults to the "directory"
"pattern" - string, the `fnmatch` pattern to use when reading the "directory"'s files. default "*"
"recursive" - boolean, when true the stats will recurse into directories. default False
"""
def check(self, instance):
if "directory" not in instance:
raise Exception('DirectoryCheck: missing "directory" in config')
directory = instance["directory"]
abs_directory = abspath(directory)
name = instance.get("name") or directory
pattern = instance.get("pattern") or "*"
recursive = instance.get("recursive") or False
if not exists(abs_directory):
raise Exception("DirectoryCheck: the directory (%s) does not exist" % abs_directory)
self._get_stats(abs_directory, name, pattern, recursive)
def _get_stats(self, directory, name, pattern, recursive):
dimensions = {"name": name}
directory_bytes = 0
directory_files = 0
for root, dirs, files in walk(directory):
for filename in files:
filename = join(root, filename)
# check if it passes our filter
if not fnmatch(filename, pattern):
continue
try:
file_stat = stat(filename)
except OSError as ose:
self.warning("DirectoryCheck: could not stat file %s - %s" % (filename, ose))
else:
directory_files += 1
directory_bytes += file_stat.st_size
# file specific metrics
self.histogram(
"system.disk.directory.file.bytes",
file_stat.st_size,
dimensions=dimensions)
self.histogram(
"system.disk.directory.file.modified_sec_ago",
time.time() -
file_stat.st_mtime,
dimensions=dimensions)
self.histogram(
"system.disk.directory.file.created_sec_ago",
time.time() -
file_stat.st_ctime,
dimensions=dimensions)
# os.walk gives us all sub-directories and their files
# if we do not want to do this recursively and just want
# the top level directory we gave it, then break
if not recursive:
break
# number of files
self.gauge("system.disk.directory.files", directory_files, dimensions=dimensions)
# total file size
self.gauge("system.disk.directory.bytes", directory_bytes, dimensions=dimensions)