X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=hippotat.git;a=blobdiff_plain;f=hippotat%2F__init__.py;h=c31bdb786d37aeda5a65d6d57a810074dcf7e008;hp=5d5129a86fe74eba3c6961f44e53699a2a7b48c2;hb=2e68eb10e3d3068968a930a5a2ab22e97f27853f;hpb=c13ee6e6ebf8336c44baacae7d8ee7a501b37f90 diff --git a/hippotat/__init__.py b/hippotat/__init__.py index 5d5129a..c31bdb7 100644 --- a/hippotat/__init__.py +++ b/hippotat/__init__.py @@ -5,6 +5,8 @@ signal.signal(signal.SIGINT, signal.SIG_DFL) import sys +from zope.interface import implementer + import twisted from twisted.internet import reactor import twisted.internet.endpoints @@ -32,42 +34,71 @@ import re as regexp import hippotat.slip as slip class DBG(twisted.python.constants.Names): + INIT = NamedConstant() ROUTE = NamedConstant() DROP = NamedConstant() FLOW = NamedConstant() HTTP = NamedConstant() - HTTP_CTRL = NamedConstant() - INIT = NamedConstant() + TWISTED = NamedConstant() QUEUE = NamedConstant() + HTTP_CTRL = NamedConstant() QUEUE_CTRL = NamedConstant() HTTP_FULL = NamedConstant() - SLIP_FULL = NamedConstant() CTRL_DUMP = NamedConstant() + SLIP_FULL = NamedConstant() _hex_codec = codecs.getencoder('hex_codec') +#---------- logging ---------- + +org_stderr = sys.stderr + log = twisted.logger.Logger() +debug_set = set() +debug_def_detail = DBG.HTTP + def log_debug(dflag, msg, idof=None, d=None): + if dflag not in debug_set: return #print('---------------->',repr((dflag, msg, idof, d)), file=sys.stderr) if idof is not None: msg = '[%#x] %s' % (id(idof), msg) if d is not None: - d = d[0:64] + #d = d[0:64] d = _hex_codec(d)[0].decode('ascii') msg += ' ' + d log.info('{dflag} {msgcore}', dflag=dflag, msgcore=msg) +@implementer(twisted.logger.ILogFilterPredicate) +class LogNotBoringTwisted: + def __call__(self, event): + yes = twisted.logger.PredicateResult.yes + no = twisted.logger.PredicateResult.no + return yes + try: + if event.get('log_level') != LogLevel.info: + return yes + try: + dflag = event.get('dflag') + except KeyError: + dflag = DBG.TWISTED + return yes if (dflag in debug_set) else no + except Exception: + print(traceback.format_exc(), file=org_stderr) + return yes + +#---------- default config ---------- + defcfg = ''' [DEFAULT] #[] overrides max_batch_down = 65536 # used by server, subject to [limits] max_queue_time = 10 # used by server, subject to [limits] -max_request_time = 54 # used by server, subject to [limits] target_requests_outstanding = 3 # must match; subject to [limits] on server +http_timeout = 30 # used by both } must be +http_timeout_grace = 5 # used by both } compatible max_requests_outstanding = 4 # used by client max_batch_up = 4000 # used by client -http_timeout = 30 # used by client http_retry = 5 # used by client #[server] or [] overrides @@ -96,7 +127,7 @@ port = 80 # used by server [limits] max_batch_down = 262144 # used by server max_queue_time = 121 # used by server -max_request_time = 121 # used by server +http_timeout = 121 # used by server target_requests_outstanding = 10 # used by server ''' @@ -171,9 +202,8 @@ class SlipStreamDecoder(): def inputdata(self, data): self._log('inputdata', d=data) - data = self._buffer + data - self._buffer = b'' packets = slip.decode(data) + packets[0] = self._buffer + packets[0] self._buffer = packets.pop() for packet in packets: self._maybe_packet(packet) @@ -369,14 +399,36 @@ def process_cfg_clients(constructor): #---------- startup ---------- def common_startup(): - log_formatter = twisted.logger.formatEventAsClassicLogText - log_observer = twisted.logger.FileLogObserver(sys.stderr, log_formatter) - twisted.logger.globalLogBeginner.beginLoggingTo( - [ log_observer, crash_on_critical ] - ) - optparser.add_option('-c', '--config', dest='configfile', default='/etc/hippotat/config') + + def ds_by_detail(od,os,detail_level,op): + global debug_set + debug_set = set([df for df in DBG.iterconstants() if df <= detail_level]) + + def ds_one(mutator,df, od,os,value,op): + mutator(df) + + optparser.add_option('-D', '--debug', + default=debug_def_detail.name, + type='choice', + choices=[dl.name for dl in DBG.iterconstants()], + action='callback', + callback= ds_by_detail) + + optparser.add_option('--no-debug', + nargs=0, + action='callback', + callback= partial(ds_by_detail,DBG.INIT)) + + for df in DBG.iterconstants(): + optparser.add_option('--debug-'+df.name, + action='callback', + callback= partial(ds_one, debug_set.add, df)) + optparser.add_option('--no-debug-'+df.name, + action='callback', + callback= partial(ds_one, debug_set.discard, df)) + (opts, args) = optparser.parse_args() if len(args): optparser.error('no non-option arguments please') @@ -384,6 +436,21 @@ def common_startup(): cfg.read_string(re.sub('', defcfg)) cfg.read(opts.configfile) + log_formatter = twisted.logger.formatEventAsClassicLogText + stdout_obs = twisted.logger.FileLogObserver(sys.stdout, log_formatter) + stderr_obs = twisted.logger.FileLogObserver(sys.stderr, log_formatter) + pred = twisted.logger.LogLevelFilterPredicate(LogLevel.error) + stdsomething_obs = twisted.logger.FilteringLogObserver( + stderr_obs, [pred], stdout_obs + ) + log_observer = twisted.logger.FilteringLogObserver( + stdsomething_obs, [LogNotBoringTwisted()] + ) + #log_observer = stdsomething_obs + twisted.logger.globalLogBeginner.beginLoggingTo( + [ log_observer, crash_on_critical ] + ) + def common_run(): log_debug(DBG.INIT, 'entering reactor') if not _crashing: reactor.run()