From: Stephen Soltesz Date: Tue, 2 Dec 2008 19:31:20 +0000 (+0000) Subject: basic display of nodes, pcus, and sites. X-Git-Tag: Monitor-2.0-0~24 X-Git-Url: http://git.onelab.eu/?p=monitor.git;a=commitdiff_plain;h=d8616c5bab940943ef8a17db7937a5eb733dd526 basic display of nodes, pcus, and sites. updates to various files needed to enable this. --- diff --git a/monitor/database/info/history.py b/monitor/database/info/history.py index c871c78..dc53860 100644 --- a/monitor/database/info/history.py +++ b/monitor/database/info/history.py @@ -40,8 +40,14 @@ class HistorySiteRecord(Entity): nodes_total = Field(Int,default=0) nodes_up = Field(Int,default=0) + slices_total = Field(Int,default=0) slices_used = Field(Int,default=0) + # all nodes offline and never-contact. + new = Field(Boolean,default=False) + + enabled = Field(Boolean,default=False) + status = Field(String,default="unknown") @classmethod diff --git a/monitor/util/__init__.py b/monitor/util/__init__.py index f204047..8986f7f 100644 --- a/monitor/util/__init__.py +++ b/monitor/util/__init__.py @@ -1 +1,34 @@ __all__=["writepid","removepid","daemonize"] + +import time +import math + +def diff_time(timestamp, abstime=True): + now = time.time() + if timestamp == None: + return "unknown" + if abstime: + diff = now - timestamp + else: + diff = timestamp + # return the number of seconds as a difference from current time. + t_str = "" + if diff < 60: # sec in min. + t = diff / 1 + t_str = "%s sec ago" % int(math.ceil(t)) + elif diff < 60*60: # sec in hour + t = diff / (60) + t_str = "%s min ago" % int(math.ceil(t)) + elif diff < 60*60*24: # sec in day + t = diff / (60*60) + t_str = "%s hrs ago" % int(math.ceil(t)) + elif diff < 60*60*24*14: # sec in week + t = diff / (60*60*24) + t_str = "%s days ago" % int(math.ceil(t)) + elif diff <= 60*60*24*30: # approx sec in month + t = diff / (60*60*24*7) + t_str = "%s wks ago" % int(math.ceil(t)) + elif diff > 60*60*24*30: # approx sec in month + t = diff / (60*60*24*30) + t_str = "%s mnths ago" % int(t) + return t_str diff --git a/monitor/wrapper/plccache.py b/monitor/wrapper/plccache.py index 978e6bb..d4cfbbc 100755 --- a/monitor/wrapper/plccache.py +++ b/monitor/wrapper/plccache.py @@ -87,7 +87,7 @@ def init(): api = plc.getCachedAuthAPI() l_sites = api.GetSites({'peer_id':None}, ['login_base', 'site_id', 'abbreviated_name', 'latitude', - 'longitude', 'max_slices', 'slice_ids', 'node_ids' ]) + 'longitude', 'max_slices', 'slice_ids', 'node_ids', 'enabled' ]) l_nodes = api.GetNodes({'peer_id':None}, ['hostname', 'node_id', 'ports', 'site_id', 'version', 'last_updated', 'date_created', 'last_contact', 'pcu_ids', 'nodenetwork_ids']) diff --git a/sitebad.py b/sitebad.py index 12ae8c8..781cab6 100755 --- a/sitebad.py +++ b/sitebad.py @@ -10,7 +10,7 @@ from monitor import database from pcucontrol import reboot from monitor import parser as parsermodule from monitor import config -from monitor.database import HistorySiteRecord, FindbadNodeRecord +from monitor.database.info.model import HistorySiteRecord, FindbadNodeRecord, session from monitor.wrapper import plc, plccache from monitor.const import MINUP @@ -32,6 +32,19 @@ def main(config): checkAndRecordState(l_sites, l_plcsites) +def getnewsite(nodelist): + new = True + for node in nodelist: + try: + noderec = FindbadNodeRecord.query.filter(FindbadNodeRecord.hostname==node['hostname']).order_by(FindbadNodeRecord.date_checked.desc()).first() + if noderec is not None and \ + noderec.plc_node_stats['last_contact'] != None: + new = False + except: + import traceback + print traceback.print_exc() + return new + def getnodesup(nodelist): up = 0 for node in nodelist: @@ -62,9 +75,12 @@ def checkAndRecordState(l_sites, l_plcsites): pf = HistorySiteRecord.findby_or_create(loginbase=sitename) pf.last_checked = datetime.now() + pf.slices_total = d_site['max_slices'] pf.slices_used = len(d_site['slice_ids']) pf.nodes_total = len(lb2hn[sitename]) pf.nodes_up = getnodesup(lb2hn[sitename]) + pf.new = getnewsite(lb2hn[sitename]) + pf.enabled = d_site['enabled'] if pf.nodes_up >= MINUP: if pf.status != "good": pf.last_changed = datetime.now() @@ -76,7 +92,10 @@ def checkAndRecordState(l_sites, l_plcsites): count += 1 print "%d %15s slices(%2s) nodes(%2s) up(%2s) %s" % (count, sitename, pf.slices_used, pf.nodes_total, pf.nodes_up, pf.status) + pf.flush() + print HistorySiteRecord.query.count() + session.flush() return True diff --git a/web/MonitorWeb/dev.cfg b/web/MonitorWeb/dev.cfg index f1e675b..d5915c7 100644 --- a/web/MonitorWeb/dev.cfg +++ b/web/MonitorWeb/dev.cfg @@ -30,12 +30,12 @@ server.environment="development" autoreload.package="monitorweb" -server.socket_host="127.0.0.1" +server.socket_host="monitor.planet-lab.org" server.socket_port=8080 -server.webpath="/monitor/" -base_url_filter.on = False -base_url_filter.base_url = "http://127.0.0.1:8080/monitor" -base_url_filter.use_x_forwarded_host = True +#server.webpath="/monitor/" +#base_url_filter.on = False +#base_url_filter.base_url = "http://127.0.0.1:8080/monitor" +#base_url_filter.use_x_forwarded_host = True # Auto-Reload after code modification # autoreload.on = True diff --git a/web/MonitorWeb/monitorweb/controllers.py b/web/MonitorWeb/monitorweb/controllers.py index d2978da..d4553dc 100644 --- a/web/MonitorWeb/monitorweb/controllers.py +++ b/web/MonitorWeb/monitorweb/controllers.py @@ -51,14 +51,18 @@ class Root(controllers.RootController): node.pcu_status = pcu.reboot_trial_status else: node.pcu_status = "nodata" + node.pcu_short_status = format_pcu_shortstatus(pcu) + else: node.pcu_status = "nopcu" + node.pcu_short_status = "none" if node.kernel_version: node.kernel = node.kernel_version.split()[2] else: node.kernel = "" + # NOTE: count filters if node.observed_status != 'DOWN': filtercount[node.observed_status] += 1 @@ -102,7 +106,6 @@ class Root(controllers.RootController): else: filtercount['pending'] += 1 - print reboot.pcu_name(node.plc_pcu_stats) node.ports = format_ports(node) node.status = format_pcu_shortstatus(node) @@ -123,10 +126,32 @@ class Root(controllers.RootController): return dict(query=query, fc=filtercount) - @expose(template="monitorweb.templates.pculist") + @expose(template="monitorweb.templates.sitelist") def site(self, filter='all'): - filtercount = {'ok' : 0, 'NetDown': 0, 'Not_Run' : 0, 'pending' : 0, 'all' : 0} - return dict(query=[], fc=filtercount) + filtercount = {'good' : 0, 'down': 0, 'new' : 0, 'pending' : 0, 'all' : 0} + fbquery = HistorySiteRecord.query.all() + query = [] + for site in fbquery: + # count filter + filtercount['all'] += 1 + if site.new and site.slices_used == 0 and not site.enabled: + filtercount['new'] += 1 + elif not site.enabled: + filtercount['pending'] += 1 + else: + filtercount[site.status] += 1 + + # apply filter + if filter == "all": + query.append(site) + elif filter == 'new' and site.new and site.slices_used == 0 and not site.enabled: + query.append(site) + elif filter == "pending" and not site.enabled: + query.append(site) + elif filter == site.status: + query.append(site) + + return dict(query=query, fc=filtercount) @expose(template="monitorweb.templates.pculist") def action(self, filter='all'): diff --git a/web/MonitorWeb/monitorweb/model.py b/web/MonitorWeb/monitorweb/model.py index b570416..f3fda87 100644 --- a/web/MonitorWeb/monitorweb/model.py +++ b/web/MonitorWeb/monitorweb/model.py @@ -11,6 +11,7 @@ from elixir import String, Unicode, Integer, DateTime options_defaults['autosetup'] = False +from monitor.database.info.model import * # your data model diff --git a/web/MonitorWeb/monitorweb/static/css/style.css b/web/MonitorWeb/monitorweb/static/css/style.css index 59053a2..072c484 100644 --- a/web/MonitorWeb/monitorweb/static/css/style.css +++ b/web/MonitorWeb/monitorweb/static/css/style.css @@ -10,18 +10,20 @@ html, body { padding: 0; } -td, th {padding:2px;border:none;} +td, th {padding:1px;border:none;} tr th {text-align:left;background-color:#f0f0f0;color:#333;} tr.odd td {background-color:#edf3fe;} tr.even td {background-color:#fff;} #header { - height: 80px; - width: 777px; - background: blue URL('../images/header_inner.png') no-repeat; + height: 40px; + width: 780px; + /*background: blue URL('../images/header_inner.png') no-repeat;*/ border-left: 1px solid #aaa; border-right: 1px solid #aaa; margin: 0 auto 0 auto; + text-align: center; + font-size: 180%; } a.link, a, a.active { @@ -42,7 +44,16 @@ a.link, a, a.active { #status-Not_Run { background-color: lightgrey; } #status-ok { background-color: darkseagreen; } #status-0 { background-color: darkseagreen; } -#status-error { background-color: indianred; width="200px"; } +#status-error { background-color: indianred; } +#status-none { background-color: white; } + +#site-good { background-color : darkseagreen; } +#site-down { background-color: indianred; } + +/*#nps-table { background-color: lightgrey; }*/ +/*#sub-table { background-color: lightgrey; }*/ +/* td, th {padding:2px;border:none;} */ +/* tr th {text-align:left;background-color:#f0f0f0;color:#333;} */ #main_content { color: black; @@ -112,7 +123,7 @@ h2 { padding: 10px; font-size: 80%; text-align: center; - width: 757px; + width: 765px; margin: 0 auto 1em auto; } diff --git a/web/MonitorWeb/monitorweb/templates/nodelist.kid b/web/MonitorWeb/monitorweb/templates/nodelist.kid index dc3bf92..5e5dec1 100644 --- a/web/MonitorWeb/monitorweb/templates/nodelist.kid +++ b/web/MonitorWeb/monitorweb/templates/nodelist.kid @@ -1,6 +1,8 @@ @@ -20,12 +22,12 @@ layout_params['page_title'] = "Monitor Node View" - +
- + @@ -36,11 +38,11 @@ layout_params['page_title'] = "Monitor Node View" - - + + - +
Hostname pingssh pcu status kernel
diff --git a/web/MonitorWeb/monitorweb/templates/pculist.kid b/web/MonitorWeb/monitorweb/templates/pculist.kid index fc1b835..1ca6e36 100644 --- a/web/MonitorWeb/monitorweb/templates/pculist.kid +++ b/web/MonitorWeb/monitorweb/templates/pculist.kid @@ -15,7 +15,7 @@ def pcu_link(pcu): xmlns:py="http://purl.org/kid/ns#">
- +
@@ -28,7 +28,7 @@ def pcu_link(pcu):
Ok(${fc['ok']})
- +
@@ -52,7 +52,7 @@ def pcu_link(pcu): 80 - + diff --git a/web/MonitorWeb/monitorweb/templates/sitemenu.kid b/web/MonitorWeb/monitorweb/templates/sitemenu.kid index 23e9d41..d46e500 100644 --- a/web/MonitorWeb/monitorweb/templates/sitemenu.kid +++ b/web/MonitorWeb/monitorweb/templates/sitemenu.kid @@ -6,11 +6,11 @@ -

