clearer names for actions, and infer actions better
[monitor.git] / commands / comonquery.py
1 #!/usr/bin/python
2
3
4 import sys
5 from monitor import database
6 from monitor.common import *
7 from monitor.model import Record
8 import glob
9 import os
10 import traceback
11
12 import time
13 import re
14 import string
15
16 from monitor.wrapper import plc
17 api = plc.getAuthAPI()
18
19 from monitor.util import file
20 from monitor import config
21
22 from monitor.sources import comon
23
24 default_fields="name,resptime,sshstatus,date,uptime,lastcotop,cpuspeed,memsize,disksize"
25
26 class NoKeyException(Exception): pass
27
28 def daysdown_print_nodeinfo(co_nodeinfo, hostname):
29         co_nodeinfo['hostname'] = hostname
30         co_nodeinfo['daysdown'] = Record.getStrDaysDown(co_nodeinfo)
31         co_nodeinfo['intdaysdown'] = Record.getDaysDown(co_nodeinfo)
32
33         print "%(intdaysdown)5s %(hostname)-44s | %(state)10.10s | %(daysdown)s" % co_nodeinfo
34
35 def co_print_nodeinfo(co_nodeinfo, hostname, fields=None):
36         
37         co_nodeinfo['name'] = hostname
38
39         if 'uptime' in co_nodeinfo and co_nodeinfo['uptime'] != "null":
40                 co_nodeinfo['uptime'] = diff_time(time.time()-float(co_nodeinfo['uptime']))
41
42         if 'date' in co_nodeinfo and co_nodeinfo['date'] != "null":
43                 co_nodeinfo['date'] = diff_time(float(co_nodeinfo['date']))
44
45         if fields == default_fields.split(','):
46
47                 print "%(name)-40s %(sshstatus)5.5s %(resptime)6.6s %(lastcotop)6.6s %(uptime)s" % co_nodeinfo
48         else:
49                 format = ""
50                 for f in fields:
51                         format += "%%(%s)s," % f
52                 print format % co_nodeinfo
53
54 def main():
55
56         from monitor import parser as parsermodule
57         parser = parsermodule.getParser()
58
59         parser.set_defaults(node=None, 
60                                 select=None, 
61                                 list=None, 
62                                 dns=False,
63                                 listkeys=False,
64                                 pcuselect=None, 
65                                 cache=False,
66                                 nodelist=None, 
67                                 daysdown=None, 
68                                 fields=default_fields)
69         parser.add_option("", "--daysdown", dest="daysdown", action="store_true",
70                                                 help="List the node state and days down...")
71
72         parser.add_option("", "--select", dest="select", metavar="key=value", 
73                                                 help="List all nodes with the given key=value pattern")
74         parser.add_option("", "--fields", dest="fields", metavar="key,list,...", 
75                                                 help="a list of keys to display for each entry.")
76         parser.add_option("", "--list", dest="list", action="store_true", 
77                                                 help="Write only the hostnames as output.")
78         parser.add_option("", "--nodelist", dest="nodelist", metavar="nodelist.txt", 
79                                                 help="A list of nodes to bring out of debug mode.")
80         parser.add_option("", "--listkeys", dest="listkeys", action="store_true",
81                                                 help="A list of nodes to bring out of debug mode.")
82         parser.add_option("", "--cache", dest="cache", action="store_true",
83                                                 help="Specify whether the command should perform a live query or save/use a cached values.")
84
85         parser.add_option("", "--dns", dest="dns", action="store_true",
86                                                 help="A convenience query for dns values")
87
88         parser = parsermodule.getParser(['defaults'], parser)
89         config = parsermodule.parse_args(parser)
90         
91         # lastcotop measures whether cotop is actually running.  this is a better
92         # metric than sshstatus, or other values from CoMon
93
94         COMON_COTOPURL= "http://comon.cs.princeton.edu/status/tabulator.cgi?" + \
95                                         "table=table_nodeview&formatcsv"
96         if config.dns:
97                 config.fields = "name,dns1udp,dns1tcp,dns2udp,dns2tcp"
98                 config.select = "dns1udp>0||dns1tcp>0||dns2udp>0||dns2tcp>0"
99
100         if config.fields == "all":
101                 cotop_url = COMON_COTOPURL
102         else:
103                 cotop_url = COMON_COTOPURL + "&dumpcols='%s'" % config.fields
104
105         if config.select:
106                 cotop_url = cotop_url + "&select='%s'" % config.select
107
108         if config.listkeys:
109                 cotop_url = COMON_COTOPURL + "&limit=1"
110
111         cotop = comon.Comon()
112         if database.cachedRecently(cotop_url):
113                 print >>sys.stderr, "loading cached query :%s" % cotop_url
114                 cohash = database.dbLoad(cotop_url)
115         else:
116                 cohash = cotop.coget(cotop_url)
117                 if config.cache:
118                         print >>sys.stderr, "saving query :%s" % cotop_url
119                         database.dbDump(cotop_url, cohash)
120
121         if config.nodelist:
122                 nodelist = file.getListFromFile(config.nodelist)
123         else:
124                 # NOTE: list of nodes should come from comon query.   
125                 nodelist = cohash.keys()
126
127         fields = config.fields.split(",")
128         f_info = {}
129         for f in fields: f_info[f]=f 
130         co_print_nodeinfo(f_info, "hostname", fields)
131
132         for node in nodelist:
133                 config.node = node
134
135                 if node not in cohash: continue
136
137                 co_nodeinfo = cohash[node]
138
139                 if config.listkeys:
140                         print >>sys.stderr, "Primary keys available in the comon object:"
141                         for key in co_nodeinfo.keys():
142                                 print "\t",key
143                         sys.exit(0)
144                         
145                 if config.list:
146                         print node
147                 else:
148                         if config.daysdown:
149                                 daysdown_print_nodeinfo(co_nodeinfo, node)
150                         else:
151                                 fields = config.fields.split(",")
152                                 co_print_nodeinfo(co_nodeinfo, node, fields)
153                 
154 if __name__ == "__main__":
155         main()