True Story Follows
In my last post I wrote about some techniques to add a decorator that will log all of the local variables in a function and otherwise keep your actual code clean and spotless from context switching. I used this at work to keep logging as decoupled as possible from the rest of the code in the application. I wrote briefly about how this fits nicely in a case where most of the entities in your application have UUID identifiers.
At this point, we have a case where we can grep through the logs for a particular UUID, and you can trace through all of the events that have occurred for a particular entity or an object in a particular state. But who wants to look at UUID’s all day? The aforementioned is nice for isolating events that have happened, but if we are indeed using UUID’s for most of our identifiers, it becomes mentally taxing to provite context around a particular event with other objects. UUID’s are in essence 16 random bytes, and so what kind of masochist wants to just look through UUID’s in a log?
In my experience with the gfycat API, one of the nice things I noticed was that unique identifiers were created using english nouns. This made URL’s much more human friendly and eye pleasing. I basically applied this same concept to logging where I mapped UUID’s to nouns, and I included this noun in every object __repr__ method.
So for example:
I can create some base objects that all objects in the repository inherit from, and I can add a bit of logic to associate some deterministic UUID for each object. With that UUID, you can simply map it to a deterministic index on a large list of nouns:
And now all objects when logged will look something like this:
Now, as we traverse our logs we can more easily discern what objects are getting passed into particular functions and we can isolate more than just a single entity at a time (since we’re able to scan text with our eyes now instead of searching for an exact UUID string match).