diff --git a/.flake8 b/.flake8 index be591a55..a8973037 100644 --- a/.flake8 +++ b/.flake8 @@ -1,4 +1,4 @@ [flake8] max-line-length = 100 -exclude = bin/,.tox/,examples/,.github/,dist/,build/,htmlcov/ +exclude = bin/,.tox/,examples/,.github/,dist/,build/,htmlcov/,.venv/ ignore = W605,F401 diff --git a/Dockerfile b/Dockerfile index b91f3957..ba090576 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ RUN mkdir packages \ # # RELEASE STAGE # -FROM vaporio/python:3.9-slim +FROM vaporio/python:3.9 LABEL org.opencontainers.image.title="Synse Server" \ org.opencontainers.image.source="https://github.com/vapor-ware/synse-server" \ @@ -32,12 +32,16 @@ RUN groupadd -g 51453 synse \ && useradd -u 51453 -g 51453 synse RUN apt-get update && apt-get install -y --no-install-recommends \ - tini curl \ + curl \ && rm -rf /var/lib/apt/lists/* \ && mkdir -p /synse \ && mkdir -p /etc/synse \ - && chown -R synse:synse /synse \ - && chown -R synse:synse /etc/synse + && chown -R synse:synse /synse /etc/synse + +# PYTHONUNBUFFERED: allow stdin, stdout, and stderr to be totally unbuffered. +# This is required so that the container logs are rendered as they are logged into +# `docker logs`. +ENV PYTHONUNBUFFERED=1 COPY --from=builder /build/dist/synse-server-*.tar.gz /synse/synse-server.tar.gz COPY --from=builder /build/packages /pip-packages @@ -51,4 +55,4 @@ RUN pip install --no-index --find-links=/pip-packages /pip-packages/* \ USER synse -ENTRYPOINT ["/usr/bin/tini", "--", "synse_server"] +ENTRYPOINT ["synse_server"] diff --git a/Makefile b/Makefile index 17738aee..91e65cbe 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ lint: ## Run linting checks on the project source code (isort, flake8, twine) poetry check test: ## Run the unit tests - poetry run pytest -s -vv --cov-report html --cov-report term-missing --cov synse_server + poetry run pytest --disable-warnings -s -vv --cov-report html --cov-report term-missing --cov synse_server version: ## Print the version of Synse Server @echo "${PKG_VERSION}" diff --git a/docker-compose.yml b/docker-compose.yml index 037b3f38..ec089ed2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,6 @@ services: ports: - '5000:5000' environment: - SYNSE_LOGGING: debug SYNSE_PLUGIN_TCP: emulator-plugin:5001 SYNSE_METRICS_ENABLED: 'true' links: diff --git a/poetry.lock b/poetry.lock index 73d9c462..6f8b36a3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -172,6 +172,14 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "containerlog" +version = "0.4.2" +description = "Optimized, opinionated structured logging for Python" +category = "main" +optional = false +python-versions = ">=3.6.1,<4.0.0" + [[package]] name = "coverage" version = "5.5" @@ -778,22 +786,6 @@ category = "dev" optional = false python-versions = ">=3.5" -[[package]] -name = "structlog" -version = "21.1.0" -description = "Structured Logging for Python" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} - -[package.extras] -dev = ["coverage", "freezegun (>=0.2.8)", "pretend", "pytest-asyncio", "pytest-randomly", "pytest (>=6.0)", "simplejson", "furo", "sphinx", "sphinx-toolbox", "twisted", "pre-commit"] -docs = ["furo", "sphinx", "sphinx-toolbox", "twisted"] -tests = ["coverage", "freezegun (>=0.2.8)", "pretend", "pytest-asyncio", "pytest-randomly", "pytest (>=6.0)", "simplejson"] - [[package]] name = "synse-grpc" version = "3.1.0" @@ -831,7 +823,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" name = "typing-extensions" version = "3.10.0.0" description = "Backported and Experimental Type Hints for Python 3.5+" -category = "main" +category = "dev" optional = false python-versions = "*" @@ -933,7 +925,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "d39c7ee3128e9c29b0447f72bebeac3d6d09f61ca886e3a621bcfb709fc89c13" +content-hash = "d19cfdac1b34fa744f05a944172a78f5d9ef7dcef848e41c09253eba2de849aa" [metadata.files] aiocache = [ @@ -1035,6 +1027,10 @@ colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] +containerlog = [ + {file = "containerlog-0.4.2-py3-none-any.whl", hash = "sha256:71f3b29aff051bbf290aba10e1d19e08587b659ebef6581a709a66cc4322aa9a"}, + {file = "containerlog-0.4.2.tar.gz", hash = "sha256:bb18dbb6b7dd4dad6a51c307071d881f5dfc2470f1742e79fb18d749a325d671"}, +] coverage = [ {file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"}, {file = "coverage-5.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b"}, @@ -1450,10 +1446,6 @@ sniffio = [ {file = "sniffio-1.2.0-py3-none-any.whl", hash = "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663"}, {file = "sniffio-1.2.0.tar.gz", hash = "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"}, ] -structlog = [ - {file = "structlog-21.1.0-py2.py3-none-any.whl", hash = "sha256:62f06fc0ee32fb8580f0715eea66cb87271eb7efb0eaf9af6b639cba8981de47"}, - {file = "structlog-21.1.0.tar.gz", hash = "sha256:d9d2d890532e8db83c6977a2a676fb1889922ff0c26ad4dc0ecac26f9fafbc57"}, -] synse-grpc = [ {file = "synse_grpc-3.1.0-py2.py3-none-any.whl", hash = "sha256:9c63b425722d66d1b53a84dda0d45fac5c4b07e98eea93fd18583b1f347623ef"}, {file = "synse_grpc-3.1.0.tar.gz", hash = "sha256:01c313bb440b4e9289458f2a4e92a6d5ac4fcb65108f0f38e4817655269bf085"}, diff --git a/pyproject.toml b/pyproject.toml index b6d6c738..fb979281 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,9 +18,9 @@ PyYAML = "^5.4.1" sanic = "^21.6.2" prometheus-client = "^0.11.0" shortuuid = "^1.0.1" -structlog = "^21.1.0" websockets = "^9.1" synse-grpc = "3.1.0" +containerlog = "^0.4.2" [tool.poetry.dev-dependencies] aiohttp = "^3.7.4" diff --git a/synse_server/api/http.py b/synse_server/api/http.py index 1e9502ce..93023706 100644 --- a/synse_server/api/http.py +++ b/synse_server/api/http.py @@ -1,10 +1,10 @@ """Synse Server HTTP API.""" import ujson +from containerlog import get_logger from sanic import Blueprint from sanic.request import Request from sanic.response import HTTPResponse, StreamingHTTPResponse, stream -from structlog import get_logger from synse_server import cmd, errors, plugin, utils diff --git a/synse_server/api/websocket.py b/synse_server/api/websocket.py index 0c40c8e1..81eac654 100644 --- a/synse_server/api/websocket.py +++ b/synse_server/api/websocket.py @@ -5,10 +5,10 @@ import time from typing import Any, Dict, List, Union +from containerlog import get_logger from sanic import Blueprint from sanic.request import Request from sanic.websocket import ConnectionClosed -from structlog import get_logger from websockets import WebSocketCommonProtocol from synse_server import cmd, errors, utils diff --git a/synse_server/app.py b/synse_server/app.py index ab46988c..b747049e 100644 --- a/synse_server/app.py +++ b/synse_server/app.py @@ -1,27 +1,27 @@ """Factory for creating Synse Server Sanic application instances.""" import shortuuid -import structlog +from containerlog import contextvars, get_logger from sanic import Sanic from sanic.request import Request from sanic.response import HTTPResponse -from structlog import contextvars from synse_server import errors from synse_server.api import http, websocket -logger = structlog.get_logger() +logger = get_logger() def on_request(request: Request) -> None: """Middleware function that runs prior to processing a request via Sanic.""" + # Generate a unique request ID and use it as a field in any logging that # takes place during the request handling. req_id = shortuuid.uuid() request.ctx.uuid = req_id - contextvars.clear_contextvars() - contextvars.bind_contextvars( + contextvars.clear() + contextvars.bind( request_id=req_id, ) @@ -53,7 +53,7 @@ def on_response(request: Request, response: HTTPResponse) -> None: ) # Unbind the request ID from the logger. - contextvars.unbind_contextvars( + contextvars.unbind( 'request_id', ) diff --git a/synse_server/cache.py b/synse_server/cache.py index 8f2d2800..340b06a9 100644 --- a/synse_server/cache.py +++ b/synse_server/cache.py @@ -6,7 +6,7 @@ import aiocache import grpc import synse_grpc.utils -from structlog import get_logger +from containerlog import get_logger from synse_grpc import api from synse_server import loop, plugin diff --git a/synse_server/cmd/config.py b/synse_server/cmd/config.py index 9f0370d7..2bff2588 100644 --- a/synse_server/cmd/config.py +++ b/synse_server/cmd/config.py @@ -1,7 +1,7 @@ from typing import Any, Dict -from structlog import get_logger +from containerlog import get_logger from synse_server.config import options diff --git a/synse_server/cmd/info.py b/synse_server/cmd/info.py index c17afa66..2a6e8b0d 100644 --- a/synse_server/cmd/info.py +++ b/synse_server/cmd/info.py @@ -1,7 +1,7 @@ from typing import Any, Dict -from structlog import get_logger +from containerlog import get_logger from synse_grpc import utils from synse_server import cache, errors diff --git a/synse_server/cmd/plugin.py b/synse_server/cmd/plugin.py index 0c8cdb25..2faa703f 100644 --- a/synse_server/cmd/plugin.py +++ b/synse_server/cmd/plugin.py @@ -1,7 +1,7 @@ from typing import Any, Dict, List -from structlog import get_logger +from containerlog import get_logger from synse_grpc import api, utils import synse_server.utils diff --git a/synse_server/cmd/read.py b/synse_server/cmd/read.py index a6a6fd39..0d85d01b 100644 --- a/synse_server/cmd/read.py +++ b/synse_server/cmd/read.py @@ -8,7 +8,7 @@ import synse_grpc.utils import websockets -from structlog import get_logger +from containerlog import get_logger from synse_grpc import api from synse_server import cache, errors, plugin diff --git a/synse_server/cmd/scan.py b/synse_server/cmd/scan.py index 80d0dab4..4a64f3e3 100644 --- a/synse_server/cmd/scan.py +++ b/synse_server/cmd/scan.py @@ -1,7 +1,7 @@ from typing import Any, Dict, List -from structlog import get_logger +from containerlog import get_logger from synse_grpc import utils from synse_server import cache, errors @@ -68,7 +68,7 @@ async def scan( try: device_group = await cache.get_devices(*group) except Exception as e: - logger.exception(e) + logger.exception(str(e)) raise errors.ServerError('failed to get devices from cache') from e for device in device_group: diff --git a/synse_server/cmd/tags.py b/synse_server/cmd/tags.py index 62833c31..f37854f5 100644 --- a/synse_server/cmd/tags.py +++ b/synse_server/cmd/tags.py @@ -1,7 +1,7 @@ from typing import List -from structlog import get_logger +from containerlog import get_logger from synse_server import cache diff --git a/synse_server/cmd/test.py b/synse_server/cmd/test.py index a2086099..d08aa25e 100644 --- a/synse_server/cmd/test.py +++ b/synse_server/cmd/test.py @@ -1,7 +1,7 @@ from typing import Dict -from structlog import get_logger +from containerlog import get_logger from synse_server import utils diff --git a/synse_server/cmd/transaction.py b/synse_server/cmd/transaction.py index e280dca0..c0196e18 100644 --- a/synse_server/cmd/transaction.py +++ b/synse_server/cmd/transaction.py @@ -2,7 +2,7 @@ from typing import Any, Dict, List import synse_grpc.utils -from structlog import get_logger +from containerlog import get_logger from synse_server import cache, errors, plugin, utils diff --git a/synse_server/cmd/version.py b/synse_server/cmd/version.py index 1aea1c96..67b6814c 100644 --- a/synse_server/cmd/version.py +++ b/synse_server/cmd/version.py @@ -1,7 +1,7 @@ from typing import Dict -from structlog import get_logger +from containerlog import get_logger import synse_server diff --git a/synse_server/cmd/write.py b/synse_server/cmd/write.py index 9bfe4858..10bf939c 100644 --- a/synse_server/cmd/write.py +++ b/synse_server/cmd/write.py @@ -1,7 +1,7 @@ from typing import Any, Dict, List, Union -from structlog import get_logger +from containerlog import get_logger from synse_grpc import utils as grpc_utils from synse_server import cache, errors, utils diff --git a/synse_server/config.py b/synse_server/config.py index a0f8a658..1e08671a 100644 --- a/synse_server/config.py +++ b/synse_server/config.py @@ -4,7 +4,11 @@ # The Synse Server configuration scheme scheme = Scheme( + # DEPRECATED: no longer supporting logging in this format. This will + # be removed by upcoming release. Option('logging', default='debug', choices=['debug', 'info', 'warning', 'error', 'critical']), + + Option('debug', default=True, field_type=bool), Option('pretty_json', default=True, field_type=bool), DictOption('plugin', default={}, scheme=Scheme( ListOption('tcp', default=[], member_type=str, bind_env=True), diff --git a/synse_server/discovery/kubernetes.py b/synse_server/discovery/kubernetes.py index cb5cc893..2ecfe17b 100644 --- a/synse_server/discovery/kubernetes.py +++ b/synse_server/discovery/kubernetes.py @@ -4,7 +4,7 @@ import kubernetes.client import kubernetes.config -from structlog import get_logger +from containerlog import get_logger from synse_server import config diff --git a/synse_server/errors.py b/synse_server/errors.py index 43731a7f..7a596734 100644 --- a/synse_server/errors.py +++ b/synse_server/errors.py @@ -1,10 +1,10 @@ """Error definitions for Synse Server.""" +from containerlog import get_logger from sanic.exceptions import SanicException from sanic.handlers import ErrorHandler from sanic.request import Request from sanic.response import HTTPResponse -from structlog import get_logger from synse_server import utils diff --git a/synse_server/log.py b/synse_server/log.py deleted file mode 100644 index 551197c2..00000000 --- a/synse_server/log.py +++ /dev/null @@ -1,97 +0,0 @@ -"""Synse Server application logging.""" - -import logging -import logging.config -import sys - -import structlog -from sanic import app, asgi, handlers, request, server -from structlog import contextvars - -from synse_server import config - -logging_config = { - 'version': 1, - 'disable_existing_loggers': False, - 'loggers': { - 'root': { - 'level': 'INFO', - 'handlers': ['default'], - }, - 'synse_server': { - 'level': 'INFO', - 'handlers': ['default'], - 'propagate': True, - }, - 'sanic.root': { - 'level': 'INFO', - 'handlers': ['default'], - }, - 'sanic.error': { - 'level': 'INFO', - 'handlers': ['error'], - 'propagate': True, - 'qualname': 'sanic.error', - }, - }, - 'handlers': { - 'default': { - 'class': 'logging.StreamHandler', - 'stream': sys.stdout, - }, - 'error': { - 'class': 'logging.StreamHandler', - 'stream': sys.stderr, - }, - }, -} - -logging.config.dictConfig(logging_config) - -structlog.configure( - processors=[ - contextvars.merge_contextvars, - structlog.stdlib.filter_by_level, - structlog.stdlib.add_logger_name, - structlog.stdlib.add_log_level, - structlog.stdlib.PositionalArgumentsFormatter(), - structlog.processors.TimeStamper(fmt='iso'), - structlog.processors.StackInfoRenderer(), - structlog.processors.format_exc_info, - structlog.processors.UnicodeDecoder(), - structlog.processors.KeyValueRenderer( - key_order=['timestamp', 'logger', 'level', 'event'] - ), - ], - context_class=dict, - logger_factory=structlog.stdlib.LoggerFactory(), - wrapper_class=structlog.stdlib.BoundLogger, - cache_logger_on_first_use=True, -) - - -def override_sanic_loggers(): - # Override Sanic loggers with structlog loggers. Unfortunately - # there isn't a great way of doing this because the Sanic modules - # already hold a reference to the logging.Logger at import load, - # so we are stuck with just replacing those references in their - # respective modules. - root = structlog.get_logger('sanic.root') - error = structlog.get_logger('sanic.error') - - app.error_logger = error - app.logger = root - asgi.logger = root - handlers.logger = root - request.logger = root - request.error_logger = error - server.logger = root - - -override_sanic_loggers() - - -def setup_logger() -> None: - """Configure the Synse Server logger.""" - level = logging.getLevelName(config.options.get('logging', 'info').upper()) - structlog.get_logger('synse_server').setLevel(level) diff --git a/synse_server/plugin.py b/synse_server/plugin.py index 1f27050d..f37aca22 100644 --- a/synse_server/plugin.py +++ b/synse_server/plugin.py @@ -4,7 +4,7 @@ import time from typing import Dict, List, Optional, Tuple, Union -from structlog import get_logger +from containerlog import contextvars, get_logger from synse_grpc import client, utils from synse_server import backoff, config, errors, loop @@ -466,30 +466,32 @@ async def _reconnect(self): of a failure to connect with the plugin. """ start = time.time() - _l = logger.bind(plugin=self.id) - _l.info('starting plugin reconnect task') + contextvars.bind(plugin=self.id) + logger.info('starting plugin reconnect task') bo = backoff.ExponentialBackoff() + try: + while True: + logger.debug('plugin reconnect task: attempting reconnect') + try: + self.client.test() + except Exception as ex: + logger.info('plugin reconnect task: failed to reconnect to plugin', error=ex) + # The plugin should still be in the inactive state, but we re-set + # it here to ensure it is true. + self.mark_inactive() + else: + self.mark_active() + logger.info( + 'plugin reconnect task: established connection with plugin', + total_time=time.time() - start, + ) + return - while True: - _l.debug('plugin reconnect task: attempting reconnect') - try: - self.client.test() - except Exception as ex: - _l.info('plugin reconnect task: failed to reconnect to plugin', error=ex) - # The plugin should still be in the inactive state, but we re-set - # it here to ensure it is true. - self.mark_inactive() - else: - self.mark_active() - _l.info( - 'plugin reconnect task: established connection with plugin', - total_time=time.time() - start, - ) - return - - delay = bo.delay() - _l.debug('plugin reconnect task: waiting until next retry', delay=delay) - await asyncio.sleep(delay) + delay = bo.delay() + logger.debug('plugin reconnect task: waiting until next retry', delay=delay) + await asyncio.sleep(delay) + finally: + contextvars.unbind('plugin_id') def refresh_state(self): """Refresh the state of the plugin. @@ -508,21 +510,24 @@ def refresh_state(self): also refreshes the state of each existing individual plugin to ensure that its active/inactive state is up-to-date. """ - _l = logger.bind(plugin=self.id) - _l.info('refreshing plugin state') - - if self.disabled: - _l.info('plugin is disabled, will not refresh') - return + contextvars.bind(plugin=self.id) + logger.info('refreshing plugin state') try: - self.client.test() - except Exception as ex: - _l.debug('plugin refresh: failed to connect to plugin', errror=ex) - self.mark_inactive() - else: - _l.debug('plugin refresh: successfully connected to plugin') - self.mark_active() + if self.disabled: + logger.info('plugin is disabled, will not refresh') + return + + try: + self.client.test() + except Exception as ex: + logger.debug('plugin refresh: failed to connect to plugin', errror=ex) + self.mark_inactive() + else: + logger.debug('plugin refresh: successfully connected to plugin') + self.mark_active() + finally: + contextvars.unbind('plugin') def is_ready(self): """Check whether the plugin is ready to communicate with. diff --git a/synse_server/server.py b/synse_server/server.py index 7951e5d2..ec8b6523 100644 --- a/synse_server/server.py +++ b/synse_server/server.py @@ -9,13 +9,17 @@ import os import signal import sys +import warnings -from structlog import get_logger +import containerlog.proxy.std +from containerlog import get_logger import synse_server -from synse_server import (app, cache, config, errors, loop, metrics, plugin, - tasks) -from synse_server.log import setup_logger +from synse_server import app, cache, config, loop, metrics, plugin, tasks + +# Patch the sanic loggers to use the containerlog proxy. +containerlog.proxy.std.patch("sanic*") +containerlog.enable_contextvars() logger = get_logger() @@ -102,10 +106,6 @@ def _initialize(self) -> None: config=config.options.config, ) - # Configure logging, using the loaded config. - setup_logger() - logger.info('configured logger') - # Make sure that the filesystem layout needed by Synse Server # is present. If not, create the required directories. os.makedirs(self._server_config_dir, exist_ok=True) @@ -121,6 +121,19 @@ def _initialize(self) -> None: def run(self) -> None: """Run Synse Server.""" + # Set up application logging. Default is debug mode enabled. Set the level + # to INFO if debug disabled. + # FIXME (also checking the historical "logging" configuration option, which + # is now deprecated. This will be removed in an upcoming release.) + _log_opt_debug = config.options.get('logging') != 'debug' + if not config.options.get('debug') or _log_opt_debug: + if _log_opt_debug: + warnings.warn( + 'You are using a deprecated configuration option (logging). ' + 'Instead, use "debug" (debug=True / debug=False)' + ) + containerlog.set_level(containerlog.INFO) # pragma: nocover + # Register signals for graceful termination for sig in ('SIGINT', 'SIGTERM'): logger.info('adding signal handler to synse loop') diff --git a/synse_server/tasks.py b/synse_server/tasks.py index 709e46ea..4fd046bd 100644 --- a/synse_server/tasks.py +++ b/synse_server/tasks.py @@ -3,7 +3,7 @@ import asyncio import sanic -from structlog import get_logger +from containerlog import get_logger from synse_server import config, plugin from synse_server.cache import update_device_cache diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index 05213bbe..dae65693 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -1,8 +1,8 @@ """Fixture definitions for Synse Server unit tests.""" import datetime -import logging import asynctest +import containerlog import pytest from sanic_testing import TestManager from synse_grpc import api, client @@ -22,17 +22,14 @@ # @pytest.mark.usefixtures() -@pytest.fixture(scope='module', autouse=True) -def disable_loggers(): - """Fixture to disable loggers for the tests.""" +@pytest.fixture(autouse=True) +def disable_logger(): + """Disable the application logger for unit tests. - logging.getLogger('synse_server').setLevel(logging.CRITICAL) - - logging.getLogger('synse_server').disabled = True - logging.getLogger('root').disabled = True - logging.getLogger('sanic.access').disabled = True - logging.getLogger('sanic.error').disabled = True - logging.getLogger('sanic.root').disabled = True + This helps to keep the test output cleaner and more easily readable. If there are + cases where having the extra logging would be helpful, simply disable this fixture. + """ + containerlog.disable() @pytest.fixture() diff --git a/tests/unit/test_app.py b/tests/unit/test_app.py index 84744d1b..ca2aa8cc 100644 --- a/tests/unit/test_app.py +++ b/tests/unit/test_app.py @@ -1,7 +1,7 @@ """Unit tests for the ``synse_server.app`` module.""" +from containerlog import contextvars from sanic.response import HTTPResponse, StreamingHTTPResponse -from structlog import contextvars from synse_server import app, errors @@ -27,16 +27,16 @@ class MockRequest: req = MockRequest() resp = HTTPResponse() - contextvars.bind_contextvars( + contextvars.bind( request_id='test-request', ) - ctx = contextvars._CONTEXT_VARS - assert 'test-request' == ctx['structlog_request_id'].get() + ctx = contextvars._CTXVARS + assert 'test-request' == ctx['containerlog_request_id'].get() app.on_response(req, resp) - ctx = contextvars._CONTEXT_VARS - assert ctx['structlog_request_id'].get() is Ellipsis + ctx = contextvars._CTXVARS + assert ctx['containerlog_request_id'].get() is Ellipsis def test_on_response_streaming_http_response(): @@ -47,13 +47,13 @@ class MockRequest: req = MockRequest() resp = StreamingHTTPResponse(None) - contextvars.bind_contextvars( + contextvars.bind( request_id='test-request', ) - ctx = contextvars._CONTEXT_VARS - assert 'test-request' == ctx['structlog_request_id'].get() + ctx = contextvars._CTXVARS + assert 'test-request' == ctx['containerlog_request_id'].get() app.on_response(req, resp) - ctx = contextvars._CONTEXT_VARS - assert ctx['structlog_request_id'].get() is Ellipsis + ctx = contextvars._CTXVARS + assert ctx['containerlog_request_id'].get() is Ellipsis diff --git a/tests/unit/test_log.py b/tests/unit/test_log.py deleted file mode 100644 index 81f62742..00000000 --- a/tests/unit/test_log.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Unit tests for the ``synse_server.log`` module.""" - -import logging - -import mock -import structlog - -from synse_server import log - - -def test_setup_logger_defaults(): - logger = structlog.get_logger('synse_server') - logger.setLevel(logging.DEBUG) - - log.setup_logger() - assert logger.getEffectiveLevel() == logging.INFO - - -@mock.patch('synse_server.log.config.options.get', return_value='error') -def test_setup_logger_configured(mock_get): - log.setup_logger() - assert structlog.get_logger('synse_server').getEffectiveLevel() == logging.ERROR - mock_get.assert_called_once_with('logging', 'info') diff --git a/tests/unit/test_server.py b/tests/unit/test_server.py index 9fa68cbd..f89f2073 100644 --- a/tests/unit/test_server.py +++ b/tests/unit/test_server.py @@ -24,12 +24,10 @@ def test_init_ok(self, mock_init): mock_init.assert_called_once() @mock.patch('os.makedirs') - @mock.patch('synse_server.server.setup_logger') @mock.patch('synse_server.server.Synse.reload_config') - def test_initialize(self, mock_reload, mock_logger, mock_mkdirs): + def test_initialize(self, mock_reload, mock_mkdirs): synse = server.Synse() - mock_logger.assert_called_once() mock_reload.assert_called_once() mock_mkdirs.assert_has_calls([ mock.call(synse._server_config_dir, exist_ok=True),