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.

Taming conditionals with bitmasks

· 9 min

The 100k context window of Claude 2 has been a huge boon for me since now I can paste a moderately complex problem to the chat window and ask questions about it. In that spirit, it recently refactored some pretty gnarly conditional logic for me in such an elegant manner that it absolutely blew me away. Now, I know how bitmasks work and am aware of the existence of enum.Flag in Python. However, it never crossed my mind that flags can be leveraged to trim conditional branches in such a clever manner that Claude illustrated. But once I looked at the proposed solution, the whole thing immediately clicked for me.

Using DNS record to share text data

· 2 min

This morning, while browsing Hacker News, I came across a neat trick for sharing data via DNS TXT records. It can be useful for propagating a small amount of data in environments that restrict IP but allow DNS queries, or to bypass censorship.

To test this out, I opened my domain registrar’s panel and created a new TXT type DNS entry with a base64 encoded message containing the poem A Poison Tree by William Blake. The message can now be queried and decoded with the following shell command:

Memory leakage in Python descriptors

· 5 min

Unless I’m hand rolling my own ORM-like feature or validation logic, I rarely need to write custom descriptors in Python. The built-in descriptor magics like @classmethod, @property, @staticmethod, and vanilla instance methods usually get the job done. However, every time I need to dig my teeth into descriptors, I reach for this fantastic Descriptor how-to guide by Raymond Hettinger. You should definitely set aside the time to read it if you haven’t already. It has helped me immensely to deepen my understanding of how many of the fundamental language constructs are wired together underneath.

Unix-style pipelining with Python's subprocess module

· 6 min

Python offers a ton of ways like os.system or os.spawn* to create new processes and run arbitrary commands in your system. However, the documentation usually encourages you to use the subprocess module for creating and managing child processes. The subprocess module exposes a high-level run() function that provides a simple interface for running a subprocess and waiting for it to complete. It accepts the command to run as a list of strings, starts the subprocess, waits for it to finish, and then returns a CompletedProcess object with information about the result. For example:

Enabling repeatable lazy iterations in Python

· 4 min

The current title of this post is probably incorrect and may even be misleading. I had a hard time coming up with a suitable name for it. But the idea goes like this: sometimes you might find yourself in a situation where you need to iterate through a generator more than once. Sure, you can use an iterable like a tuple or list to allow multiple iterations, but if the number of elements is large, that’ll cause an OOM error. On the other hand, once you’ve already consumed a generator, you’ll need to restart it if you want to go through it again. This behavior is common in pretty much every programming language that supports the generator construct.

Associative arrays in Bash

· 4 min

One of my favorite pastimes these days is to set BingChat to creative mode, ask it to teach me a trick about topic X, and then write a short blog post about it to reinforce my understanding. Some of the things it comes up with are absolutely delightful. In the spirit of that, I asked it to teach me a Shell trick that I can use to mimic maps or dictionaries in a shell environment. I didn’t even know what I was expecting.

Process substitution in Bash

· 6 min

I needed to compare two large directories with thousands of similarly named PDF files and find the differing filenames between them. In the first pass, this is what I did:

Listed out the content of the first directory and saved it in a file:

ls dir1 > dir1.txt

Did the same for the second directory:

ls dir2 > dir2.txt

Compared the difference between the two outputs:

diff dir1.txt dir2.txt

This returned the name of the differing files likes this:

Dynamic menu with select statement in Bash

· 4 min

Whenever I need to whip up a quick command line tool, my go-to is usually Python. Python’s CLI solutions tend to be more robust than their Shell counterparts. However, dealing with its portability can sometimes be a hassle, especially when all you want is to distribute a simple script. That’s why while toying around with argparse to create a dynamic menu, I decided to ask ChatGPT if there’s a way to achieve the same using native shell scripting. Delightfully, it introduced me to the dead-simple select command that I probably should’ve known about years ago. But I guess better late than never! Here’s what I was trying to accomplish:

Simple terminal text formatting with tput

· 3 min

When writing shell scripts, I’d often resort to using hardcoded ANSI escape codes to format text, such as:

#!/usr/bin/env bash

BOLD="\033[1m"
UNBOLD="\033[22m"
FG_RED="\033[31m"
BG_YELLOW="\033[43m"
BG_BLUE="\033[44m"
RESET="\033[0m"

# Print a message in bold red text on a yellow background.
echo -e "${BOLD}${FG_RED}${BG_YELLOW}This is a warning message${RESET}"

# Print a message in white text on a blue background.
echo -e "${BG_BLUE}This is a debug message${RESET}"

This shell snippet above shows how to add text formatting and color to shell script output via ANSI escape codes. It defines a few variables that contain different escape codes for bold, unbold, foreground, and background colors. Then, we echo two log messages with different colors and formatting options.