Commit 16b33bfe authored by Alain Takoudjou's avatar Alain Takoudjou

monitor: add support for report script folder

parent 0f3ae9fb
......@@ -99,7 +99,7 @@ recipe = slapos.recipe.template:jinja2
filename = template-monitor.cfg
template = ${:_profile_base_location_}/instance-monitor.cfg.jinja2.in
rendered = ${buildout:directory}/template-monitor.cfg
md5sum = cd7f386fe1b5066d8508758249b408d3
md5sum = b6da7709da533c5c8280e5e103809c58
context =
key apache_location apache:location
key gzip_location gzip:location
......@@ -130,13 +130,13 @@ depends =
[monitor2-bin]
<= monitor-template-script
filename = monitor.py
md5sum = 31beec15d3c3cd7979d04ecb834c439a
md5sum = 6db3d9fcfff32c556f2bedee804ffb47
[run-promise-py]
recipe = slapos.recipe.template:jinja2
template = ${:_profile_base_location_}/scripts/run-promise.py
rendered = ${buildout:parts-directory}/monitor-scripts/run-promise.py
md5sum = 8ba8b661c55f2c5a379e9e42573be486
md5sum = 5694920c5789f4d953cb5d41adfa7f8b
mode = 0755
context =
raw python ${buildout:directory}/bin/${extra-eggs:interpreter}
......
......@@ -70,7 +70,7 @@ etc = ${directory:etc}
run = ${directory:monitor}/run
#run = ${directory:scripts}
promises = ${directory:monitor-promise}
report = ${directory:monitor-report}
reports = ${directory:monitor-report}
pids = ${directory:run}/monitor
cgi-bin = ${directory:monitor}/cgi-bin
webdav = ${directory:monitor}/webdav
......@@ -134,6 +134,7 @@ root-title = ${monitor-instance-parameter:root-instance-title}
public-folder = ${monitor-directory:public}
private-folder = ${monitor-directory:private}
webdav-folder = ${monitor-directory:webdav}
report-folder = ${monitor-directory:reports}
web-folder = ${monitor-directory:web-dir}
base-url = ${monitor-instance-parameter:monitor-base-url}
monitor-hal-json = ${monitor-directory:public}/monitor.hal.json
......
......@@ -94,6 +94,7 @@ class Monitoring(object):
self.collector_db = config.get("monitor", "collector-db")
self.collect_script = config.get("monitor", "collect-script")
self.webdav_folder = config.get("monitor", "webdav-folder")
self.report_script_folder = config.get("monitor", "report-folder")
self.webdav_url = '%s/share' % config.get("monitor", "base-url")
self.public_url = '%s/public' % config.get("monitor", "base-url")
self.status_history_folder = os.path.join(self.public_folder, 'history')
......@@ -106,6 +107,7 @@ class Monitoring(object):
self.parameter_cfg_file = config.get("monitor", "parameter-file-path").strip()
self.config_folder = os.path.join(self.private_folder, 'config')
self.report_folder = os.path.join(self.private_folder, 'report')
self.promise_dict = {}
for promise_folder in self.promise_folder_list:
......@@ -267,9 +269,11 @@ class Monitoring(object):
raise
self.data_folder = os.path.join(self.private_folder, 'data', '.jio_documents')
self.report_folder = os.path.join(self.report_folder, '.jio_documents')
config_folder = os.path.join(self.config_folder, '.jio_documents')
mkdirAll(self.data_folder)
mkdirAll(config_folder)
mkdirAll(self.report_folder)
try:
os.symlink(os.path.join(self.private_folder, 'data'),
os.path.join(jio_private, 'data'))
......@@ -281,6 +285,11 @@ class Monitoring(object):
except OSError, e:
if e.errno != os.errno.EEXIST:
raise
try:
os.symlink(self.report_folder, os.path.join(jio_private, 'report'))
except OSError, e:
if e.errno != os.errno.EEXIST:
raise
def makeConfigurationFiles(self):
config_folder = os.path.join(self.config_folder, '.jio_documents')
......@@ -385,6 +394,53 @@ class Monitoring(object):
with open(self.monitor_hal_json, "w") as fp:
json.dump(self.monitor_dict, fp)
def generateReportCronEntries(self):
cron_line_list = []
# We should add the possibility to modify this parameter later from monitor interface
report_frequency = "*/30 * * * *"
report_name_list = [name.replace('.report.json', '')
for name in os.listdir(self.report_folder) if name.endswith('.report.json')]
for filename in os.listdir(self.report_script_folder):
report_script = os.path.join(self.report_script_folder, filename)
if os.path.isfile(report_script) and os.access(report_script, os.X_OK):
report_name = os.path.splitext(filename)[0]
report_json_path = "%s.report.json" % report_name
report_cmd_line = [
report_frequency,
self.promise_runner,
'--pid_path "%s"' % os.path.join(self.service_pid_folder,
"%s.pid" % filename),
'--output "%s"' % os.path.join(self.report_folder,report_json_path),
'--promise_script "%s"' % report_script,
'--promise_name "%s"' % report_name,
'--monitor_url "%s/jio_private/"' % self.webdav_url, # XXX hardcoded,
'--history_folder "%s"' % self.report_folder,
'--instance_name "%s"' % self.title,
'--hosting_name "%s"' % self.root_title,
'--promise_type "report"']
cron_line_list.append(' '.join(report_cmd_line))
if report_name in report_name_list:
report_name_list.pop(report_name_list.index(report_name))
# cleanup removed report json result
if report_name_list != []:
for report_name in report_name_list:
result_path = os.path.join(self.public_folder, '%s.report.json' % report_name)
if os.path.exists(result_path):
try:
os.unlink(result_path)
except OSError, e:
print "Error: Failed to delete %s" % result_path, str(e)
pass
with open(self.crond_folder + "/monitor-reports", "w") as freport:
freport.write("\n".join(cron_line_list))
def generateServiceCronEntries(self):
# XXX only if at least one configuration file is modified, then write in the cron
#cron_line_list = ['PATH=%s\n' % os.environ['PATH']]
......@@ -401,13 +457,13 @@ class Monitoring(object):
promise_cmd_line = [
softConfigGet(service_config, "service", "frequency") or "* * * * *",
self.promise_runner,
'--pid_path %s' % os.path.join(self.service_pid_folder,
'--pid_path "%s"' % os.path.join(self.service_pid_folder,
"%s.pid" % service_name),
'--output %s' % service_status_path,
'--promise_script %s' % promise["path"],
'--output "%s"' % service_status_path,
'--promise_script "%s"' % promise["path"],
'--promise_name "%s"' % service_name,
'--monitor_url "%s/jio_private/"' % self.webdav_url, # XXX hardcoded,
'--history_folder %s' % self.status_history_folder,
'--history_folder "%s"' % self.status_history_folder,
'--instance_name "%s"' % self.title,
'--hosting_name "%s"' % self.root_title]
......@@ -442,6 +498,13 @@ class Monitoring(object):
cronf.write(entry_line)
def bootstrapMonitor(self):
# create symlinks from monitor.conf
self.createSymlinksFromConfig(self.public_folder, self.public_path_list)
self.createSymlinksFromConfig(self.private_folder, self.private_path_list)
self.configureFolders()
# create symlinks from service configurations
self.promise_items = self.promise_dict.items()
for service_name, promise in self.promise_items:
......@@ -457,12 +520,6 @@ class Monitoring(object):
private_path_list.split(),
service_name)
# create symlinks from monitor.conf
self.createSymlinksFromConfig(self.public_folder, self.public_path_list)
self.createSymlinksFromConfig(self.private_folder, self.private_path_list)
self.configureFolders()
# generate monitor.json
self.monitor_dict = {}
self.generateMonitorHalJson()
......@@ -474,6 +531,9 @@ class Monitoring(object):
# put promises to a cron file
self.generateServiceCronEntries()
# put report script to cron
self.generateReportCronEntries()
# Generate parameters files and scripts
self.makeConfigurationFiles()
......
......@@ -24,15 +24,18 @@ def parseArguments():
help='Promise script to execute.')
parser.add_argument('--promise_name',
help='Title to give to this promise.')
parser.add_argument('--promise_type',
default='status',
help='Type of promise to execute. [status, report].')
parser.add_argument('--monitor_url',
help='Monitor Instance website URL.')
parser.add_argument('--history_folder',
help='Path where old result file will be placed before generate a new json result file.')
parser.add_argument('--instance_name',
default='UNKNOW Software Instance',
default='UNKNOWN Software Instance',
help='Software Instance name.')
parser.add_argument('--hosting_name',
default='UNKNOW Hosting Subscription',
default='UNKNOWN Hosting Subscription',
help='Hosting Subscription name.')
return parser.parse_args()
......@@ -74,14 +77,16 @@ def main():
updateStatusHistoryFolder(
parser.promise_name,
parser.output,
parser.history_folder
parser.history_folder,
parser.promise_type
)
with open(parser.output, "w") as outputfile:
json.dump(status_json, outputfile)
os.remove(parser.pid_path)
def updateStatusHistoryFolder(name, status_file, history_folder):
def updateStatusHistoryFolder(name, status_file, history_folder, promise_type):
old_history_list = []
keep_item_amount = 25
history_path = os.path.join(history_folder, name, '.jio_documents')
if not os.path.exists(status_file):
return
......@@ -96,18 +101,19 @@ def updateStatusHistoryFolder(name, status_file, history_folder):
else: raise
with open(status_file, 'r') as sf:
status_dict = json.loads(sf.read())
filename = '%s.status.json' % (
status_dict['start-date'].replace(' ', '_').replace(':', ''))
filename = '%s.%s.json' % (
status_dict['start-date'].replace(' ', '_').replace(':', ''),
promise_type)
copyfile(status_file, os.path.join(history_path, filename))
# Don't let history foler grow too much, keep 40 files
# Don't let history foler grow too much, keep xx files
file_list = filter(os.path.isfile,
glob.glob("%s/*.status.json" % history_path)
glob.glob("%s/*.%s.json" % (history_path, promise_type))
)
file_count = len(file_list)
if file_count > 40:
if file_count > keep_item_amount:
file_list.sort(key=lambda x: os.path.getmtime(x))
while file_count > 40:
while file_count > keep_item_amount:
to_delete = file_list.pop(0)
try:
os.unlink(to_delete)
......
......@@ -63,7 +63,7 @@ mode = 0644
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-pull-backup.cfg.in
output = ${buildout:directory}/instance-pull-backup.cfg
md5sum = 028dfc01dfb0d738e1b4793f67b24e8c
md5sum = cb7acac7ab41bf44c20d6d03bfad8217
mode = 0644
[template-replicated]
......
......@@ -11,6 +11,7 @@ parts =
## Monitor for pbs
monitor-base
monitor-check-resilient-feed-file
extends = ${monitor2-template:rendered}
......@@ -266,7 +267,7 @@ private-path-list +=
[monitor-check-resilient-feed-file]
recipe = slapos.recipe.template:jinja2
template = ${template-monitor-check-resilient-feed:location}/${template-monitor-check-resilient-feed:filename}
rendered = $${monitor-directory:promises}/check-create-resilient-feed-files
rendered = $${monitor-directory:reports}/check-create-resilient-feed-files
mode = 700
context =
key input_feed_directory directory:notifier-feeds
......
Markdown is supported
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