archApp: archiver appliance monitoring

This commit is contained in:
Michael Davidsaver
2014-12-09 11:50:23 -05:00
parent 46bc99a57d
commit 0d8690d5b7
3 changed files with 283 additions and 0 deletions

13
archApp/Makefile Normal file
View File

@ -0,0 +1,13 @@
TOP=..
include $(TOP)/configure/CONFIG
include $(TOP)/configure/CONFIG_PY
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
PY += bplreport.py
DB += applmetrics.db
include $(TOP)/configure/RULES
include $(TOP)/configure/RULES_PY
#----------------------------------------
# ADD RULES AFTER THIS LINE

119
archApp/applmetrics.db Normal file
View File

@ -0,0 +1,119 @@
record(ai, "$(P)Rate:Store-I") {
field(DTYP, "Python Device")
field(INP , "@bplreport fetch_float metrics.0.dataRateGBPerDay")
field(SCAN, "I/O Intr")
field(PREC, "2")
field(EGU , "GB/day")
field(TSE , "-2")
field(HOPR, "50")
field(LOPR, "0")
field(HIHI, "15")
field(HIGH, "11")
field(LOW , "9")
field(LOLO, "0.1")
field(HHSV, "MAJOR")
field(HSV , "MINOR")
field(LSV , "MINOR")
field(LLSV, "INVALID")
info("autosaveFields_pass0", "HOPR LOPR HIHI HIGH LOW LOLO")
}
record(ai, "$(P)Rate:Event-I") {
field(DTYP, "Python Device")
field(INP , "@bplreport fetch_float metrics.0.eventRate")
field(SCAN, "I/O Intr")
field(PREC, "2")
field(EGU , "evt/s")
field(TSE , "-2")
field(HOPR, "50000")
field(LOPR, "0")
field(HIHI, "10000")
field(HIGH, "7000")
field(LOW , "5000")
field(LOLO, "1")
field(HHSV, "MAJOR")
field(HSV , "MINOR")
field(LSV , "MINOR")
field(LLSV, "INVALID")
info("autosaveFields_pass0", "HOPR LOPR HIHI HIGH LOW LOLO")
}
record(ai, "$(P)Time:Write-I") {
field(DESC, "Engine write thread")
field(DTYP, "Python Device")
field(INP , "@bplreport fetch_float metrics.0.secondsConsumedByWritter")
field(SCAN, "I/O Intr")
field(PREC, "2")
field(EGU , "s")
field(TSE , "-2")
field(HOPR, "10")
field(LOPR, "0")
field(HIHI, "5")
field(HIGH, "2")
field(LOW , "0.2")
field(LOLO, "0.1")
field(HHSV, "MAJOR")
field(HSV , "MINOR")
field(LSV , "MINOR")
field(LLSV, "INVALID")
info("autosaveFields_pass0", "HOPR LOPR HIHI HIGH LOW LOLO")
}
record(longin, "$(P)Cnt:Conn-I") {
field(DTYP, "Python Device")
field(INP , "@bplreport fetch_int metrics.0.connectedPVCount")
field(SCAN, "I/O Intr")
field(TSE , "-2")
}
record(longin, "$(P)Cnt:Disconn-I") {
field(DTYP, "Python Device")
field(INP , "@bplreport fetch_int metrics.0.disconnectedPVCount")
field(SCAN, "I/O Intr")
field(TSE , "-2")
field(HOPR, "10000")
field(LOPR, "0")
field(HIHI, "10")
field(HIGH, "1")
field(LOW , "0")
field(HHSV, "MAJOR")
field(HSV , "MINOR")
info("autosaveFields_pass0", "HOPR LOPR HIHI HIGH")
}
record(stringin, "$(P)Status-I") {
field(DTYP, "Python Device")
field(INP , "@bplreport fetch_string metrics.0.status")
field(SCAN, "I/O Intr")
field(TSE , "-2")
}
record(longin, "$(P)Cnt:Type-I") {
field(DTYP, "Python Device")
field(INP , "@bplreport fetch_length typechange.0.")
field(SCAN, "I/O Intr")
field(TSE , "-2")
field(HOPR, "10000")
field(LOPR, "0")
field(HIHI, "10")
field(HIGH, "1")
field(LOW , "0")
field(HHSV, "MAJOR")
field(HSV , "MINOR")
info("autosaveFields_pass0", "HOPR LOPR HIHI HIGH")
}
record(longin, "$(P)Cnt:Never-I") {
field(DTYP, "Python Device")
field(INP , "@bplreport fetch_length neverconn.0.")
field(SCAN, "I/O Intr")
field(TSE , "-2")
field(HOPR, "10000")
field(LOPR, "0")
field(HIHI, "10")
field(HIGH, "1")
field(LOW , "0")
field(HHSV, "MAJOR")
field(HSV , "MINOR")
info("autosaveFields_pass0", "HOPR LOPR HIHI HIGH")
}

