From 7dc398586c2156a456d9526ac0e42c1fec9f8143 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Wed, 28 Aug 2019 21:18:53 +1000 Subject: Implement a structured logging output system. (#5680) --- tox.ini | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tox.ini') diff --git a/tox.ini b/tox.ini index 09b4b8fc3c..f9a3b7e49a 100644 --- a/tox.ini +++ b/tox.ini @@ -146,3 +146,13 @@ commands = coverage combine coverage xml codecov -X gcov + +[testenv:mypy] +basepython = python3.5 +deps = + {[base]deps} + mypy +extras = all +commands = mypy --ignore-missing-imports \ + synapse/logging/_structured.py \ + synapse/logging/_terse_json.py \ No newline at end of file -- cgit 1.4.1 From e7011280c7796e437ba34ed97033b120b8556043 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Thu, 29 Aug 2019 22:19:57 +1000 Subject: Fix coverage in sytest and use plugins for buildkite (#5922) --- .buildkite/docker-compose.py35.pg95.yaml | 4 +- .buildkite/docker-compose.py37.pg11.yaml | 4 +- .buildkite/docker-compose.py37.pg95.yaml | 4 +- .buildkite/merge_base_branch.sh | 2 +- .buildkite/pipeline.yml | 84 +++++++++++++++++++++++++++----- .coveragerc | 3 +- changelog.d/5922.misc | 1 + tox.ini | 22 ++++----- 8 files changed, 92 insertions(+), 32 deletions(-) create mode 100644 changelog.d/5922.misc (limited to 'tox.ini') diff --git a/.buildkite/docker-compose.py35.pg95.yaml b/.buildkite/docker-compose.py35.pg95.yaml index aaea33006b..43237b7775 100644 --- a/.buildkite/docker-compose.py35.pg95.yaml +++ b/.buildkite/docker-compose.py35.pg95.yaml @@ -17,6 +17,6 @@ services: SYNAPSE_POSTGRES_HOST: postgres SYNAPSE_POSTGRES_USER: postgres SYNAPSE_POSTGRES_PASSWORD: postgres - working_dir: /app + working_dir: /src volumes: - - ..:/app + - ..:/src diff --git a/.buildkite/docker-compose.py37.pg11.yaml b/.buildkite/docker-compose.py37.pg11.yaml index 1b32675e78..b767228147 100644 --- a/.buildkite/docker-compose.py37.pg11.yaml +++ b/.buildkite/docker-compose.py37.pg11.yaml @@ -17,6 +17,6 @@ services: SYNAPSE_POSTGRES_HOST: postgres SYNAPSE_POSTGRES_USER: postgres SYNAPSE_POSTGRES_PASSWORD: postgres - working_dir: /app + working_dir: /src volumes: - - ..:/app + - ..:/src diff --git a/.buildkite/docker-compose.py37.pg95.yaml b/.buildkite/docker-compose.py37.pg95.yaml index 7679f6508d..02fcd28304 100644 --- a/.buildkite/docker-compose.py37.pg95.yaml +++ b/.buildkite/docker-compose.py37.pg95.yaml @@ -17,6 +17,6 @@ services: SYNAPSE_POSTGRES_HOST: postgres SYNAPSE_POSTGRES_USER: postgres SYNAPSE_POSTGRES_PASSWORD: postgres - working_dir: /app + working_dir: /src volumes: - - ..:/app + - ..:/src diff --git a/.buildkite/merge_base_branch.sh b/.buildkite/merge_base_branch.sh index 26176d6465..eb7219a56d 100755 --- a/.buildkite/merge_base_branch.sh +++ b/.buildkite/merge_base_branch.sh @@ -27,7 +27,7 @@ git config --global user.name "A robot" # Fetch and merge. If it doesn't work, it will raise due to set -e. git fetch -u origin $GITBASE -git merge --no-edit origin/$GITBASE +git merge --no-edit --no-commit origin/$GITBASE # Show what we are after. git --no-pager show -s diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index d9327227ed..d901849735 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -1,8 +1,7 @@ env: - CODECOV_TOKEN: "2dd7eb9b-0eda-45fe-a47c-9b5ac040045f" + COVERALLS_REPO_TOKEN: wsJWOby6j0uCYFiCes3r0XauxO27mx8lD steps: - - command: - "python -m pip install tox" - "tox -e check_codestyle" @@ -10,6 +9,7 @@ steps: plugins: - docker#v3.0.1: image: "python:3.6" + mount-buildkite-agent: false - command: - "python -m pip install tox" @@ -18,6 +18,7 @@ steps: plugins: - docker#v3.0.1: image: "python:3.6" + mount-buildkite-agent: false - command: - "python -m pip install tox" @@ -26,6 +27,7 @@ steps: plugins: - docker#v3.0.1: image: "python:3.6" + mount-buildkite-agent: false - command: - "python -m pip install tox" @@ -36,6 +38,7 @@ steps: - docker#v3.0.1: image: "python:3.6" propagate-environment: true + mount-buildkite-agent: false - command: - "python -m pip install tox" @@ -44,6 +47,7 @@ steps: plugins: - docker#v3.0.1: image: "python:3.6" + mount-buildkite-agent: false - command: - "python -m pip install tox" @@ -52,21 +56,26 @@ steps: plugins: - docker#v3.0.1: image: "python:3.5" + mount-buildkite-agent: false - wait - command: - "apt-get update && apt-get install -y python3.5 python3.5-dev python3-pip libxml2-dev libxslt-dev zlib1g-dev" - "python3.5 -m pip install tox" - - "tox -e py35-old,codecov" + - "tox -e py35-old,combine" label: ":python: 3.5 / SQLite / Old Deps" env: TRIAL_FLAGS: "-j 2" LANG: "C.UTF-8" plugins: - docker#v3.0.1: - image: "ubuntu:xenial" # We use xenail to get an old sqlite and python + image: "ubuntu:xenial" # We use xenial to get an old sqlite and python + workdir: "/src" + mount-buildkite-agent: false propagate-environment: true + - matrix-org/coveralls#v1.0: + parallel: "true" retry: automatic: - exit_status: -1 @@ -76,14 +85,18 @@ steps: - command: - "python -m pip install tox" - - "tox -e py35,codecov" + - "tox -e py35,combine" label: ":python: 3.5 / SQLite" env: TRIAL_FLAGS: "-j 2" plugins: - docker#v3.0.1: image: "python:3.5" + workdir: "/src" + mount-buildkite-agent: false propagate-environment: true + - matrix-org/coveralls#v1.0: + parallel: "true" retry: automatic: - exit_status: -1 @@ -93,14 +106,18 @@ steps: - command: - "python -m pip install tox" - - "tox -e py36,codecov" + - "tox -e py36,combine" label: ":python: 3.6 / SQLite" env: TRIAL_FLAGS: "-j 2" plugins: - docker#v3.0.1: image: "python:3.6" + workdir: "/src" + mount-buildkite-agent: false propagate-environment: true + - matrix-org/coveralls#v1.0: + parallel: "true" retry: automatic: - exit_status: -1 @@ -110,14 +127,18 @@ steps: - command: - "python -m pip install tox" - - "tox -e py37,codecov" + - "tox -e py37,combine" label: ":python: 3.7 / SQLite" env: TRIAL_FLAGS: "-j 2" plugins: - docker#v3.0.1: image: "python:3.7" + workdir: "/src" + mount-buildkite-agent: false propagate-environment: true + - matrix-org/coveralls#v1.0: + parallel: "true" retry: automatic: - exit_status: -1 @@ -131,12 +152,14 @@ steps: env: TRIAL_FLAGS: "-j 8" command: - - "bash -c 'python -m pip install tox && python -m tox -e py35-postgres,codecov'" + - "bash -c 'python -m pip install tox && python -m tox -e py35-postgres,combine'" plugins: - docker-compose#v2.1.0: run: testenv config: - .buildkite/docker-compose.py35.pg95.yaml + - matrix-org/coveralls#v1.0: + parallel: "true" retry: automatic: - exit_status: -1 @@ -150,12 +173,14 @@ steps: env: TRIAL_FLAGS: "-j 8" command: - - "bash -c 'python -m pip install tox && python -m tox -e py37-postgres,codecov'" + - "bash -c 'python -m pip install tox && python -m tox -e py37-postgres,combine'" plugins: - docker-compose#v2.1.0: run: testenv config: - .buildkite/docker-compose.py37.pg95.yaml + - matrix-org/coveralls#v1.0: + parallel: "true" retry: automatic: - exit_status: -1 @@ -169,12 +194,14 @@ steps: env: TRIAL_FLAGS: "-j 8" command: - - "bash -c 'python -m pip install tox && python -m tox -e py37-postgres,codecov'" + - "bash -c 'python -m pip install tox && python -m tox -e py37-postgres,combine'" plugins: - docker-compose#v2.1.0: run: testenv config: - .buildkite/docker-compose.py37.pg11.yaml + - matrix-org/coveralls#v1.0: + parallel: "true" retry: automatic: - exit_status: -1 @@ -182,7 +209,6 @@ steps: - exit_status: 2 limit: 2 - - label: "SyTest - :python: 3.5 / SQLite / Monolith" agents: queue: "medium" @@ -195,6 +221,16 @@ steps: propagate-environment: true always-pull: true workdir: "/src" + entrypoint: ["/bin/sh", "-e", "-c"] + mount-buildkite-agent: false + volumes: ["./logs:/logs"] + - artifacts#v1.2.0: + upload: [ "logs/**/*.log", "logs/**/*.log.*", "logs/coverage.xml" ] + - matrix-org/annotate: + path: "logs/annotate.md" + class: "error" + - matrix-org/coveralls#v1.0: + parallel: "true" retry: automatic: - exit_status: -1 @@ -216,6 +252,16 @@ steps: propagate-environment: true always-pull: true workdir: "/src" + entrypoint: ["/bin/sh", "-e", "-c"] + mount-buildkite-agent: false + volumes: ["./logs:/logs"] + - artifacts#v1.2.0: + upload: [ "logs/**/*.log", "logs/**/*.log.*", "logs/coverage.xml" ] + - matrix-org/annotate: + path: "logs/annotate.md" + class: "error" + - matrix-org/coveralls#v1.0: + parallel: "true" retry: automatic: - exit_status: -1 @@ -240,9 +286,25 @@ steps: propagate-environment: true always-pull: true workdir: "/src" + entrypoint: ["/bin/sh", "-e", "-c"] + mount-buildkite-agent: false + volumes: ["./logs:/logs"] + - artifacts#v1.2.0: + upload: [ "logs/**/*.log", "logs/**/*.log.*", "logs/coverage.xml" ] + - matrix-org/annotate: + path: "logs/annotate.md" + class: "error" + - matrix-org/coveralls#v1.0: + parallel: "true" retry: automatic: - exit_status: -1 limit: 2 - exit_status: 2 limit: 2 + + - wait: ~ + continue_on_failure: true + + - label: Trigger webhook + command: "curl -k https://coveralls.io/webhook?repo_token=$COVERALLS_REPO_TOKEN -d \"payload[build_num]=$BUILDKITE_BUILD_NUMBER&payload[status]=done\"" diff --git a/.coveragerc b/.coveragerc index e9460a340a..11f2ec8387 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,7 +1,8 @@ [run] branch = True parallel = True -include = synapse/* +include=$TOP/synapse/* +data_file = $TOP/.coverage [report] precision = 2 diff --git a/changelog.d/5922.misc b/changelog.d/5922.misc new file mode 100644 index 0000000000..2cc864897e --- /dev/null +++ b/changelog.d/5922.misc @@ -0,0 +1 @@ +Update Buildkite pipeline to use plugins instead of buildkite-agent commands. diff --git a/tox.ini b/tox.ini index f9a3b7e49a..7cb40847b5 100644 --- a/tox.ini +++ b/tox.ini @@ -7,6 +7,7 @@ deps = python-subunit junitxml coverage + coverage-enable-subprocess parameterized # cyptography 2.2 requires setuptools >= 18.5 @@ -43,13 +44,13 @@ whitelist_externals = setenv = {[base]setenv} postgres: SYNAPSE_POSTGRES = 1 + TOP={toxinidir} passenv = * commands = /usr/bin/find "{toxinidir}" -name '*.pyc' -delete # Add this so that coverage will run on subprocesses - sh -c 'echo "import coverage; coverage.process_startup()" > {envsitepackagesdir}/../sitecustomize.py' {envbindir}/coverage run "{envbindir}/trial" {env:TRIAL_FLAGS:} {posargs:tests} {env:TOXSUFFIX:} # As of twisted 16.4, trial tries to import the tests as a package (previously @@ -75,8 +76,6 @@ commands = # ) usedevelop=true - - # A test suite for the oldest supported versions of Python libraries, to catch # any uses of APIs not available in them. [testenv:py35-old] @@ -88,6 +87,7 @@ deps = mock lxml coverage + coverage-enable-subprocess commands = /usr/bin/find "{toxinidir}" -name '*.pyc' -delete @@ -96,15 +96,11 @@ commands = # OpenSSL 1.1 compiled cryptography (as older ones don't compile on Travis). /bin/sh -c 'python -m synapse.python_dependencies | sed -e "s/>=/==/g" -e "s/psycopg2==2.6//" -e "s/pyopenssl==16.0.0/pyopenssl==17.0.0/" | xargs -d"\n" pip install' - # Add this so that coverage will run on subprocesses - /bin/sh -c 'echo "import coverage; coverage.process_startup()" > {envsitepackagesdir}/../sitecustomize.py' - # Install Synapse itself. This won't update any libraries. pip install -e . {envbindir}/coverage run "{envbindir}/trial" {env:TRIAL_FLAGS:} {posargs:tests} {env:TOXSUFFIX:} - [testenv:packaging] skip_install=True deps = @@ -137,15 +133,15 @@ basepython = python3.6 [testenv:check-sampleconfig] commands = {toxinidir}/scripts-dev/generate_sample_config --check -[testenv:codecov] +[testenv:combine] skip_install = True deps = coverage - codecov -commands = +whitelist_externals = + bash +commands= coverage combine - coverage xml - codecov -X gcov + coverage report [testenv:mypy] basepython = python3.5 @@ -155,4 +151,4 @@ deps = extras = all commands = mypy --ignore-missing-imports \ synapse/logging/_structured.py \ - synapse/logging/_terse_json.py \ No newline at end of file + synapse/logging/_terse_json.py -- cgit 1.4.1 From b617864cd9f81109e818bc5ae95bee317d917b72 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Fri, 13 Sep 2019 02:29:55 +1000 Subject: Fix for structured logging tests stomping on logs (#6023) --- MANIFEST.in | 12 +++++---- changelog.d/6023.misc | 1 + mypy.ini | 54 ++++++++++++++++++++++++++++++++++++++++ synapse/config/logger.py | 33 ++++++++++++++++++------ synapse/logging/_structured.py | 8 +++--- synapse/logging/_terse_json.py | 8 +++--- synapse/logging/opentracing.py | 4 +-- synapse/metrics/__init__.py | 5 ++-- synapse/metrics/_exposition.py | 4 ++- synapse/python_dependencies.py | 7 +++--- tests/logging/test_structured.py | 25 ++++++++++++++++--- tests/logging/test_terse_json.py | 4 +-- tox.ini | 30 +++++++++++++++++----- 13 files changed, 154 insertions(+), 41 deletions(-) create mode 100644 changelog.d/6023.misc create mode 100644 mypy.ini (limited to 'tox.ini') diff --git a/MANIFEST.in b/MANIFEST.in index 919cd8a1cd..9c2902b8d2 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -38,14 +38,16 @@ exclude sytest-blacklist include pyproject.toml recursive-include changelog.d * -prune .github -prune demo/etc -prune docker +prune .buildkite prune .circleci +prune .codecov.yml prune .coveragerc +prune .github prune debian -prune .codecov.yml -prune .buildkite +prune demo/etc +prune docker +prune mypy.ini +prune stubs exclude jenkins* recursive-exclude jenkins *.sh diff --git a/changelog.d/6023.misc b/changelog.d/6023.misc new file mode 100644 index 0000000000..d80410c22c --- /dev/null +++ b/changelog.d/6023.misc @@ -0,0 +1 @@ +Fix the structured logging tests stomping on the global log configuration for subsequent tests. diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000000..8788574ee3 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,54 @@ +[mypy] +namespace_packages=True +plugins=mypy_zope:plugin +follow_imports=skip +mypy_path=stubs + +[mypy-synapse.config.homeserver] +# this is a mess because of the metaclass shenanigans +ignore_errors = True + +[mypy-zope] +ignore_missing_imports = True + +[mypy-constantly] +ignore_missing_imports = True + +[mypy-twisted.*] +ignore_missing_imports = True + +[mypy-treq.*] +ignore_missing_imports = True + +[mypy-hyperlink] +ignore_missing_imports = True + +[mypy-h11] +ignore_missing_imports = True + +[mypy-opentracing] +ignore_missing_imports = True + +[mypy-OpenSSL] +ignore_missing_imports = True + +[mypy-netaddr] +ignore_missing_imports = True + +[mypy-saml2.*] +ignore_missing_imports = True + +[mypy-unpaddedbase64] +ignore_missing_imports = True + +[mypy-canonicaljson] +ignore_missing_imports = True + +[mypy-jaeger_client] +ignore_missing_imports = True + +[mypy-jsonschema] +ignore_missing_imports = True + +[mypy-signedjson.*] +ignore_missing_imports = True diff --git a/synapse/config/logger.py b/synapse/config/logger.py index 2704c18720..767ecfdf09 100644 --- a/synapse/config/logger.py +++ b/synapse/config/logger.py @@ -21,7 +21,12 @@ from string import Template import yaml -from twisted.logger import STDLibLogObserver, globalLogBeginner +from twisted.logger import ( + ILogObserver, + LogBeginner, + STDLibLogObserver, + globalLogBeginner, +) import synapse from synapse.app import _base as appbase @@ -124,7 +129,7 @@ class LoggingConfig(Config): log_config_file.write(DEFAULT_LOG_CONFIG.substitute(log_file=log_file)) -def _setup_stdlib_logging(config, log_config): +def _setup_stdlib_logging(config, log_config, logBeginner: LogBeginner): """ Set up Python stdlib logging. """ @@ -165,12 +170,12 @@ def _setup_stdlib_logging(config, log_config): return observer(event) - globalLogBeginner.beginLoggingTo( - [_log], redirectStandardIO=not config.no_redirect_stdio - ) + logBeginner.beginLoggingTo([_log], redirectStandardIO=not config.no_redirect_stdio) if not config.no_redirect_stdio: print("Redirected stdout/stderr to logs") + return observer + def _reload_stdlib_logging(*args, log_config=None): logger = logging.getLogger("") @@ -181,7 +186,9 @@ def _reload_stdlib_logging(*args, log_config=None): logging.config.dictConfig(log_config) -def setup_logging(hs, config, use_worker_options=False): +def setup_logging( + hs, config, use_worker_options=False, logBeginner: LogBeginner = globalLogBeginner +) -> ILogObserver: """ Set up the logging subsystem. @@ -191,6 +198,12 @@ def setup_logging(hs, config, use_worker_options=False): use_worker_options (bool): True to use the 'worker_log_config' option instead of 'log_config'. + + logBeginner: The Twisted logBeginner to use. + + Returns: + The "root" Twisted Logger observer, suitable for sending logs to from a + Logger instance. """ log_config = config.worker_log_config if use_worker_options else config.log_config @@ -210,10 +223,12 @@ def setup_logging(hs, config, use_worker_options=False): log_config_body = read_config() if log_config_body and log_config_body.get("structured") is True: - setup_structured_logging(hs, config, log_config_body) + logger = setup_structured_logging( + hs, config, log_config_body, logBeginner=logBeginner + ) appbase.register_sighup(read_config, callback=reload_structured_logging) else: - _setup_stdlib_logging(config, log_config_body) + logger = _setup_stdlib_logging(config, log_config_body, logBeginner=logBeginner) appbase.register_sighup(read_config, callback=_reload_stdlib_logging) # make sure that the first thing we log is a thing we can grep backwards @@ -221,3 +236,5 @@ def setup_logging(hs, config, use_worker_options=False): logging.warn("***** STARTING SERVER *****") logging.warn("Server %s version %s", sys.argv[0], get_version_string(synapse)) logging.info("Server hostname: %s", config.server_name) + + return logger diff --git a/synapse/logging/_structured.py b/synapse/logging/_structured.py index 0367d6dfc4..3220e985a9 100644 --- a/synapse/logging/_structured.py +++ b/synapse/logging/_structured.py @@ -18,6 +18,7 @@ import os.path import sys import typing import warnings +from typing import List import attr from constantly import NamedConstant, Names, ValueConstant, Values @@ -33,7 +34,6 @@ from twisted.logger import ( LogLevelFilterPredicate, LogPublisher, eventAsText, - globalLogBeginner, jsonFileLogObserver, ) @@ -134,7 +134,7 @@ class PythonStdlibToTwistedLogger(logging.Handler): ) -def SynapseFileLogObserver(outFile: typing.io.TextIO) -> FileLogObserver: +def SynapseFileLogObserver(outFile: typing.IO[str]) -> FileLogObserver: """ A log observer that formats events like the traditional log formatter and sends them to `outFile`. @@ -265,7 +265,7 @@ def setup_structured_logging( hs, config, log_config: dict, - logBeginner: LogBeginner = globalLogBeginner, + logBeginner: LogBeginner, redirect_stdlib_logging: bool = True, ) -> LogPublisher: """ @@ -286,7 +286,7 @@ def setup_structured_logging( if "drains" not in log_config: raise ConfigError("The logging configuration requires a list of drains.") - observers = [] + observers = [] # type: List[ILogObserver] for observer in parse_drain_configs(log_config["drains"]): # Pipe drains diff --git a/synapse/logging/_terse_json.py b/synapse/logging/_terse_json.py index 7f1e8f23fe..0ebbde06f2 100644 --- a/synapse/logging/_terse_json.py +++ b/synapse/logging/_terse_json.py @@ -21,10 +21,11 @@ import sys from collections import deque from ipaddress import IPv4Address, IPv6Address, ip_address from math import floor -from typing.io import TextIO +from typing import IO import attr from simplejson import dumps +from zope.interface import implementer from twisted.application.internet import ClientService from twisted.internet.endpoints import ( @@ -33,7 +34,7 @@ from twisted.internet.endpoints import ( TCP6ClientEndpoint, ) from twisted.internet.protocol import Factory, Protocol -from twisted.logger import FileLogObserver, Logger +from twisted.logger import FileLogObserver, ILogObserver, Logger from twisted.python.failure import Failure @@ -129,7 +130,7 @@ def flatten_event(event: dict, metadata: dict, include_time: bool = False): return new_event -def TerseJSONToConsoleLogObserver(outFile: TextIO, metadata: dict) -> FileLogObserver: +def TerseJSONToConsoleLogObserver(outFile: IO[str], metadata: dict) -> FileLogObserver: """ A log observer that formats events to a flattened JSON representation. @@ -146,6 +147,7 @@ def TerseJSONToConsoleLogObserver(outFile: TextIO, metadata: dict) -> FileLogObs @attr.s +@implementer(ILogObserver) class TerseJSONToTCPLogObserver(object): """ An IObserver that writes JSON logs to a TCP target. diff --git a/synapse/logging/opentracing.py b/synapse/logging/opentracing.py index 7246253018..308a27213b 100644 --- a/synapse/logging/opentracing.py +++ b/synapse/logging/opentracing.py @@ -223,8 +223,8 @@ try: from jaeger_client import Config as JaegerConfig from synapse.logging.scopecontextmanager import LogContextScopeManager except ImportError: - JaegerConfig = None - LogContextScopeManager = None + JaegerConfig = None # type: ignore + LogContextScopeManager = None # type: ignore logger = logging.getLogger(__name__) diff --git a/synapse/metrics/__init__.py b/synapse/metrics/__init__.py index b5c9595cb9..bec3b13397 100644 --- a/synapse/metrics/__init__.py +++ b/synapse/metrics/__init__.py @@ -20,6 +20,7 @@ import os import platform import threading import time +from typing import Dict, Union import six @@ -42,9 +43,7 @@ logger = logging.getLogger(__name__) METRICS_PREFIX = "/_synapse/metrics" running_on_pypy = platform.python_implementation() == "PyPy" -all_metrics = [] -all_collectors = [] -all_gauges = {} +all_gauges = {} # type: Dict[str, Union[LaterGauge, InFlightGauge, BucketCollector]] HAVE_PROC_SELF_STAT = os.path.exists("/proc/self/stat") diff --git a/synapse/metrics/_exposition.py b/synapse/metrics/_exposition.py index 1933ecd3e3..74d9c3ecd3 100644 --- a/synapse/metrics/_exposition.py +++ b/synapse/metrics/_exposition.py @@ -36,7 +36,9 @@ from twisted.web.resource import Resource try: from prometheus_client.samples import Sample except ImportError: - Sample = namedtuple("Sample", ["name", "labels", "value", "timestamp", "exemplar"]) + Sample = namedtuple( + "Sample", ["name", "labels", "value", "timestamp", "exemplar"] + ) # type: ignore CONTENT_TYPE_LATEST = str("text/plain; version=0.0.4; charset=utf-8") diff --git a/synapse/python_dependencies.py b/synapse/python_dependencies.py index 07345e916a..0bd563edc7 100644 --- a/synapse/python_dependencies.py +++ b/synapse/python_dependencies.py @@ -15,6 +15,7 @@ # limitations under the License. import logging +from typing import Set from pkg_resources import ( DistributionNotFound, @@ -97,7 +98,7 @@ CONDITIONAL_REQUIREMENTS = { "jwt": ["pyjwt>=1.6.4"], } -ALL_OPTIONAL_REQUIREMENTS = set() +ALL_OPTIONAL_REQUIREMENTS = set() # type: Set[str] for name, optional_deps in CONDITIONAL_REQUIREMENTS.items(): # Exclude systemd as it's a system-based requirement. @@ -174,8 +175,8 @@ def check_requirements(for_feature=None): pass if deps_needed: - for e in errors: - logging.error(e) + for err in errors: + logging.error(err) raise DependencyException(deps_needed) diff --git a/tests/logging/test_structured.py b/tests/logging/test_structured.py index a786de0233..451d05c0f0 100644 --- a/tests/logging/test_structured.py +++ b/tests/logging/test_structured.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import logging import os import os.path import shutil @@ -33,7 +34,20 @@ class FakeBeginner(object): self.observers = observers -class StructuredLoggingTestCase(HomeserverTestCase): +class StructuredLoggingTestBase(object): + """ + Test base that registers a cleanup handler to reset the stdlib log handler + to 'unset'. + """ + + def prepare(self, reactor, clock, hs): + def _cleanup(): + logging.getLogger("synapse").setLevel(logging.NOTSET) + + self.addCleanup(_cleanup) + + +class StructuredLoggingTestCase(StructuredLoggingTestBase, HomeserverTestCase): """ Tests for Synapse's structured logging support. """ @@ -139,7 +153,9 @@ class StructuredLoggingTestCase(HomeserverTestCase): self.assertEqual(logs[0]["request"], "somereq") -class StructuredLoggingConfigurationFileTestCase(HomeserverTestCase): +class StructuredLoggingConfigurationFileTestCase( + StructuredLoggingTestBase, HomeserverTestCase +): def make_homeserver(self, reactor, clock): tempdir = self.mktemp() @@ -179,10 +195,11 @@ class StructuredLoggingConfigurationFileTestCase(HomeserverTestCase): """ When a structured logging config is given, Synapse will use it. """ - setup_logging(self.hs, self.hs.config) + beginner = FakeBeginner() + publisher = setup_logging(self.hs, self.hs.config, logBeginner=beginner) # Make a logger and send an event - logger = Logger(namespace="tests.logging.test_structured") + logger = Logger(namespace="tests.logging.test_structured", observer=publisher) with LoggingContext("testcontext", request="somereq"): logger.info("Hello there, {name}!", name="steve") diff --git a/tests/logging/test_terse_json.py b/tests/logging/test_terse_json.py index 514282591d..4cf81f7128 100644 --- a/tests/logging/test_terse_json.py +++ b/tests/logging/test_terse_json.py @@ -23,10 +23,10 @@ from synapse.logging._structured import setup_structured_logging from tests.server import connect_client from tests.unittest import HomeserverTestCase -from .test_structured import FakeBeginner +from .test_structured import FakeBeginner, StructuredLoggingTestBase -class TerseJSONTCPTestCase(HomeserverTestCase): +class TerseJSONTCPTestCase(StructuredLoggingTestBase, HomeserverTestCase): def test_log_output(self): """ The Terse JSON outputter delivers simplified structured logs over TCP. diff --git a/tox.ini b/tox.ini index 7cb40847b5..1bce10a4ce 100644 --- a/tox.ini +++ b/tox.ini @@ -2,6 +2,7 @@ envlist = packaging, py35, py36, py37, check_codestyle, check_isort [base] +basepython = python3.7 deps = mock python-subunit @@ -137,18 +138,35 @@ commands = {toxinidir}/scripts-dev/generate_sample_config --check skip_install = True deps = coverage -whitelist_externals = - bash commands= coverage combine coverage report +[testenv:cov-erase] +skip_install = True +deps = + coverage +commands= + coverage erase + +[testenv:cov-html] +skip_install = True +deps = + coverage +commands= + coverage html + [testenv:mypy] -basepython = python3.5 +basepython = python3.7 +skip_install = True deps = {[base]deps} mypy + mypy-zope + typeshed +env = + MYPYPATH = stubs/ extras = all -commands = mypy --ignore-missing-imports \ - synapse/logging/_structured.py \ - synapse/logging/_terse_json.py +commands = mypy --show-traceback \ + synapse/logging/ \ + synapse/config/ -- cgit 1.4.1