Monitor : ${page_title}

-
Site
+ +
- +
@@ -32,6 +32,6 @@
Nodes
- + diff --git a/web/MonitorWeb/prod.cfg b/web/MonitorWeb/prod.cfg new file mode 100644 index 0000000..f1e675b --- /dev/null +++ b/web/MonitorWeb/prod.cfg @@ -0,0 +1,76 @@ +[global] +# This is where all of your settings go for your development environment +# Settings that are the same for both development and production +# (such as template engine, encodings, etc.) all go in +# monitorweb/config/app.cfg + +# DATABASE + +# driver://username:password@host:port/database + +# pick the form for your database +# sqlalchemy.dburi="postgres://username@hostname/databasename" +# sqlalchemy.dburi="mysql://username:password@hostname:port/databasename" +# sqlalchemy.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite" + +# If you have sqlite, here's a simple default to get you started +# in development +sqlalchemy.dburi="sqlite:///devdata.sqlite" + + +# SERVER + +# Some server parameters that you may want to tweak +# server.socket_port=8080 + +# Enable the debug output at the end on pages. +# log_debug_info_filter.on = False + +server.environment="development" +autoreload.package="monitorweb" + + +server.socket_host="127.0.0.1" +server.socket_port=8080 +server.webpath="/monitor/" +base_url_filter.on = False +base_url_filter.base_url = "http://127.0.0.1:8080/monitor" +base_url_filter.use_x_forwarded_host = True + +# Auto-Reload after code modification +# autoreload.on = True + +# Set to True if you'd like to abort execution if a controller gets an +# unexpected parameter. False by default +tg.strict_parameters = True + +# LOGGING +# Logging configuration generally follows the style of the standard +# Python logging module configuration. Note that when specifying +# log format messages, you need to use *() for formatting variables. +# Deployment independent log configuration is in monitorweb/config/log.cfg +[logging] + +[[loggers]] +[[[monitorweb]]] +level='DEBUG' +qualname='monitorweb' +handlers=['debug_out'] + +[[[allinfo]]] +level='INFO' +handlers=['debug_out'] + +[[[access]]] +level='INFO' +qualname='turbogears.access' +handlers=['access_out'] +propagate=0 + + +[[[database]]] +# Set to INFO to make SQLAlchemy display SQL commands +level='ERROR' +qualname='sqlalchemy.engine' +handlers=['debug_out'] +propagate=0