135 lines
4.2 KiB
Python
135 lines
4.2 KiB
Python
import logging
|
|
|
|
import flask_restx as restx
|
|
|
|
|
|
class LoggingTest(object):
|
|
def test_namespace_loggers_log_to_flask_app_logger(self, app, client, caplog):
|
|
# capture Flask app logs
|
|
caplog.set_level(logging.INFO, logger=app.logger.name)
|
|
|
|
api = restx.Api(app)
|
|
ns1 = api.namespace("ns1", path="/ns1")
|
|
ns2 = api.namespace("ns2", path="/ns2")
|
|
|
|
@ns1.route("/")
|
|
class Ns1(restx.Resource):
|
|
def get(self):
|
|
ns1.logger.info("hello from ns1")
|
|
pass
|
|
|
|
@ns2.route("/")
|
|
class Ns2(restx.Resource):
|
|
def get(self):
|
|
ns2.logger.info("hello from ns2")
|
|
pass
|
|
|
|
# debug log not shown
|
|
client.get("/ns1/")
|
|
matching = [r for r in caplog.records if r.message == "hello from ns1"]
|
|
assert len(matching) == 1
|
|
|
|
# info log shown
|
|
client.get("/ns2/")
|
|
matching = [r for r in caplog.records if r.message == "hello from ns2"]
|
|
assert len(matching) == 1
|
|
|
|
def test_defaults_to_app_level(self, app, client, caplog):
|
|
caplog.set_level(logging.INFO, logger=app.logger.name)
|
|
|
|
api = restx.Api(app)
|
|
ns1 = api.namespace("ns1", path="/ns1")
|
|
ns2 = api.namespace("ns2", path="/ns2")
|
|
|
|
@ns1.route("/")
|
|
class Ns1(restx.Resource):
|
|
def get(self):
|
|
ns1.logger.debug("hello from ns1")
|
|
pass
|
|
|
|
@ns2.route("/")
|
|
class Ns2(restx.Resource):
|
|
def get(self):
|
|
ns2.logger.info("hello from ns2")
|
|
pass
|
|
|
|
# debug log not shown
|
|
client.get("/ns1/")
|
|
matching = [r for r in caplog.records if r.message == "hello from ns1"]
|
|
assert len(matching) == 0
|
|
|
|
# info log shown
|
|
client.get("/ns2/")
|
|
matching = [r for r in caplog.records if r.message == "hello from ns2"]
|
|
assert len(matching) == 1
|
|
|
|
def test_override_app_level(self, app, client, caplog):
|
|
caplog.set_level(logging.DEBUG, logger=app.logger.name)
|
|
|
|
api = restx.Api(app)
|
|
ns1 = api.namespace("ns1", path="/ns1")
|
|
ns1.logger.setLevel(logging.DEBUG)
|
|
ns2 = api.namespace("ns2", path="/ns2")
|
|
ns2.logger.setLevel(logging.INFO)
|
|
|
|
@ns1.route("/")
|
|
class Ns1(restx.Resource):
|
|
def get(self):
|
|
ns1.logger.debug("hello from ns1")
|
|
pass
|
|
|
|
@ns2.route("/")
|
|
class Ns2(restx.Resource):
|
|
def get(self):
|
|
ns2.logger.debug("hello from ns2")
|
|
pass
|
|
|
|
# debug log shown from ns1
|
|
client.get("/ns1/")
|
|
matching = [r for r in caplog.records if r.message == "hello from ns1"]
|
|
assert len(matching) == 1
|
|
|
|
# debug not shown from ns2
|
|
client.get("/ns2/")
|
|
matching = [r for r in caplog.records if r.message == "hello from ns2"]
|
|
assert len(matching) == 0
|
|
|
|
def test_namespace_additional_handler(self, app, client, caplog, tmp_path):
|
|
caplog.set_level(logging.INFO, logger=app.logger.name)
|
|
log_file = tmp_path / "v1.log"
|
|
|
|
api = restx.Api(app)
|
|
ns1 = api.namespace("ns1", path="/ns1")
|
|
# set up a file handler for ns1 only
|
|
# FileHandler only supports Path object on Python >= 3.6 -> cast to str
|
|
fh = logging.FileHandler(str(log_file))
|
|
ns1.logger.addHandler(fh)
|
|
|
|
ns2 = api.namespace("ns2", path="/ns2")
|
|
|
|
@ns1.route("/")
|
|
class Ns1(restx.Resource):
|
|
def get(self):
|
|
ns1.logger.info("hello from ns1")
|
|
pass
|
|
|
|
@ns2.route("/")
|
|
class Ns2(restx.Resource):
|
|
def get(self):
|
|
ns2.logger.info("hello from ns2")
|
|
pass
|
|
|
|
# ns1 logs go to stdout and log_file
|
|
client.get("/ns1/")
|
|
matching = [r for r in caplog.records if r.message == "hello from ns1"]
|
|
assert len(matching) == 1
|
|
with log_file.open() as f:
|
|
assert "hello from ns1" in f.read()
|
|
|
|
# ns2 logs go to stdout only
|
|
client.get("/ns2/")
|
|
matching = [r for r in caplog.records if r.message == "hello from ns2"]
|
|
assert len(matching) == 1
|
|
with log_file.open() as f:
|
|
assert "hello from ns1" in f.read()
|