70 lines
3.0 KiB
Python
70 lines
3.0 KiB
Python
from fnmatch import fnmatch
|
|
from os import stat, walk
|
|
from os.path import abspath, exists, 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, 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)
|