Daniel Schmidt


Performance Monitoring for the Frontend — Using Zipkin

This series of blog posts is about the network related performance issues.
The goal is to give you a set of tools to use that will provide you with insights that help you deliver fewer and shorter loading screens to your customers.

Make sure you check out the first part, too: Performance Monitoring for the Frontend — An introduction

Getting Started

Now that we got the names right let’s take a look at how we might track a single span. For that, we need a tracer to start spans with.

You can see on line 13 that we need to set a sampler. A sampler is a function that returns a boolean indicating if a trace should be started or not. It is useful to set, as you might only want to trace a certain percentage of users or only users who are connected to WIFI or something unique to your business.
In line 14 you see the service name is set to “frontend”, this will be shown on the left side. Now we have a working tracer that we might use to start some actual traces.

Let’s talk about this in detail: The first thing you might notice is that we wrap the statements we want to trace in a scoped block and set the current id of the span so that Zipkin knows about which span we talk specifically. The createRootId part means that we want to create a root span, we will later see how we can create child spans. The next thing to note is that we record annotations one for client send, it marks the start point of our span and indicates that a client is about to send a request to the server. If we wrote a server here, we would need to use the server receive annotation; for local spans (with no interaction between systems) we could use local operation start. In line 15 we see the opposite part, the client receive annotation, it marks the end of the span. As you already know spans can have names, in this case, we set it to “My Span” via the RPC annotation. RPC stands for Remote Procedure Call, which means we invoke a function on a server with this call.
Last but not least we want to know the result of our API call. Therefore we record a binary log with the key “result” and the stringified response as value.

Extending Spans

There shall only be one root, so let us see how to define a child relation:

You need to be inside a scoped block of your parent so that you might extend it by running createChildId. And that’s it, easy right? It get’s a bit more complicated when you try to connect two systems with each other, I will probably go over this in detail in a later part of the series. For now, I would like to show you where you might take a look if you want to do such a thing:

- adding HTTP headers to a request
- extracting tracing context from a request

Local Spans

Finally, I would like to show you something neat @adrianfcole ‏recently added to Zipkin: Local Spans. Whenever you find yourself in need to track something that only concerns one service, and that is either a synchronous computation or an asynchronous with a promise you should use local spans for the tracing. You can either set the Annotations yourself, or you let Zipkin handle this for you, like in this example:

The first argument of local takes a span name and the second one a function. If the function returns a promise the span ends when the promise resolves, otherwise it ends when the function is finished

Want to hear more from me? Feel free to subscribe to my newsletter, I send out news roughly once a month.

More by Daniel Schmidt

Topics of interest

More Related Stories