From 50f02747de9ff21d3d6c8202ee1b14a326f332eb Mon Sep 17 00:00:00 2001 From: Neil Booth Date: Wed, 21 Dec 2016 19:38:59 +0900 Subject: [PATCH] Throttle abusive logging --- lib/jsonrpc.py | 1 + lib/util.py | 13 +++++++++++-- server/protocol.py | 5 +++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/jsonrpc.py b/lib/jsonrpc.py index 9a74eaa..7301076 100644 --- a/lib/jsonrpc.py +++ b/lib/jsonrpc.py @@ -215,6 +215,7 @@ class JSONRPC(asyncio.Protocol, LoggedClass): refund = int(elapsed / self.bandwidth_interval * self.bandwidth_limit) refund = min(refund, self.bandwidth_used) self.bandwidth_used += amount - refund + self.throttled = max(0, self.throttled - int(elapsed) // 60) def data_received(self, data): '''Handle incoming data (synchronously). diff --git a/lib/util.py b/lib/util.py index 4559cfd..c8a5fe2 100644 --- a/lib/util.py +++ b/lib/util.py @@ -22,8 +22,17 @@ class LoggedClass(object): self.logger = logging.getLogger(self.__class__.__name__) self.logger.setLevel(logging.INFO) self.log_prefix = '' - - def log_info(self, msg): + self.throttled = 0 + + def log_info(self, msg, throttle=False): + # Prevent annoying log messages by throttling them if there + # are too many in a short period + if throttle: + self.throttled += 1 + if self.throttled > 3: + return + if self.throttled == 3: + msg += ' (throttling later logs)' self.logger.info(self.log_prefix + msg) def log_warning(self, msg): diff --git a/server/protocol.py b/server/protocol.py index 7ebb06d..d76c914 100644 --- a/server/protocol.py +++ b/server/protocol.py @@ -339,7 +339,7 @@ class ServerManager(util.LoggedClass): group = self.groups[int(session.start - self.start) // 900] group.add(session) self.sessions[session] = group - session.log_info('{} from {}, {:,d} total' + session.log_info('{} {}, {:,d} total' .format(session.kind, session.peername(), len(self.sessions))) if (len(self.sessions) >= self.max_sessions @@ -920,7 +920,8 @@ class ElectrumX(Session): except DaemonError as e: error = e.args[0] message = error['message'] - self.log_info('sendrawtransaction: {}'.format(message)) + self.log_info('sendrawtransaction: {}'.format(message), + throttle=True) if 'non-mandatory-script-verify-flag' in message: return ( 'Your client produced a transaction that is not accepted '