When logging in Java, especially frameworks like Spring, making sure the logging statement has access to the full context of the operation in flight is important. Instead of spamming piles of logging statements in your business logic, you can use a “mapped diagnostic context” to cache useful bits of information during an operation, such that any logging statement can access it.
One of the tools for this is the “Mapped Data Context”, MDC. Essentially, it’s very much like a great big hash map that happens to be thread-local and is meant to be used by the logging framework. It’s a global-ish variable, but without the worst side effects of being global.
And you know people just love to use global variables.
Lothar was trying to figure out some weird requests coming out of an API, and needed to know where certain session ID values were coming from. There are a lot of “correct” ways to store session information in your Java Spring applications, and he assumed that was how they were storing those things. Lothar was wrong.
He provided this anonymized/generalized example of how pretty much every one of their REST request methods looked:
@Override
public Wtf getWtf(String wtfId) {
Map<String, Object> params = new HashMap<>();
params.put("wtfId", wtfId);
params.put("sessId", MDC.get(MDC_LABEL_SESSION_ID));
params.put(MDC_LABEL_SESSION_ID, MDC.get(MDC_LABEL_SESSION_ID));
UriComponents uriComponents = UriComponentsBuilder
.fromUriString("https://thedailywtf.com")
.buildAndExpand(params);
String urlString = uriComponents.toUriString();
ResponseEntity<byte[]> responseEntity = restTemplate.getForEntity(urlString, byte[].class);
}
Throughout their application, they (ab)used their logging framework as a thread-local storage system for passing user session data around.
Sure, the code was stupid, but the worst part about this code was that it worked. It did everything it needed to do, and it also meant that all of their log messages had rich context which made it easier to diagnose issues.
If it’s stupid and it works, that means you ship it.