4eeba985163d8d512ef8f60ce3151e09ddc6262c
[kiosk.git] / health_renderer.py
1 import constants
2 import file_writer
3 import os
4 import renderer
5 import time
6
7 class periodic_health_renderer(renderer.debuggable_abstaining_renderer):
8     def __init__(self, name_to_timeout_dict):
9         super(periodic_health_renderer, self).__init__(name_to_timeout_dict, False)
10
11     def debug_prefix(self):
12         return "health"
13
14     def periodic_render(self, key):
15         f = file_writer.file_writer('periodic-health_6_300.html')
16         timestamps = '/timestamps/'
17         days = constants.seconds_per_day
18         hours = constants.seconds_per_hour
19         mins = constants.seconds_per_minute
20         limits = {
21             timestamps + 'last_rsnapshot_hourly'          : hours * 24,
22             timestamps + 'last_rsnapshot_daily'           : days * 3,
23             timestamps + 'last_rsnapshot_weekly'          : days * 14,
24             timestamps + 'last_rsnapshot_monthly'         : days * 70,
25
26             timestamps + 'last_zfssnapshot_hourly'        : hours * 5,
27             timestamps + 'last_zfssnapshot_daily'         : hours * 36,
28             timestamps + 'last_zfssnapshot_weekly'        : days * 9,
29             timestamps + 'last_zfssnapshot_monthly'       : days * 70,
30             timestamps + 'last_zfssnapshot_cleanup'       : hours * 24,
31
32             timestamps + 'last_disk_selftest_short'       : days * 14,
33             timestamps + 'last_disk_selftest_long'        : days * 31,
34             timestamps + 'last_zfs_scrub'                 : days * 9,
35             timestamps + 'last_zfs_scrub_backup'          : days * 9,
36
37             timestamps + 'last_zfsxfer_backup.house'      : hours * 36,
38             timestamps + 'last_zfsxfer_ski.dyn.guru.org'  : days * 7,
39             timestamps + 'last_photos_sync'               : hours * 8,
40             timestamps + 'last_disk_selftest_backup_short': days * 14,
41             timestamps + 'last_disk_selftest_backup_long' : days * 31,
42
43             timestamps + 'last_healthy_wifi'              : mins * 10,
44             timestamps + 'last_healthy_network'           : mins * 10,
45             timestamps + 'last_scott_sync'                : days * 2,
46         }
47         self.write_header(f)
48
49         now = time.time()
50         n = 0
51         for x in sorted(limits):
52             ts = os.stat(x).st_mtime
53             age = now - ts
54             self.debug_print("%s -- age is %ds, limit is %ds" % (x, age, limits[x]))
55             if age < limits[x]:
56                 f.write('<TD BGCOLOR="#007010" HEIGHT=100 WIDTH=33% STYLE="text-size:60%; vertical-align: middle;">\n')
57             else:
58                 f.write('<TD BGCOLOR="#990000" HEIGHT=100 WIDTH=33% CLASS="invalid" STYLE="text-size:60%; vertical-align:middle;">\n')
59             f.write("  <CENTER><FONT SIZE=-2>\n")
60
61             name = x.replace(timestamps, "")
62             name = name.replace("last_", "")
63             name = name.replace("_", "&nbsp;")
64             days = divmod(age, constants.seconds_per_day)
65             hours = divmod(days[1], constants.seconds_per_hour)
66             minutes = divmod(hours[1], constants.seconds_per_minute)
67
68             self.debug_print("%s is %d days %02d:%02d old." % (
69                 name, days[0], hours[0], minutes[0]))
70             f.write("%s<BR>\n<B>%d</b> days <B>%02d</B>:<B>%02d</B> old.\n" % (
71                 name, days[0], hours[0], minutes[0]))
72             f.write("</FONT></CENTER>\n</TD>\n\n")
73             n += 1
74             if n % 3 == 0:
75                 f.write("</TR>\n<TR>\n<!-- ------------------- -->\n")
76         self.write_footer(f)
77         f.close()
78         return True
79
80     def write_header(self, f):
81         f.write("""
82 <HTML>
83 <HEAD>
84 <STYLE>
85 @-webkit-keyframes invalid {
86   from { background-color: #ff6400; }
87   to { background-color: #ff0000; }
88   padding-right: 25px;
89   padding-left: 25px;
90 }
91 @-moz-keyframes invalid {
92   from { background-color: #ff6400; }
93   to { background-color: #ff0000; }
94   padding-right: 25px;
95   padding-left: 25px;
96 }
97 @-o-keyframes invalid {
98   from { background-color: #ff6400; }
99   to { background-color: #ff0000; }
100   padding-right: 25px;
101   padding-left: 25px;
102 }
103 @keyframes invalid {
104   from { background-color: #ff6400; }
105   to { background-color: #ff0000; }
106   padding-right: 25px;
107   padding-left: 25px;
108 }
109 .invalid {
110   -webkit-animation: invalid 1s infinite; /* Safari 4+ */
111   -moz-animation:    invalid 1s infinite; /* Fx 5+ */
112   -o-animation:      invalid 1s infinite; /* Opera 12+ */
113   animation:         invalid 1s infinite; /* IE 10+ */
114 }
115 </STYLE>
116 <meta http-equiv="cache-control" content="max-age=0" />
117 <meta http-equiv="cache-control" content="no-cache" />
118 <meta http-equiv="expires" content="0" />
119 <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
120 <meta http-equiv="pragma" content="no-cache" />
121 </HEAD>
122 <BODY>
123 <H1>Periodic Cronjob Health Report</H1>
124 <HR>
125 <CENTER>
126 <TABLE BORDER=0 WIDTH=99% style="font-size:16pt">
127 <TR>
128 """)
129
130     def write_footer(self, f):
131         f.write("""
132 </TR>
133 </TABLE>
134 </BODY>
135 </HTML>""")
136
137 test = periodic_health_renderer({"Test", 123})
138 test.periodic_render("Test")