# HG changeset patch # User Matt Johnston # Date 1434206954 -28800 # Node ID 59cb8449ef975c328ba57962f03d739b0ac10a16 # Parent dd809548424c9d4ab9a9738f0a1bdcb2fbea9e9f Limit log diff -r dd809548424c -r 59cb8449ef97 py/configwaiter.py --- a/py/configwaiter.py Sat Jun 13 21:56:51 2015 +0800 +++ b/py/configwaiter.py Sat Jun 13 22:49:14 2015 +0800 @@ -1,4 +1,6 @@ import asyncio +import datetime + import aiohttp import utils @@ -12,6 +14,7 @@ self.server = server self.epoch_tag = None self.http_session = aiohttp.ClientSession() + self.limitlog = utils.NotTooOften(datetime.timedelta(minutes=15)) @asyncio.coroutine def run(self): @@ -49,14 +52,13 @@ pass else: # longer timeout to avoid spinning + text = yield from asyncio.wait_for(r.text(), 600) + D("Bad server response. %d %s" % (r.status, text)) yield from asyncio.sleep(30) - except asyncio.TimeoutError: - D("configwaiter http timed out") - pass + except aiohttp.errors.ClientError as e: + self.limitlog.log("Error with configwaiter: %s" % str(e)) + except asyncio.TimeoutError as e: + self.limitlog.log("configwaiter http timed out: %s" % str(e)) except Exception as e: EX("Error watching config: %s" % str(e)) - - - - diff -r dd809548424c -r 59cb8449ef97 py/uploader.py --- a/py/uploader.py Sat Jun 13 21:56:51 2015 +0800 +++ b/py/uploader.py Sat Jun 13 22:49:14 2015 +0800 @@ -15,6 +15,7 @@ class Uploader(object): def __init__(self, server): self.server = server + self.limitlog = utils.NotTooOften(600) @asyncio.coroutine def run(self): @@ -43,6 +44,9 @@ return tosend + class BadServerResponse(Exception): + pass + @asyncio.coroutine def send(self, tosend): js = json.dumps(tosend) @@ -55,7 +59,7 @@ r = yield from asyncio.wait_for(aiohttp.request('post', config.UPDATE_URL, data=send_data), 60) result = yield from asyncio.wait_for(r.text(), 60) if r.status == 200 and result != 'OK': - raise Exception("Server returned %s" % result) + raise BadServerResponse("Server returned %s" % result) @asyncio.coroutine def do(self): @@ -67,6 +71,12 @@ yield from self.send(tosend) readings = None D("Sent updated %d readings" % nreadings) + except aiohttp.errors.ClientError as e: + self.limitlog.log("Error with uploader: %s" % str(e)) + except asyncio.TimeoutError as e: + self.limitlog.log("uploader http timed out: %s" % str(e)) + except self.BadServerResponse as e: + self.limitlog.log("Bad reply with uploader: %s" % str(e)) except Exception as e: EX("Error in uploader: %s" % str(e)) finally: diff -r dd809548424c -r 59cb8449ef97 py/utils.py --- a/py/utils.py Sat Jun 13 21:56:51 2015 +0800 +++ b/py/utils.py Sat Jun 13 22:49:14 2015 +0800 @@ -1,11 +1,12 @@ import os import sys -#import ctypes +import ctypes import time import select import logging import binascii import json +import datetime D = logging.debug L = logging.info @@ -138,3 +139,35 @@ def json_load_round_float(s, **args): return json.loads(s,parse_float = lambda f: round(float(f), 2), **args) + +class NotTooOften(object): + """ prevents things happening more than once per limit. + Isn't monotonic, good enough for logging. eg + self.logfailure = NotTooOften(180) # 3 minutes + ... + if self.logfailure(): + L("blah") + """ + def __init__(self, limit): + """ limit is a delay in seconds or TimeDelta """ + if type(limit) is datetime.timedelta: + self.limit = limit + else: + self.limit = datetime.timedelta(seconds=limit) + + # must be positive + assert self.limit > datetime.timedelta(0) + self.last = datetime.datetime(10, 1, 1) + + def __call__(self): + if datetime.datetime.now() - self.last > self.limit: + self.last = datetime.datetime.now() + return True + + def log(self, msg): + """ calls L(msg) if it isn't too often, otherwise D(msg) + """ + if self(): + L(msg + " (log interval %s)" % str(self.limit)) + else: + D(msg)