by Adam Brett

Brocade Virtual Traffic Manager UUID

Just a short one today.

Lately, I've been working with some of my teams on improving the logging in their applications. Logging is something that people rarely do well, but when done right can prove invaluable.

One really useful logging feature, especially with service oriented & microservice architectures, is request tracking. That is, assigning a unique identifiter to a request that is passed through to every service in your system. This in turn is logged with every log line written for that request.

This allows us to trace a single request from our load balancer through every service that it touches, and every log line or event it produces. If we see an error in one of our backend services, we can likewise trace it back to the request that generated it and every service it touched in between.

In order to implement this, we need some sort of unique identifier to be generated by our load balancer, and then added to each request. For us, this is as simple as adding a header to the request called Request-Id, which contains a simple version 4 UUID (UUIDv4).

Unfortunately, our traffic manager (Stringray/Zeus/Brocade VTM), which uses a DSL called TrafficScript, does not provide a way to do this natively. This meant I had to create a simple UUID function in TrafficScript to do this for me. It looks like this (saved as a rule called lib-uuid):

sub getUuidV4() {
   $bytes = string.split(string.randomBytes(16), '');

   $bytes[6] = string.intToBytes((0x40 | ($bytes[6] & 0xf)));
   $bytes[8] = string.intToBytes((0x80 | ($bytes[8] & 0x3f)));

   $i = 0;

   foreach($byte in $bytes) {
      $bytes[$i] = string.substring(string.intToHex(string.bytesToInt($byte)), 6, 7);
      $i++;
   }

   $hex = array.join($bytes, '');

   return string.sprintf(
      '%s-%s-%s-%s-%s',
      string.substring($hex, 0, 7),
      string.substring($hex, 8, 11),
      string.substring($hex, 12, 15),
      string.substring($hex, 16, 19),
      string.substring($hex, 20, 31)
   );
}

Whilst I was initially frustrated that TrafficScript lacked such a simple ability, and something that should be quite common in load balancers (for request tracing, browser identifiers, and so on), I was equally as impressed that implementing a v4 UUID was not only possible using native TrafficScript, but that it ended up being so clean and simple.

The second part of the rule (which is in a different rule file, and the one actually assigned to the virtual server), is just as simple:

import "lib-uuid" as uuid;

if (http.getHeader('Request-Id') == '') {
   http.addHeader('Request-Id', uuid.getUuidV4());
}

The guard around the addHeader call checks to see if a Request-Id header already exists. This is to prevent the load balancer generating a new Request-Id when a request from an internal service goes back through the load balancer.

Now ensure that your applications log this as part of every log line, and forward it on to any requests to other services, and debugging your service oriented architecture is going to get a lot simpler.

For exclusive content, including screen-casts, videos, and early beta access to my projects, subscribe to my email list below.


I love discussion, but not blog comments. If you want to comment on what's written above, head over to twitter.