Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static checks #34

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
repos:
- repo: git://github.com/pre-commit/pre-commit-hooks
rev: v1.3.0
hooks:
- id: trailing-whitespace
- id: check-ast
- id: check-merge-conflict
- id: flake8
- repo: https://github.com/asottile/seed-isort-config
rev: v1.8.0
hooks:
- id: seed-isort-config
- repo: https://github.com/pre-commit/mirrors-isort
rev: v4.3.17
hooks:
- id: isort
- repo: https://github.com/ambv/black
rev: 19.3b0
hooks:
- id: black
8 changes: 7 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ before_install:
- docker run -d --rm -p 15672:15672 -p 5672:5672 -p 5671:5671 --name nameko-rabbitmq nameko/nameko-rabbitmq:3.6.6

stages:
- static
- test

jobs:
Expand All @@ -29,6 +30,11 @@ jobs:
env: DEPS="nameko>=2.12.0"
- python: 3.5
env: DEPS="nameko>=2.12.0"
- python: 3.6
stage: static
install: pip install pre-commit
script: make static
env:

matrix:
allow_failures:
Expand All @@ -41,7 +47,7 @@ install:
- pip install -U $DEPS

script:
- make test
- make pytest

deploy:
- provider: pypi
Expand Down
9 changes: 3 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
test: flake8 pylint pytest
test: static pytest

flake8:
flake8 nameko_tracer tests

pylint:
pylint nameko_tracer -E
static:
pre-commit run --all-files

pytest:
coverage run --concurrency=eventlet --source nameko_tracer --branch -m pytest tests
Expand Down
99 changes: 47 additions & 52 deletions nameko_tracer/adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import logging
from traceback import format_exception

import six
from nameko.exceptions import get_module_path
from nameko.utils import get_redacted_args
import six
from werkzeug.wrappers import Response

from nameko_tracer import constants, utils
Expand All @@ -14,7 +14,6 @@


class DefaultAdapter(logging.LoggerAdapter):

def process(self, message, kwargs):
""" Extract useful entrypoint processing information

Expand All @@ -26,24 +25,23 @@ def process(self, message, kwargs):

"""

hostname = self.extra['hostname']
hostname = self.extra["hostname"]

stage = kwargs['extra']['stage']
worker_ctx = kwargs['extra']['worker_ctx']
timestamp = kwargs['extra']['timestamp']
stage = kwargs["extra"]["stage"]
worker_ctx = kwargs["extra"]["worker_ctx"]
timestamp = kwargs["extra"]["timestamp"]

entrypoint = worker_ctx.entrypoint

data = kwargs['extra'].get(constants.TRACE_KEY, {})
data = kwargs["extra"].get(constants.TRACE_KEY, {})

data[constants.TIMESTAMP_KEY] = timestamp
data[constants.HOSTNAME_KEY] = hostname
data[constants.SERVICE_NAME_KEY] = worker_ctx.service_name
data[constants.ENTRYPOINT_TYPE_KEY] = type(entrypoint).__name__
data[constants.ENTRYPOINT_NAME_KEY] = entrypoint.method_name

data[constants.CONTEXT_DATA_KEY] = utils.safe_for_serialisation(
worker_ctx.data)
data[constants.CONTEXT_DATA_KEY] = utils.safe_for_serialisation(worker_ctx.data)

data[constants.CALL_ID_KEY] = worker_ctx.call_id
data[constants.CALL_ID_STACK_KEY] = worker_ctx.call_id_stack
Expand All @@ -57,22 +55,19 @@ def process(self, message, kwargs):

if stage == constants.Stage.response:

exc_info = kwargs['extra']['exc_info_']
exc_info = kwargs["extra"]["exc_info_"]

if exc_info:
data[constants.RESPONSE_STATUS_KEY] = (
constants.Status.error.value)
data[constants.RESPONSE_STATUS_KEY] = constants.Status.error.value
self.set_exception(data, worker_ctx, exc_info)
else:
data[constants.RESPONSE_STATUS_KEY] = (
constants.Status.success.value)
result = kwargs['extra']['result']
data[constants.RESPONSE_STATUS_KEY] = constants.Status.success.value
result = kwargs["extra"]["result"]
data[constants.RESPONSE_KEY] = self.get_result(result)

data[constants.RESPONSE_TIME_KEY] = (
kwargs['extra']['response_time'])
data[constants.RESPONSE_TIME_KEY] = kwargs["extra"]["response_time"]

kwargs['extra'][constants.TRACE_KEY] = data
kwargs["extra"][constants.TRACE_KEY] = data

