def configure_standard_logging(verbosity: int, mode: LoggingMode): """Configure the standard library's `logging` module. Get `logging` working with options consistent with Twisted. NOTE CAREFULLY that `django.utils.log.DEFAULT_LOGGING` may have been applied (though only if installed and if configured in this environment). Those settings and the settings this function applies must be mentally combined to understand the resultant behaviour. :param verbosity: See `get_logging_level`. :param mode: The mode in which to configure logging. See `LoggingMode`. """ set_standard_verbosity(verbosity) # Make sure that `logging` is not configured to capture warnings. logging.captureWarnings(False) # If a logger is ever configured `propagate=False` but without handlers # `logging.Logger.callHandlers` will employ the `lastResort` handler in # order that the log is not lost. This goes to standard error by default. # Here we arrange for these situations to be logged more distinctively so # that they're easier to diagnose. logging.lastResort = logging.StreamHandler( twistedModern.LoggingFile( logger=twistedModern.Logger("lost+found"), level=twistedModern.LogLevel.error, ))
def __init__(self, operation_name, min=10, max=30 * 60, failed_mult=1.8, success_mult=0.8): """New rate limiter for a specific operation. Instead of running the operation directly, call this object's `schedule()` method that will enqueue it and call it when possible. If that succeeds, call `success()` to reduce the backoff. Else call `fail()` to increase backoff. :param str operation_name: A name for that operation, used in log messages (for example, "api_request"). :param float min: Minimum delay between operations. :param float max: Maximum delay between operations; we will not increase the delay past that value when backing off. :param float failed_mult: How much to increase the delay when an operation fails (2 would wait twice as long each time). :param float success_mult: How much to change the delay when an operation succeeds (0.5 would wait half as long, 0 would return to the minimum delay immediately). """ self.logger = logger.Logger('%s.RateLimiter.%s' % (__name__, operation_name)) self.min = min self.max = max self.failed_mult = failed_mult self.success_mult = success_mult self.delay = self.min self.last_scheduled = 0 self.queue = []
def show_warning_via_twisted(message, category, filename, lineno, file=None, line=None): """Replacement for `warnings.showwarning` that logs via Twisted.""" if file is None: # Try to find a module name with which to log this warning. module = get_module_for_file(filename) logger = twistedModern.Logger( "global" if module is None else module.__name__) # `message` is/can be an instance of `category`, so stringify. logger.warn( "{category}: {message}", message=str(message), category=category.__qualname__, filename=filename, lineno=lineno, line=line, ) else: # It's not clear why and when `file` will be specified, but try to # honour the intention. warning = warnings.formatwarning(message, category, filename, lineno, line) try: file.write(warning) file.flush() except OSError: pass # We tried.
def __init__(self, name, out_callable=None, err_callable=None): self._log = logger.Logger(namespace=name) self.started = defer.Deferred() self.stopped = defer.Deferred() self._out_callable = out_callable self._err_callable = err_callable self._pid = None
class HandoffFactory(protocol.Factory): protocol = HandoffProtocol log = logger.Logger() def __init__(self, handoff_port, handoff_port_description): self.handoff_port = handoff_port self.handoff_port_description = handoff_port_description def doStop(self): self.log.info("Stopping server port {handoff_port!r}", handoff_port=self.handoff_port) self.handoff_port.connectionLost(CONNECTION_LOST)
def _action_set_log_level(self, message): try: namespace = message['namespace'] level = message['level'] except KeyError: _log.warn('missing level/namespace: {m!r}', m=message) else: self.factory.wiring.set_log_level(namespace, level) # Log message on the specified logger/level to feed user back. level = logger.LogLevel.levelWithName(level) logger.Logger(namespace=namespace).emit(level, 'log level set')
def __init__(self, filename, player_mgr, *, layer=0, loop=False, alpha=255, fadein=0, fadeout=0): """ Initialization arguments: - `filename`: the movie filename to play. - `player_mgr`: provides access to DBus, reactor, and more. - `layer`: used with omxplayer --layer argument. - `loop`: if true, omxplayer is passed the --loop argument. - `alpha`: used with omxplayer --alpha argument. - `fadein`: fade in duration, in seconds. - `fadeout`: fade out duration, in seconds. """ self._filename = filename self._player_mgr = player_mgr self._dbus_mgr = player_mgr.dbus_mgr self._layer = layer self._loop = loop self._alpha = alpha self._fadein = fadein self._fadeout = fadeout # Will be obtained by querying the omxplayer process via DBus. self._duration = None # Use a known name so that we can track omxplayer's DBus presence. self._dbus_player_name = self.generate_player_name(filename) self._log = logger.Logger(namespace='player.each.%s' % (self._dbus_player_name, )) self._reactor = self._player_mgr.reactor self._dbus_conn = self._dbus_mgr.dbus_conn # Used to track omxplayer process startup/termination. self._process_protocol = None # DBus proxy object for the player: used to control it. self._dbus_player = None # Lifecycle tracking. self._ready = defer.Deferred() self._stop_in_progress = False self._fadeout_dc = None self._fading_out = False
# ---------------------------------------------------------------------------- # vim: ts=4:sw=4:et # ---------------------------------------------------------------------------- # inputs/hid/reader.py # ---------------------------------------------------------------------------- """ USB HID device reader. """ from twisted.internet import interfaces from twisted import logger from zope.interface import implementer import evdev _log = logger.Logger(namespace='inputs.hid.reader') @implementer(interfaces.IReadDescriptor) class InputDeviceReader(object): """ Twisted IReadDescritor implementation that reads events from the USB HID device file, integrating evdev's InputDevice file descriptor into the reactor and using the InputDevice's read_one() method to complete reads. Events matching `reading_event_code` will be passed to the `event_callback`. """ # Mostly adapted from glyph's answer at: # (glyph is the creator of Twisted, integrating his response is solid!) #
from twisted.internet import reactor from twisted import logger from twisted.web.resource import NoResource, Resource from twisted.web.server import NOT_DONE_YET, Site import urllib from matrix_gitter.utils import FormProducer, read_json_response, http_request log = logger.Logger() HTML_TEMPLATE = '''\ <html> <head><title>{title}</title></head> <body> {content} </body> </html> ''' class Index(Resource): """Index page, showing some info about this system. """ def __init__(self, botname): self.botname = botname Resource.__init__(self) def render_GET(self, request): request.setHeader('content-type', 'text/html') return HTML_TEMPLATE.format( title="Gitter-Matrix bridge",
import sys from functools import lru_cache from ipaddress import IPv4Network, IPv6Network, ip_address, ip_network import twisted.logger as logger from klein import Klein from twisted.names import authority, dns from twisted.python.filepath import FilePath from twisted.web.resource import ErrorPage, ForbiddenResource from hashing import hash_parts_generator log = logger.Logger(observer=logger.textFileLogObserver(sys.stdout)) class _WordsController(object): """ Basic controller that manages registered zones and manages name assignment by filtering on the registered IP subnet. """ def __init__(self, data_dir="data", word_count=3): self.data_dir = FilePath(data_dir) self.word_count = word_count self.separator = b"-" self.data = dict() self.proxied = False self.app = Klein()
""" An asyncronous, Twisted/Autobahn based, HTTP/websocket server. """ from datetime import datetime import json import textwrap from zope.interface import provider from twisted import logger from autobahn.twisted import websocket import log as log_package _log = logger.Logger(namespace='inputs.web') @provider(logger.ILogObserver) class WSProto(websocket.WebSocketServerProtocol): """ Server side websocket implementation. """ def onConnect(self, request): # Twisted/Autobahn calls this when a websocket connection is establised. pass def onOpen(self):
from twisted.internet import task as t_i_task from twisted.python import failure as t_p_failure from .modwalk import ( logimporterror, modgen, ) from .version import __release__ # ---- Data -------------------------------------------------------------- __all__ = () _LOGGER = logging.getLogger(__name__) _T_LOGGER = t_logger.Logger(__name__) _T_LOG_OBSERVER = t_logger.STDLibLogObserver() _LOG_FMT_ENV = 'LOG_FMT' _LOG_FMT_DFLT = '%(message)s' _LOG_LVL_ENV = 'LOG_LVL' _LOG_LVL_DFLT = logging.getLevelName(logging.WARNING) # ---- Classes ----------------------------------------------------------- # ======================================================================== class CallbackAppender(argparse.Action): # ---- Class methods ------------------------------------------------- @classmethod
# ---------------------------------------------------------------------------- # vim: ts=4:sw=4:et # ---------------------------------------------------------------------------- # inputs/audio/input.py # ---------------------------------------------------------------------------- """ The audio input. """ from twisted.internet import defer from twisted import logger from inputs import input_base from common import process _log = logger.Logger(namespace='inputs.audio') class AudioInput(input_base.InputBase): """ Audio input. """ # Spawns ALSA's arecord utility as a sub-process and tracks its # very-very-verbose mode output on stderr, that produces lines like: # # "Max peak (800 samples): 0x00007ffc #################### 99%" # # These are parsed into individual integer readings and output via the # `wiring.audio` call.
# ---------------------------------------------------------------------------- """ Asyncronous, Twisted based, input management. """ from twisted.internet import defer from twisted import logger from . import agd from . import arduino from . import audio from . import network from . import web from . import hid _log = logger.Logger(namespace='inputs') _INPUT_CLASSES = { 'agd': agd.Input, 'arduino': arduino.Input, 'audio': audio.Input, 'hid': hid.Input, 'network': network.Input, 'web': web.Input, } class InputManager(object): """ Initializes inputs and mediates their feeds to a player manager. """
# ---------------------------------------------------------------------------- """ Asyncronous, Twisted based, video playing interface. """ import collections import os import random from twisted.internet import defer from twisted import logger from .dbus_manager import DBusManager from .player import OMXPlayer _log = logger.Logger(namespace='player.mngr') class PlayerManager(object): """ Tracks and controls video playing via one OMXPlayer instance per level. """ # General lifecycle # ----------------- # - Initialization finds available video files from the settings. # - Starting: # - Spawns one OMXPlayer per level (which start in paused mode). # - Unpause level 0 player. # - Level triggering calls (from the outside): # - Unpause level X player.
class AlwaysAbortFactory(protocol.Factory): log = logger.Logger() def buildProtocol(self, addr): self.log.warn('rejecting incoming connection: {addr}', addr=addr) return None
# ---------------------------------------------------------------------------- # vim: ts=4:sw=4:et # ---------------------------------------------------------------------------- # inputs/arduino/input.py # ---------------------------------------------------------------------------- """ High level Arduino input. """ from twisted.internet import defer, serialport from twisted import logger from inputs import input_base from . import protocol _log = logger.Logger(namespace='inputs.arduino') class ArduinoInput(input_base.InputBase): """ Processes serial received PDUs (protocol data units) that are integers that will be bigger when the sensors detect "more wind". Produces output by calling `arduino` on the `wiring`. """ def __init__(self, reactor, wiring, device_file, baud_rate): super(ArduinoInput, self).__init__(reactor, wiring) self._device_file = device_file self._baud_rate = baud_rate self._output_callable = wiring.arduino
# ---------------------------------------------------------------------------- # vim: ts=4:sw=4:et # ---------------------------------------------------------------------------- # inputs/hid/input.py # ---------------------------------------------------------------------------- """ The USB HID input. """ from twisted.internet import defer from twisted import logger from inputs import input_base from . import reader _log = logger.Logger(namespace='inputs.hid') class USBHIDInput(input_base.InputBase): """ USB HID input. Monitors USB HID events and delivers readings for the tracked event code. Operates at two levels: - Events are filtered and stored asynchronously, as they come. - The output stream of readings is kept at a constant pace, set by `period`, regardless of underlying events. """ # The async storing of readings vs. steady-pace reading output production # has two benefits:
# vim: ts=4:sw=4:et # ---------------------------------------------------------------------------- # inputs/network/protocol.py # ---------------------------------------------------------------------------- """ Twisted implementation of the network input protocol. """ from twisted.internet import protocol from twisted.protocols import basic from twisted import logger _log = logger.Logger(namespace='inputs.network') class ControlProtocol(basic.LineReceiver): """ Line based control protocol. Lines should be terminated by CRLF. Accepts single digit lines that notify the input manager of such level change requests. """ def connectionMade(self):
""" Asyncrounous, Twisted Based, DBus connection setup and name tracking. """ import os from twisted.internet import defer from twisted import logger from txdbus import client as txdbus_client from common import process _log = logger.Logger(namespace='player.dbus') class DBusManager(object): """ Manages a private DBus instance by spawning a child DBus daemon, connecting to it and tracking object names showing up/going away. """ def __init__(self, reactor, settings): self._reactor = reactor # Will be set once the private DBus process is spawned.