def test_atoms_defaults(): response = SimpleNamespace( status='200', response_length=1024, headers=(('Content-Type', 'application/json'), ), sent=1024, ) request = SimpleNamespace(headers=(('Accept', 'application/json'), )) environ = { 'REQUEST_METHOD': 'GET', 'RAW_URI': '/my/path?foo=bar', 'PATH_INFO': '/my/path', 'QUERY_STRING': 'foo=bar', 'SERVER_PROTOCOL': 'HTTP/1.1', } logger = Logger(Config()) atoms = logger.atoms(response, request, environ, datetime.timedelta(seconds=1)) assert isinstance(atoms, dict) assert atoms['r'] == 'GET /my/path?foo=bar HTTP/1.1' assert atoms['m'] == 'GET' assert atoms['U'] == '/my/path' assert atoms['q'] == 'foo=bar' assert atoms['H'] == 'HTTP/1.1' assert atoms['b'] == '1024' assert atoms['B'] == 1024 assert atoms['{accept}i'] == 'application/json' assert atoms['{content-type}o'] == 'application/json'
def access(self, resp, req, environ, request_time): # health check endpoints are only logged in debug mode if (not os.environ.get('DEIS_DEBUG', False) and req.path in ['/readiness', '/healthz']): return Logger.access(self, resp, req, environ, request_time)
def _sock_send(self, msg): try: if isinstance(msg, six.text_type): msg = msg.encode("ascii") if self.sock: self.sock.send(msg) except Exception: Logger.warning(self, "Error sending message to statsd", exc_info=True)
def access(self, resp, req, environ, request_time): # health check endpoints are only logged in debug mode if ( not os.environ.get('DEIS_DEBUG', False) and req.path in ['/readiness', '/healthz'] ): return Logger.access(self, resp, req, environ, request_time)
def access(self, resp, req, environ, request_time): """Measure request duration request_time is a datetime.timedelta """ Logger.access(self, resp, req, environ, request_time) duration_in_ms = request_time.seconds * 1000 + float(request_time.microseconds) / 10 ** 3 self.histogram("gunicorn.request.duration", duration_in_ms) self.increment("gunicorn.requests", 1) self.increment("gunicorn.request.status.%d" % int(resp.status.split()[0]), 1)
def __init__(self, cfg): """host, port: statsD server """ Logger.__init__(self, cfg) try: host, port = cfg.statsd_host self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.connect((host, int(port))) except Exception: self.sock = None
def __init__(self, cfg): """host, port: statsD server """ Logger.__init__(self, cfg) self.prefix = sub(r"^(.+[^.]+)\.*$", "\\g<1>.", cfg.statsd_prefix) try: host, port = cfg.statsd_host self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.connect((host, int(port))) except Exception: self.sock = None
def access(self, resp, req, environ, request_time): """Measure request duration request_time is a datetime.timedelta """ Logger.access(self, resp, req, environ, request_time) duration_in_s = request_time.seconds + float( request_time.microseconds) / 10**6 self.histogram("gunicorn.request.duration", duration_in_s) self.increment("gunicorn.requests", 1) self.increment( "gunicorn.request.status.%d" % int(resp.status.split()[0]), 1)
def access(self, resp, req, environ, request_time): """Measure request duration request_time is a datetime.timedelta """ Logger.access(self, resp, req, environ, request_time) duration_in_ms = request_time.seconds * 1000 + float(request_time.microseconds) / 10 ** 3 status = resp.status if isinstance(status, str): status = int(status.split(None, 1)[0]) self.histogram("gunicorn.request.duration", duration_in_ms) self.increment("gunicorn.requests", 1) self.increment("gunicorn.request.status.%d" % status, 1)
def _sock_send(self, msg): try: if isinstance(msg, str): msg = msg.encode("ascii") # http://docs.datadoghq.com/guides/dogstatsd/#datagram-format if self.dogstatsd_tags: msg = msg + b"|#" + self.dogstatsd_tags.encode('ascii') if self.sock: self.sock.send(msg) except Exception: Logger.warning(self, "Error sending message to statsd", exc_info=True)
def __init__(self, cfg): Logger.__init__(self, cfg) self.is_statsd = False statsd_server = os.environ.get("statsd") if statsd_server: try: host, port = statsd_server.split(":") self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.connect((host, int(port))) except Exception: self.sock = None else: self.is_statsd = True
def test_atoms_defaults(): response = Mock(status='200', response_length=1024, headers=(('Content-Type', 'application/json'), )) request = Mock(headers=(('Accept', 'application/json'), )) environ = {'REQUEST_METHOD': 'GET', 'RAW_URI': 'http://my.uri', 'SERVER_PROTOCOL': 'HTTP/1.1'} logger = Logger(Config()) atoms = logger.atoms(response, request, environ, datetime.timedelta(seconds=1)) t.istype(atoms, dict) t.eq(atoms['r'], 'GET http://my.uri HTTP/1.1') t.eq(atoms['{accept}i'], 'application/json') t.eq(atoms['{content-type}o'], 'application/json')
def test_get_username_from_basic_auth_header(): request = SimpleNamespace(headers=()) response = SimpleNamespace( status='200', response_length=1024, sent=1024, headers=(('Content-Type', 'text/plain'),), ) environ = { 'REQUEST_METHOD': 'GET', 'RAW_URI': 'http://my.uri', 'SERVER_PROTOCOL': 'HTTP/1.1', 'HTTP_AUTHORIZATION': 'Basic YnJrMHY6', } logger = Logger(Config()) atoms = logger.atoms(response, request, environ, datetime.timedelta(seconds=1)) assert atoms['u'] == 'brk0v'
def test_atoms_zero_bytes(): response = SimpleNamespace( status='200', response_length=0, headers=(('Content-Type', 'application/json'),), sent=0, ) request = SimpleNamespace(headers=(('Accept', 'application/json'),)) environ = { 'REQUEST_METHOD': 'GET', 'RAW_URI': '/my/path?foo=bar', 'PATH_INFO': '/my/path', 'QUERY_STRING': 'foo=bar', 'SERVER_PROTOCOL': 'HTTP/1.1', } logger = Logger(Config()) atoms = logger.atoms(response, request, environ, datetime.timedelta(seconds=1)) assert atoms['b'] == '0' assert atoms['B'] == 0
def test_get_username_from_basic_auth_header(): request = SimpleNamespace(headers=()) response = SimpleNamespace( status='200', response_length=1024, sent=1024, headers=(('Content-Type', 'text/plain'),), ) environ = { 'REQUEST_METHOD': 'GET', 'RAW_URI': '/my/path?foo=bar', 'PATH_INFO': '/my/path', 'QUERY_STRING': 'foo=bar', 'SERVER_PROTOCOL': 'HTTP/1.1', 'HTTP_AUTHORIZATION': 'Basic YnJrMHY6', } logger = Logger(Config()) atoms = logger.atoms(response, request, environ, datetime.timedelta(seconds=1)) assert atoms['u'] == 'brk0v'
def test_atoms_defaults(): response = SimpleNamespace( status='200', response_length=1024, headers=(('Content-Type', 'application/json'),), sent=1024, ) request = SimpleNamespace(headers=(('Accept', 'application/json'),)) environ = { 'REQUEST_METHOD': 'GET', 'RAW_URI': 'http://my.uri', 'SERVER_PROTOCOL': 'HTTP/1.1', } logger = Logger(Config()) atoms = logger.atoms(response, request, environ, datetime.timedelta(seconds=1)) assert isinstance(atoms, dict) assert atoms['r'] == 'GET http://my.uri HTTP/1.1' assert atoms['{accept}i'] == 'application/json' assert atoms['{content-type}o'] == 'application/json'
def test_get_username_handles_malformed_basic_auth_header(): """Should catch a malformed auth header""" request = SimpleNamespace(headers=()) response = SimpleNamespace( status='200', response_length=1024, sent=1024, headers=(('Content-Type', 'text/plain'),), ) environ = { 'REQUEST_METHOD': 'GET', 'RAW_URI': '/my/path?foo=bar', 'PATH_INFO': '/my/path', 'QUERY_STRING': 'foo=bar', 'SERVER_PROTOCOL': 'HTTP/1.1', 'HTTP_AUTHORIZATION': 'Basic ixsTtkKzIpVTncfQjbBcnoRNoDfbnaXG', } logger = Logger(Config()) atoms = logger.atoms(response, request, environ, datetime.timedelta(seconds=1)) assert atoms['u'] == '-'
def info(self, msg, *args, **kwargs): """Log a given statistic if metric, value and type are present """ Logger.info(self, msg, *args, **kwargs) extra = kwargs.get("extra", None) if extra is not None: metric = extra.get(METRIC_VAR, None) value = extra.get(VALUE_VAR, None) typ = extra.get(MTYPE_VAR, None) if metric and value and typ: if typ == GAUGE_TYPE: self.gauge(metric, value) elif typ == COUNTER_TYPE: self.increment(metric, value) elif typ == HISTOGRAM_TYPE: self.histogram(metric, value) else: pass
def setup(self, cfg): Logger.setup(self, cfg) CONFIG_DEFAULTS['handlers']['console']['filters'] = \ ["stdout_filter"] CONFIG_DEFAULTS['handlers']['error_console']['filters'] = \ ["stderr_filter"] CONFIG_DEFAULTS['loggers']['gunicorn.error']['handlers'] = \ ['console', 'error_console'] CONFIG_DEFAULTS['filters'] = { "stdout_filter": { "()": "gunicorn_custom_log.StdoutFilter" }, "stderr_filter": { "()": "gunicorn_custom_log.StderrFilter" } } CONFIG_DEFAULTS['disable_existing_loggers'] = True dictConfig(CONFIG_DEFAULTS)
def test_atoms_defaults(): response = SimpleNamespace( status='200', response_length=1024, headers=(('Content-Type', 'application/json'), ), sent=1024, ) request = SimpleNamespace(headers=(('Accept', 'application/json'), )) environ = { 'REQUEST_METHOD': 'GET', 'RAW_URI': 'http://my.uri', 'SERVER_PROTOCOL': 'HTTP/1.1', } logger = Logger(Config()) atoms = logger.atoms(response, request, environ, datetime.timedelta(seconds=1)) assert isinstance(atoms, dict) assert atoms['r'] == 'GET http://my.uri HTTP/1.1' assert atoms['{accept}i'] == 'application/json' assert atoms['{content-type}o'] == 'application/json'
def __init__(self, cfg): """host, port: statsD server """ Logger.__init__(self, cfg) self.prefix = sub(r"^(.+[^.]+)\.*$", "\\g<1>.", cfg.statsd_prefix) if cfg.statsd_socket: address_family = socket.AF_UNIX address = cfg.statsd_socket elif cfg.statsd_host: address_family = socket.AF_INET host, port = cfg.statsd_host address = (host, int(port)) try: self.sock = socket.socket(address_family, socket.SOCK_DGRAM) self.sock.connect(address) except Exception: self.sock = None self.dogstatsd_tags = cfg.dogstatsd_tags
def test_atoms_defaults(): response = SimpleNamespace( status='200', response_length=1024, headers=(('Content-Type', 'application/json'),), sent=1024, ) request = SimpleNamespace(headers=(('Accept', 'application/json'),)) environ = { 'REQUEST_METHOD': 'GET', 'RAW_URI': '/my/path?foo=bar', 'PATH_INFO': '/my/path', 'QUERY_STRING': 'foo=bar', 'SERVER_PROTOCOL': 'HTTP/1.1', } logger = Logger(Config()) atoms = logger.atoms(response, request, environ, datetime.timedelta(seconds=1)) assert isinstance(atoms, dict) assert atoms['r'] == 'GET /my/path?foo=bar HTTP/1.1' assert atoms['m'] == 'GET' assert atoms['U'] == '/my/path' assert atoms['q'] == 'foo=bar' assert atoms['H'] == 'HTTP/1.1' assert atoms['b'] == '1024' assert atoms['B'] == 1024 assert atoms['{accept}i'] == 'application/json' assert atoms['{content-type}o'] == 'application/json'
def log(self, lvl, msg, *args, **kwargs): """Log a given statistic if metric, value and type are present """ try: extra = kwargs.get("extra", None) if extra is not None: metric = extra.get(METRIC_VAR, None) value = extra.get(VALUE_VAR, None) typ = extra.get(MTYPE_VAR, None) if metric and value and typ: if typ == GAUGE_TYPE: self.gauge(metric, value) elif typ == COUNTER_TYPE: self.increment(metric, value) elif typ == HISTOGRAM_TYPE: self.histogram(metric, value) else: pass # Log to parent logger only if there is something to say if msg: Logger.log(self, lvl, msg, *args, **kwargs) except Exception: Logger.warning(self, "Failed to log to statsd", exc_info=True)
def debug(self, msg, *args, **kwargs): Logger.debug(self, msg, *args, **kwargs)
def exception(self, msg, *args, **kwargs): Logger.exception(self, msg, *args, **kwargs) self.increment("gunicorn.log.exception", 1)
def warning(self, msg, *args, **kwargs): Logger.warning(self, msg, *args, **kwargs) self.increment("gunicorn.log.warning", 1)
def error(self, msg, *args, **kwargs): Logger.error(self, msg, *args, **kwargs) self.increment("gunicorn.log.error", 1)
def critical(self, msg, *args, **kwargs): Logger.critical(self, msg, *args, **kwargs) self.increment("gunicorn.log.critical", 1)
def log(self, lvl, msg, *args, **kwargs): Logger.log(self, lvl, msg, *args, **kwargs)
def __init__(self, cfg): Logger.__init__(self, cfg)