151
archApp/bplreport.py Normal file
View File

@ -0,0 +1,151 @@
# -*- coding: utf-8 -*-
import time, sched, urllib2, json
from devsup.db import IOScanListBlock
from devsup.hooks import initHook
from devsup.util import StoppableThread
class BPLReport(object):
reports = {}
def __init__(self, name, url, period):
self.name = name
self.url, self.period = url, period
self.result = None
self.reports[name] = self
self.scan = IOScanListBlock()
def fail(self):
self.result = None
def process(self):
self.result = None
R = urllib2.urlopen(self.url, timeout=3)
try:
if R.getcode()!=200:
print 'Fail',R.getcode(), self.url
self.result = None
return
self.result = json.load(R)
except:
print 'Error fetching',self.url
import traceback
traceback.print_exc()
finally:
R.close()
self.result_time = time.time()
self.scan.interrupt(reason = self.result)
add = BPLReport
class ReportRunner(StoppableThread):
class _Done(Exception):
pass
def _sleep(self, time):
if not self.sleep(time):
raise self._Done()
def _proc(self, R):
self._S.enter(R.period, 0, self._proc, (R,))
try:
R.process()
except:
print 'Error in processing',R.url
import traceback
traceback.print_exc()
R.fail()
def run(self):
self._S = S = sched.scheduler(time.time, self._sleep)
for R in BPLReport.reports.itervalues():
S.enter(0, 0, self._proc, (R,))
try:
S.run()
except self._Done:
print 'BPL worker exit'
except:
print 'Error in scheduler'
import traceback
traceback.print_exc()
_worker = ReportRunner()
@initHook("AfterIocRunning")
def _startWorker():
_worker.start()
print 'BPL worker started'
@initHook("AtIocExit")
def _stopWorker():
print 'BPL worker stopping'
_worker.join()
print 'BPL worker stopped'
class ReportItem(object):
raw = True
def __init__(self, rec, args):
# "<operation> <report>.<index>.<attribute> "
opname, src = args.split(None,2)[:2]
self.report, self.idx, self.attrib = src.split('.',2)
self.idx = int(self.idx)
self.R = BPLReport.reports[self.report]
self.allowScan = self.R.scan.add
self.process = getattr(self, 'process_'+opname)
def detach(self, rec):
pass
def process_fetch_float(self, rec, reason=None):
R = self.R.result
invalid = True
if R is not None and len(R)>self.idx:
try:
rec.VAL = float(str(R[self.idx][self.attrib]).translate(None,','))
except KeyError:
pass
else:
invalid = False
rec.UDF = invalid
rec.setTime(self.R.result_time)
def process_fetch_int(self, rec, reason=None):
R = self.R.result
invalid = True
if R is not None and len(R)>self.idx:
try:
rec.VAL = int(R[self.idx][self.attrib])
except KeyError:
pass
else:
invalid = False
rec.UDF = invalid
rec.setTime(self.R.result_time)
def process_fetch_string(self, rec, reason=None):
R = self.R.result
invalid = True
if R is not None and len(R)>self.idx:
try:
rec.VAL = R[self.idx][self.attrib].encode('ascii')
except KeyError:
pass
else:
invalid = False
if invalid:
rec.setSevr() # default is INVALID_ALARM
rec.setTime(self.R.result_time)
def process_fetch_length(self, rec, reason=None):
if self.R.result is not None:
rec.VAL = len(self.R.result)
rec.UDF = self.R.result is None
rec.setTime(self.R.result_time)
build = ReportItem