return message, kwargs

Expand All @@ -82,20 +77,21 @@ def get_call_args(self, worker_ctx):

entrypoint = worker_ctx.entrypoint

if getattr(entrypoint, 'sensitive_variables', None):
if getattr(entrypoint, "sensitive_variables", None):
# backwards compatibility with nameko < 2.7.0
entrypoint.sensitive_arguments = entrypoint.sensitive_variables

if getattr(entrypoint, 'sensitive_arguments', None):
if getattr(entrypoint, "sensitive_arguments", None):
call_args = get_redacted_args(
entrypoint, *worker_ctx.args, **worker_ctx.kwargs)
entrypoint, *worker_ctx.args, **worker_ctx.kwargs
)
redacted = True
else:
method = getattr(
entrypoint.container.service_cls, entrypoint.method_name)
method = getattr(entrypoint.container.service_cls, entrypoint.method_name)
call_args = inspect.getcallargs(
method, None, *worker_ctx.args, **worker_ctx.kwargs)
del call_args['self']
method, None, *worker_ctx.args, **worker_ctx.kwargs
)
del call_args["self"]
redacted = False

return call_args, redacted
Expand All @@ -112,14 +108,15 @@ def set_exception(self, data, worker_ctx, exc_info):
exc_type, exc, _ = exc_info

expected_exceptions = getattr(
worker_ctx.entrypoint, 'expected_exceptions', None)
worker_ctx.entrypoint, "expected_exceptions", None
)
expected_exceptions = expected_exceptions or tuple()
is_expected = isinstance(exc, expected_exceptions)

try:
exc_traceback = ''.join(format_exception(*exc_info))
exc_traceback = "".join(format_exception(*exc_info))
except Exception:
exc_traceback = 'traceback serialisation failed'
exc_traceback = "traceback serialisation failed"

exc_args = utils.safe_for_serialisation(exc.args)

Expand All @@ -132,27 +129,26 @@ def set_exception(self, data, worker_ctx, exc_info):


class HttpRequestHandlerAdapter(DefaultAdapter):

def get_call_args(self, worker_ctx):
""" Transform request object to serialized dictionary
"""

entrypoint = worker_ctx.entrypoint

method = getattr(
entrypoint.container.service_cls, entrypoint.method_name)
method = getattr(entrypoint.container.service_cls, entrypoint.method_name)
call_args = inspect.getcallargs(
method, None, *worker_ctx.args, **worker_ctx.kwargs)
del call_args['self']
method, None, *worker_ctx.args, **worker_ctx.kwargs
)
del call_args["self"]

request = call_args.pop('request')
request = call_args.pop("request")
data = request.data or request.form
call_args['request'] = {
'url': request.url,
'method': request.method,
'data': utils.safe_for_serialisation(data),
'headers': dict(self.get_headers(request.environ)),
'env': dict(self.get_environ(request.environ)),
call_args["request"] = {
"url": request.url,
"method": request.method,
"data": utils.safe_for_serialisation(data),
"headers": dict(self.get_headers(request.environ)),
"env": dict(self.get_environ(request.environ)),
}

return call_args, False
Expand All @@ -170,32 +166,31 @@ def get_result(self, result):
payload = result
status = 200

result = Response(
payload,
status=status,
)
result = Response(payload, status=status)

return {
'content_type': result.content_type,
'data': result.get_data(),
'status_code': result.status_code,
'content_length': result.content_length,
"content_type": result.content_type,
"data": result.get_data(),
"status_code": result.status_code,
"content_length": result.content_length,
}

def get_headers(self, environ):
""" Return only proper HTTP headers
"""
for key, value in six.iteritems(environ):
key = str(key)
if key.startswith('HTTP_') and key not in \
('HTTP_CONTENT_TYPE', 'HTTP_CONTENT_LENGTH'):
if key.startswith("HTTP_") and key not in (
"HTTP_CONTENT_TYPE",
"HTTP_CONTENT_LENGTH",
):
yield key[5:].lower(), str(value)
elif key in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
elif key in ("CONTENT_TYPE", "CONTENT_LENGTH"):
yield key.lower(), str(value)

def get_environ(self, environ):
""" Return white-listed environment variables
"""
for key in ('REMOTE_ADDR', 'SERVER_NAME', 'SERVER_PORT'):
for key in ("REMOTE_ADDR", "SERVER_NAME", "SERVER_PORT"):
if key in environ:
yield key.lower(), str(environ[key])
Loading