Skip to content

Instantly share code, notes, and snippets.

@miikka
Last active February 5, 2020 17:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save miikka/6c4d7c5035ab591fa9362aba486e5c86 to your computer and use it in GitHub Desktop.
Save miikka/6c4d7c5035ab591fa9362aba486e5c86 to your computer and use it in GitHub Desktop.
import contextvars
import logging
import uuid
import tornado.ioloop
import tornado.web
logger = logging.getLogger(__name__)
request_id_var = contextvars.ContextVar("request_id")
# Let's have an async function for the sake of demonstration
async def generate_number():
logger.info("generate a number")
return 4
class MyHandler(tornado.web.RequestHandler):
# prepare is called at the beginning of request handling
def prepare(self):
# If the request headers do not include a request ID, let's generate one.
request_id = self.request.headers.get("request-id") or str(uuid.uuid4())
request_id_var.set(request_id)
async def get(self):
number = await generate_number()
self.write(f"Here's a number: {number}")
def make_app():
return tornado.web.Application([(r"/", MyHandler),])
class MyFilter(logging.Filter):
def filter(self, record):
record.request_id = request_id_var.get("-")
return True
if __name__ == "__main__":
logging.basicConfig(
format="%(levelname)s %(request_id)s %(message)s", level=logging.INFO
)
# Log filters do not propagate, but handlers do. Thus we add the filter
# to the handlers of the root logger so that the messages of child loggers
# get filtered as well.
my_filter = MyFilter()
for handler in logging.getLogger().handlers:
handler.addFilter(my_filter)
port = 8000
app = make_app()
app.listen(port)
logger.info("Listening at http://localhost:%d/", port)
tornado.ioloop.IOLoop.current().start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment