3.1.16
[infrastructure.git] / nagios / plugin / comon_sensor.py
1 #!/usr/bin/env python
2 import re
3 import nagios
4 import socket
5 import signal
6 import string
7
8 import sys
9
10 # default port number
11 PORT=3121
12 # default timeout
13 TIMEOUT=10
14
15 # exception raised when timeout occurs
16 TimeoutException = "Timeout"
17
18 #################### comon-based acquisition
19 def check (hostname, timeout=None):
20
21 #    print "Entering comon_sensor::check",hostname
22
23     if (timeout == None):
24         timeout=TIMEOUT
25
26     try:
27         # connect to comon and read data
28         page = read_data (hostname,timeout)
29         # parse lines and store in dict
30         dict = parse_data (page)
31         # keep only relevant stuff and refine parsing
32         dict = filter (dict)
33         # make decision
34         return interpret (dict)
35
36     except TimeoutException:
37         print "While connecting to comon sensor : timeout expired %d s"%timeout
38         ### XXX - in some cases this is a KO, but in general
39         # maybe comon does not run on these nodes
40         return nagios.UNKNOWN
41
42 ### implement timeout as an alarm signal
43 def alarm_handler(s,closure):
44     if s == signal.SIGALRM:
45         raise TimeoutException
46     else:
47         print "unexpected signal s in alarm_handler"
48
49 ###
50 # returns a list of lines
51 # dont use httplib nor urllib2
52 # the server side replies its data even before you send a GET request
53 # with urllib2 you basically get a 'Connection reset by peer' error
54 def read_data (hostname,timeout,port=None):
55
56     if (port ==None):
57         port=PORT
58
59     signal.signal(signal.SIGALRM,alarm_handler)
60     signal.alarm(timeout)
61     s =socket.socket(socket.AF_INET, socket.SOCK_STREAM)
62     s.connect((hostname,port))
63     signal.alarm(0)
64     
65     lines=[]
66     line=""
67     while 1:
68         char=s.recv(1)
69         if not char:
70             break
71         elif char == '\n':
72             lines += [line]
73             line=""
74         else:
75             line+=char
76     return lines
77
78 ### pattern for interpreting sensor output
79 re_line="^([a-zA-Z0-9_]+): (.*)$"
80 ma_line=re.compile(re_line)
81
82 def parse_data (page):
83     dict={}
84     for line in page:
85         matched=ma_line.match(line)
86         if matched:
87             key,val=matched.groups()
88             dict[key]=val
89     return dict
90         
91 FIELDS_FOCUS = {
92     'Loads':'floats',
93     'VMStat':'ints',
94     'CPUUse':'ints',
95     'MemInfo':'floats',
96     'Date':'floats',
97     'DfDot':'percent-floats',
98     'LastSsh':'ints',
99     }
100
101
102 def filter (dict):
103
104     filtered = {}
105     for key in dict.keys():
106         if key in FIELDS_FOCUS.keys():
107             format=FIELDS_FOCUS[key]
108             value=dict[key].rstrip()
109             if format == 'ints':
110                 filtered[key]=map(int,value.split(' '))
111             elif format == 'floats':
112                 filtered[key]=map(float,value.split(' '))
113             elif format == 'percent-floats':
114                 fields=value.split()
115                 pval=string.replace(fields[0],'%','')
116                 filtered[key]=map(float,[pval]+fields[1:])
117             # simpler access to single-fields
118             value = filtered[key]
119             if len(value)==1:
120                 filtered[key]=value[0]
121     return filtered
122
123 def interpret (dict):
124
125     status = nagios.OK
126
127     ### check ssh status
128     ssh_delay = dict['Date']- dict['LastSsh']
129     print ssh_delay
130
131     ### 
132     return status
133
134 ###
135 def usage():
136     print "Usage comon_sensor.py node timeout"
137     sys.exit(1)
138
139 if __name__=='__main__':
140     if len(sys.argv) != 3:
141         usage()
142     check(sys.argv[1],int(sys.argv[2]))