Commit 12eccd0d authored by Tristan Cavelier's avatar Tristan Cavelier

monitor2: add rss feed

parent 865a6f41
...@@ -106,7 +106,7 @@ recipe = slapos.recipe.template:jinja2 ...@@ -106,7 +106,7 @@ recipe = slapos.recipe.template:jinja2
filename = template-monitor.cfg filename = template-monitor.cfg
template = ${:_profile_base_location_}/instance-monitor.cfg.jinja2.in template = ${:_profile_base_location_}/instance-monitor.cfg.jinja2.in
rendered = ${buildout:directory}/template-monitor.cfg rendered = ${buildout:directory}/template-monitor.cfg
md5sum = c3438660ae33d0049fceaf45ddb781bf md5sum = e6244ecdae7fa8f5b5b6b7f94d30be8b
context = context =
key apache_location apache:location key apache_location apache:location
key gzip_location gzip:location key gzip_location gzip:location
...@@ -133,6 +133,7 @@ context = ...@@ -133,6 +133,7 @@ context =
raw python_executable ${buildout:executable} raw python_executable ${buildout:executable}
raw promise_executor_py ${run-promise-py:location}/${run-promise-py:filename} raw promise_executor_py ${run-promise-py:location}/${run-promise-py:filename}
raw template_wrapper ${template-wrapper:output} raw template_wrapper ${template-wrapper:output}
raw status2rss_executable_path ${status2rss-executable:location}/${status2rss-executable:filename}
[monitor-httpd-conf] [monitor-httpd-conf]
<= monitor-download-base <= monitor-download-base
...@@ -219,14 +220,10 @@ filename = monitor-password.py.cgi ...@@ -219,14 +220,10 @@ filename = monitor-password.py.cgi
filename = monitor-password-interface.html filename = monitor-password-interface.html
md5sum = 04b664dfb47bfd3d01502768311aa239 md5sum = 04b664dfb47bfd3d01502768311aa239
[rss-bin] [status2rss-executable]
recipe = hexagonit.recipe.download <= monitor-download-base
url = ${:_profile_base_location_}/${:filename}
download-only = true
md5sum = 6c84a826778cb059754623f39b33651b
destination = ${buildout:parts-directory}/monitor-template-rss-bin
filename = status2rss.py filename = status2rss.py
mode = 0644 md5sum = 65315ded80cd72f54f6e12d06ce813c4
[dcron-service] [dcron-service]
recipe = slapos.recipe.template recipe = slapos.recipe.template
......
...@@ -69,6 +69,7 @@ promise-wrapper = ${directory:var}/monitor-promise-wrapper ...@@ -69,6 +69,7 @@ promise-wrapper = ${directory:var}/monitor-promise-wrapper
monitor-var = ${directory:var}/monitor monitor-var = ${directory:var}/monitor
monitor-password-var = ${monitor-directory:monitor-var}/password monitor-password-var = ${monitor-directory:monitor-var}/password
monitor-password-interface = ${monitor-directory:monitor-password-var}/password/interface monitor-password-interface = ${monitor-directory:monitor-password-var}/password/interface
monitor-status2rss-var = ${monitor-directory:monitor-var}/status2rss
[logrotate-directory] [logrotate-directory]
recipe = slapos.cookbook:mkdirectory recipe = slapos.cookbook:mkdirectory
...@@ -182,6 +183,18 @@ context = ...@@ -182,6 +183,18 @@ context =
key content :command key content :command
command = kill -USR1 $(cat ${monitor-httpd-conf-parameter:pid-file}) command = kill -USR1 $(cat ${monitor-httpd-conf-parameter:pid-file})
[monitor-status2rss-wrapper]
recipe = slapos.cookbook:wrapper
command-line = {{ python_executable }} {{ status2rss_executable_path }} '${monitor-instance-parameter:monitor-title}' '${monitor-httpd-conf-parameter:url}feed' ${monitor-directory:public} ${monitor-directory:monitor-status2rss-var}/previous_status ${monitor-directory:web-dir}/feed
wrapper-path = ${directory:bin}/monitor-status2rss.py
[monitor-status2rss-cron-entry]
recipe = slapos.cookbook:cron.d
cron-entries = ${cron:cron-entries}
name = monitor-status2rss
frequency = * * * * *
command = ${monitor-status2rss-wrapper:wrapper-path}
[monitor-web-default-promise-interface] [monitor-web-default-promise-interface]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
template = {{ monitor_web_default_promise_interface }} template = {{ monitor_web_default_promise_interface }}
...@@ -342,4 +355,5 @@ parts = ...@@ -342,4 +355,5 @@ parts =
monitor-password-promise-conf monitor-password-promise-conf
monitor-password-cgi monitor-password-cgi
monitor-password-promise-interface monitor-password-promise-interface
monitor-status2rss-cron-entry
publish publish
import datetime
import PyRSS2Gen
import sys import sys
import sqlite3 import os
import time import json
import datetime
import base64 import base64
import hashlib
# Based on http://thehelpfulhacker.net/2011/03/27/a-rss-feed-for-your-crontabs/ def main():
_, title, link, public_folder, previous_status_path, output_path = sys.argv
# ### Defaults final_status = "OK";
TITLE = sys.argv[1] # getting status
LINK = sys.argv[2] for filename in os.listdir(public_folder):
db_path = sys.argv[3] if filename.endswith(".status.json"):
DESCRIPTION = TITLE filepath = os.path.join(public_folder, filename)
SUCCESS = "SUCCESS" status = None
FAILURE = "FAILURE" try:
status = json.load(open(filepath, "r"))
items = [] except ValueError:
status = "" continue
try:
current_timestamp = int(time.time()) if status["status"] != "OK":
# We only build the RSS for the last ten days final_status = "BAD"
period = 3600 * 24 * 10 break
db = sqlite3.connect(db_path) except KeyError:
rows = db.execute("select timestamp, status from status where timestamp>? order by timestamp", (current_timestamp - period,)) final_status = "BAD"
for row in rows: break
line_timestamp, line_status = row # checking previous status
line_status = line_status.encode() try:
status = open(previous_status_path, "r").readline(4)
if status == final_status:
return 0
except IOError:
pass
# update status
open(previous_status_path, "w").write(final_status)
# generating RSS
utcnow = datetime.datetime.utcnow()
open(output_path, "w").write(
newRssString(
title,
title,
link,
utcnow,
utcnow,
"60",
[
newRssItemString(
"Status is %s" % final_status,
"Status is %s" % final_status,
link,
newGuid("%s, %s" % (utcnow, final_status)),
utcnow,
)
],
)
)
if line_status == status:
continue
status = line_status def escapeHtml(string):
return string.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace("\"", "&quot;")
event_time = datetime.datetime.fromtimestamp(line_timestamp).strftime('%Y-%m-%d %H:%M:%S') def newGuid(string):
sha256 = hashlib.sha256()
sha256.update(string)
return sha256.hexdigest()
individual_rows = db.execute("select status, element, output from individual_status where timestamp=?", (line_timestamp,)) def newRssItemString(title, description, link, guid, pub_date, guid_is_perma_link=True):
description = '\n'.join(['%s: %s %s' % row for row in individual_rows]) return """<item>
<title>%(title)s</title>
<description>%(description)s</description>
<link>%(link)s</link>
<guid isPermaLink="%(guid_is_perma_link)s">%(guid)s</guid>
<pubDate>%(pub_date)s</pubDate>
</item>""" % {
"title": escapeHtml(title),
"description": escapeHtml(description),
"link": escapeHtml(link),
"guid": escapeHtml(guid),
"pub_date": escapeHtml(pub_date.strftime("%a, %d %b %Y %H:%M:%S +0000")),
"guid_is_perma_link": escapeHtml(repr(guid_is_perma_link).lower()),
}
rss_item = PyRSS2Gen.RSSItem( def newRssString(title, description, link, last_build_date, pub_date, ttl, rss_item_string_list):
title = status, return """<?xml version="1.0" encoding="UTF-8" ?>
description = "%s: %s\n%s" % (event_time, status, description), <rss version="2.0">
link = LINK, <channel>
pubDate = event_time, <title>%(title)s</title>
guid = PyRSS2Gen.Guid(base64.b64encode("%s, %s" % (event_time, status))) <description>%(description)s</description>
) <link>%(link)s</link>
items.append(rss_item) <lastBuildDate>%(last_build_date)s</lastBuildDate>
<pubDate>%(pub_date)s</pubDate>
### Build the rss feed <ttl>%(ttl)s</ttl>
items.reverse() %(items)s
rss_feed = PyRSS2Gen.RSS2 ( </channel>
title = TITLE, </rss>
link = LINK, """ % {
description = DESCRIPTION, "title": escapeHtml(title),
lastBuildDate = datetime.datetime.utcnow(), "description": escapeHtml(description),
items = items "link": escapeHtml(link),
) "last_build_date": escapeHtml(last_build_date.strftime("%a, %d %b %Y %H:%M:%S +0000")),
"pub_date": escapeHtml(pub_date.strftime("%a, %d %b %Y %H:%M:%S +0000")),
"ttl": escapeHtml(str(ttl)),
"items": "\n\n".join([" " + item.replace("\n", "\n ") for item in rss_item_string_list]),
}
print rss_feed.to_xml() if __name__ == "__main__":
exit(main())
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