atst/tests/utils/test_logging.py
dandds 9ae20b4a2a JSON logging for Celery workers.
This enables JSON logging for Celery workers if the LOG_JSON conig value
is set. It uses the same JsonFormatter class used by the Flask
applications. That class has been updated in two ways:

- It takes a `source` kwarg to define the log source for the formatter.
- The `msg` attribute of the log record is formatted with any arguments
  that may have been passed. This is necessary for Celery to render task
  type, completion time, etc. into the log output.
2019-11-25 10:13:37 -05:00

81 lines
2.1 KiB
Python

from io import StringIO
import json
import logging
from uuid import uuid4
from unittest.mock import Mock
import pytest
from atst.utils.logging import JsonFormatter, RequestContextFilter
from tests.factories import UserFactory
@pytest.fixture
def log_stream():
return StringIO()
@pytest.fixture
def log_stream_content(log_stream):
def _log_stream_content():
log_stream.seek(0)
return log_stream.read()
return _log_stream_content
@pytest.fixture
def logger(log_stream):
logger = logging.getLogger()
for handler in logger.handlers:
logger.removeHandler(handler)
logHandler = logging.StreamHandler(log_stream)
formatter = JsonFormatter()
logHandler.setFormatter(formatter)
logger.setLevel(logging.INFO)
logger.addFilter(RequestContextFilter())
logger.addHandler(logHandler)
return logger
def test_json_formatter(logger, log_stream_content):
logger.warning("do or do not", extra={"tags": ["wisdom", "jedi"]})
log = json.loads(log_stream_content())
assert log["tags"] == ["wisdom", "jedi"]
assert log["message"] == "do or do not"
assert log["severity"] == "WARNING"
assert log.get("details") is None
def test_json_formatter_for_exceptions(logger, log_stream_content):
try:
raise Exception()
except Exception:
logger.exception("you found the ventilation shaft!")
log = json.loads(log_stream_content())
assert log["severity"] == "ERROR"
assert log.get("details")
def test_request_context_filter(logger, log_stream_content, request_ctx, monkeypatch):
request_uuid = str(uuid4())
user_uuid = str(uuid4())
user = Mock(spec=["id"])
user.id = user_uuid
user.dod_id = "5678901234"
monkeypatch.setattr("atst.utils.logging.g", Mock(current_user=user))
request_ctx.request.environ["HTTP_X_REQUEST_ID"] = request_uuid
logger.info("this user is doing something")
log = json.loads(log_stream_content())
assert log["user_id"] == str(user_uuid)
assert log["dod_edipi"] == str(user.dod_id)
assert log["request_id"] == request_uuid