# coding: utf8 # -------------- Modules ------------------------- from json import load import os from os.path import isfile import re import datetime import time from glob import glob import cPickle import syslog import sys import Activity import WGDBus import FileIface import logConfig import status_mod import subprocess # Fake globals for syntax check if False: response = None request = None session = None db = None syserrdb = None status_mod.sessionUserMgr.setLastVisit(session, request) if logConfig.diagSessFrgt: session.forget(response) DEFAULT_LANG = 'en' MESSAGES_FILE = '/mnt/data/log/messages' RDYSTATUS_FILE = '/home/tool/config/log/rdystatus.json' if FileIface._DATA_ROOT_PATH == None or FileIface._DATA_ROOT_PATH == '': TIWLAN_DIR = '/var/run/diag/tiwlan/' else: TIWLAN_DIR = FileIface._DATA_ROOT_PATH + 'diag/tiwlan/' # -------------------------------------------- # System errors # -------------------------------------------- def __loadErrorStrings(): langData = {} lang = session.lang if session.lang else DEFAULT_LANG langFile = '/home/tool/config/langs/{0}.json'.format(lang) if not isfile(langFile) and lang != DEFAULT_LANG: langFile = '/home/tool/config/langs/{0}.json'.format(DEFAULT_LANG) try: with open(langFile, 'rt') as f: data = load(f) langData = data['syserror'] except: pass return langData @auth.requires(request.ajax==True, requires_login=True) def lastNotQuittedError(): code2string = __loadErrorStrings() columns = ['id', 'date', 'code', 'class', 'ack'] result = {'desc': 'Error not found'} try: table = syserrdb.executesql('SELECT {0} FROM syserrors where id = (SELECT max(id) from syserrors where ack = 0)'.format(', '.join(columns))) for row in table: tmp = dict(zip(columns, row)) tmp['desc'] = code2string.get(str(tmp['code']), '') result = tmp except: pass return response.json(result) @auth.requires(request.ajax==True, requires_login=True) def sysErrors(): code2string = __loadErrorStrings() columns = ['id', 'date', 'code', 'class', 'ack'] result = [] try: table = syserrdb.executesql('SELECT {0} FROM syserrors'.format(','.join(columns))) for row in table: tmp = dict(zip(columns, row)) tmp['desc'] = code2string.get(str(tmp['code']), '') # CR13452 this is not wanted, cause in sys error it is not possible: #offset = calendar.timegm(time.localtime()) - calendar.timegm(time.gmtime()) #tmp['date'] = tmp['date'] + offset # CR16078 Always write datetime # date and time with tz offset implemented as in result_mod.actualvalues: tmp['date'] = "{0} {1}".format(datetime.datetime.fromtimestamp(tmp['date']).date().isoformat(), datetime.datetime.fromtimestamp(tmp['date']).time().isoformat()) result.append(tmp) except: pass return response.json(result) @auth.requires(request.ajax==True, requires_login=True) def countNotAckErrors(): try: table = syserrdb.executesql('SELECT count(ack) FROM syserrors WHERE ack = 0') count = table[0][0] except: pass return response.json(count) @auth.requires(request.ajax==True, requires_login=True) def errorStatistics(): code2string = __loadErrorStrings() result = [] try: errors = [e for e in syserrdb.executesql("SELECT code, class FROM syserrors")] if errors: counter = {} for code in errors: if code[0] in counter: counter[code[0]][0] += 1 else: counter[code[0]] = [1, code[1]] for code, count in counter.iteritems(): desc = code2string.get(str(code), '') result.append({'code': code, 'rate': float(count[0]) / len(errors), 'cnt': count[0], 'class': count[1], 'desc': desc}) except: pass return response.json(result) @auth.requires(request.ajax==True, requires_login=True) def ackErrors(): if WGDBus.ackErrorList(): Activity.LOG(session, Activity.SYS_ERRORS_ACK) @auth.requires(request.ajax==True, requires_login=True) def delErrors(): if WGDBus.delErrorList(): Activity.LOG(session, Activity.SYS_ERRORS_DEL) # -------------------------------------------- # Log messages # -------------------------------------------- def __dateDict2Int(date): # example: { 'month': Jan, 'day': '28', 'hour': '01', 'minute': '32', 'second': '06' } if not date.get('year', None): date['year'] = datetime.datetime.now().year for k in date.iterkeys(): if k == 'month': date[k] = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'].index(date[k]) + 1 else: date[k] = int(date[k]) date = datetime.datetime(**date) # datetime.datetime date = date.timetuple() # time.time_struct date = time.mktime(date) # float, seconds since 1 Jan 1970 00:00:00 return int(date) def __parseMessageLine(pattern, line): parts = pattern.match(line).groupdict() desc = parts.get('desc') service = desc.split(":")[0] parts['service'] = service date = {} for key in ['year', 'month', 'day', 'hour', 'minute', 'second']: date[key] = parts.pop(key, None) parts['date'] = __dateDict2Int(date) return parts @auth.requires(request.ajax==True, requires_login=True) def logMessages(): result = [] try: with open(MESSAGES_FILE, 'rt') as f: pattern = re.compile('(?P[A-Z]{1}[a-z]{2})\s+(?P[0-9]{1,2})\s+(?P[0-9]{2}):(?P[0-9]{2}):(?P[0-9]{2})\s+(?P\S+)\s+(?P[^ \t\n\r\f\v\.]+)\.(?P\S+)\s+(?P.*)') for line in f: result.append(__parseMessageLine(pattern, line.decode('utf-8').strip())) except: syslog.syslog(syslog.LOG_INFO, "web2py:diagnosis.logMessages: " + str(sys.exc_info()[1])) syslog.syslog(syslog.LOG_INFO, "web2py:diagnosis.logMessages: trying to recover with iso-8859-1") try: with open(MESSAGES_FILE, 'rt') as f: pattern = re.compile('(?P[A-Z]{1}[a-z]{2})\s+(?P[0-9]{1,2})\s+(?P[0-9]{2}):(?P[0-9]{2}):(?P[0-9]{2})\s+(?P\S+)\s+(?P[^ \t\n\r\f\v\.]+)\.(?P\S+)\s+(?P.*)') for line in f: result.append(__parseMessageLine(pattern, unicode(line.decode('iso-8859-1')).strip())) except: syslog.syslog(syslog.LOG_ERR, "web2py:diagnosis.logMessages: " + str(sys.exc_info()[1])) return response.json(result) # -------------------------------------------- # Ready status # -------------------------------------------- @auth.requires(request.ajax==True, requires_login=True) def rdyStatus(): result = [] values = WGDBus.rdyGet() if values: istValues = values[0].real sollValues = values[1].real try: with open(RDYSTATUS_FILE, 'r') as f: data = load(f) for item in data['flags']: if item['state']: bit = item['nr'] soll = sollValues >> bit & 1 ist = istValues >> bit & 1 r = {'name': item['name'], 'soll': soll, 'ist': ist} result.append(r) except: pass return response.json(result) # -------------------------------------------- # Server errors # -------------------------------------------- @auth.requires(request.ajax==True, requires_login=True) def serverErrors(): res = [] filelist = glob('./applications/BS350/errors/*') filelist.sort(reverse=True) total = len(filelist) ii = 1 for filename in filelist: item = {} tokens = os.path.basename(filename).split('.') item['id'] = ii ii +=1 item['ip'] = '.'.join(tokens[0:4]) item['timestamp'] = ' '.join((tokens[4], tokens[5].replace('-', ':'))) with open(filename, 'r') as f: data = cPickle.load(f) item['output'] = data['output'] item['layer'] = data['layer'] item['traceback'] = data['traceback'] res.append(item) return response.json({'total': total, 'items': res, 'success': True}) @auth.requires(request.ajax==True, requires_login=True) def deleteServerErrors(): filelist = glob('./applications/BS350/errors/*') for f in filelist: os.remove(f) def getTR(dicti, key): """Returns the i18n value if key found in Dictionary, else return given key.""" return dicti.get(key, key) # -------------------------------------------- # Activity log # -------------------------------------------- @auth.requires(request.ajax==True, requires_login=True) def getlog(): # get entries entries = Activity.getEntries() # get users items = db.executesql("SELECT id,username FROM auth_user") users={} for i in items: users[i[0]] = i[1] # get translations lang = str(session.lang) TR = {} try: with open('/home/tool/config/langs/%s.json' % lang, 'r') as f: data = load(f) TR = data['activity'] TRwg = data['webgui'] except: pass res = [] for entry in entries: userId = entry['user'] if userId in users: username = users[userId] else: username = 'unknown (%s)' % userId code = str(entry['code']) if code in TR: event = TR[code] if entry['value1']: ctrl = entry['value1'].split('/') tmp = [] if ctrl: for key in ctrl: tmp.append(getTR(TRwg, key)) entry['value1'] = "/".join(tmp) event = event.replace('%1', getTR(TRwg, entry['value1'])) event = event.replace('%2', getTR(TRwg, entry['value2'])) event = event.replace('%3', getTR(TRwg, entry['value3'])) event = event.replace('%4', getTR(TRwg, entry['value4'])) else: event = '%s: %s %s %s %s' % (code, entry['value1'], entry['value2'], entry['value3'], entry['value4']) timestamp = datetime.datetime.fromtimestamp(entry['timestamp']) res.append({'id': entry['id'], 'timestamp': timestamp, 'username': username, 'event': event}) return response.json(res) @auth.requires(request.ajax==True, requires_login=True) def clearlog(): Activity.clearLog(session) @auth.requires(request.ajax==True, requires_login=True) def wlan(): name = request.vars.name filename = "-".join(map(lambda x: x.lower(), filter(lambda x: len(x) > 0, re.split("([A-Z]?[a-z]*)", name)))) if filename == 'power-consumption-statistics': filename = 'power-cons-statistics' elif filename == 'basic-statistics': filename = 'basic-statistic' elif filename == 'roaming-candidate-list': filename = 'roaming-list' if WGDBus.reqWlanDiagnostics(name) != 0: return response.json({'data': "Wlan request failed, try refresh", 'mtime': -1 }) if os.path.isfile(TIWLAN_DIR + filename + '.dat'): with open(TIWLAN_DIR + filename + '.dat', 'rt') as f: data = f.read() return response.json({'data': data, 'mtime': int(os.path.getmtime(TIWLAN_DIR + filename + '.dat'))}) return response.json({'data': "File not found, try refresh", 'mtime': -1 }) @auth.requires(request.ajax==True, requires_login=True) def wlanRefresh(): return (wlan())