Log context propagation in Python ASGI apps

· 7 min

Let’s say you have a web app that emits log messages from different layers. Your log shipper collects and sends these messages to a destination like Datadog where you can query them. One common requirement is to tag the log messages with some common attributes, which you can use later to query them.

In distributed tracing, this tagging is usually known as context propagation, where you’re attaching some contextual information to your log messages that you can use later for query purposes. However, if you have to collect the context at each layer of your application and pass it manually to the downstream ones, that’d make the whole process quite painful.

Please don't hijack my Python root logger

· 5 min

With the recent explosion of LLM tools, I often like to kill time fiddling with different LLM client libraries and SDKs in one-off scripts. Lately, I’ve noticed that some newer tools frequently mess up the logger settings, meddling with my application logs. While it’s less common in more seasoned libraries, I guess it’s worth rehashing why hijacking the root logger isn’t a good idea when writing libraries or other forms of reusable code.

Anemic stack traces in Go

· 7 min

While I like Go’s approach of treating errors as values as much as the next person, it inevitably leads to a situation where there isn’t a one-size-fits-all strategy for error handling like in Python or JavaScript.

The usual way of dealing with errors entails returning error values from the bottom of the call chain and then handling them at the top. But it’s not universal since there are cases where you might want to handle errors as early as possible and fail catastrophically. Yet, it’s common enough that we can use it as the base of our conversation.

Go structured logging with slog

· 10 min

Before the release of version 1.21, you couldn’t set levels for your log messages in Go without either using third-party libraries or writing your own boilerplates. Coming from Python, I’ve always found this odd, considering that this capability has been in the Python standard library forever. However, it seems like the new log/slog subpackage in Go allows you to do that and a whole lot more.

Apart from being able to add levels to log messages, slog also allows you to emit JSON-structured log messages and group them by certain attributes. The ability to do all this in-house is quite neat and I wanted to take it for a spin. The official documentation on this is on the terser side but still comprehensive. So, here, instead of repeating the same information, I wanted to write something for me that mainly highlights the most common cases.

Python logging quirks in AWS Lambda environment

· 4 min

At my workplace, while working on a Lambda function, I noticed that my Python logs weren’t appearing on the corresponding Cloudwatch log dashboard. At first, I thought that the function wasn’t picking up the correct log level from the environment variables. We were using Serverless framework and GitLab CI to deploy the function, so my first line of investigation involved checking for missing environment variables in those config files.

However, I quickly realized that the environment variables were being propagated to the Lambda function as expected. So, the issue had to be coming from somewhere else. After perusing through some docs, I discovered from the source code of Lambda Python Runtime Interface Client that AWS Lambda Python runtime pre-configures a logging handler that modifies the format of the log message, and also adds some metadata to the record if available. What’s not pre-configured though is the log level. This means that no matter the type of log message you try to send, it won’t print anything.