Performance tracing
Gatsby allows a build to be traced, enabling you to find which plugins or parts of the build are taking the longest. The trace information can be viewed in any OpenTracing compatible tool such as Jaeger. You can also use Zipkin compatible tools such as Zipkin or Honeycomb.
Running Gatsby with tracing turned on
Gatsby code is instrumented with OpenTracing, which is a general tracing API that is implementation agnostic. Therefore, you’ll need to include and configure an OpenTracing compatible library in your application, as well as a backend to collect the trace data.
The steps required to add tracing are below. Or, you can skip ahead if you want specific instructions for jaeger or zipkin.
1. Library dependency
Add an OpenTracing compatible library to your site’s package.json
dependencies.
2. Library configuration file
Each OpenTracing library must be configured. For example, what is the URL of the tracing backend? How often should spans be sent to the backend? What service name should the trace be recorded under? Etc.
The configuration file is a JavaScript file that exports two functions: create
and stop
.
- create: Create and return an OpenTracing compatible Tracer. It is called at the start of the build.
- stop: Called at the end of the build. Any cleanup required by the tracer should be performed here, such as clearing out any span queues and sending them to the tracing backend.
3. Start Gatsby with tracing turned on
The above configuration file can be passed to Gatsby with the --open-tracing-config-file
command-line option. When Gatsby is started with this option, it will load the supplied tracing configuration file, and call its create
function. The returned Tracer will be used for tracing the build. Once the build has stopped, the configuration file’s stop
method will be called, allowing the tracing implementation to perform any cleanup.
Tracing backend examples
There are many OpenTracing compatible backends available. Below is an example of how to hook Zipkin into Gatsby.
local Jaeger with Docker
Jaeger is an open source tracing system that can be run locally using Docker.
Add jaeger-client to your site:
yarn add jaeger-client
or
npm install jaeger-client
Run Jaeger’s all-in-one Docker instance with:
docker run -d --name jaeger \ -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \ -p 5775:5775/udp \ -p 6831:6831/udp \ -p 6832:6832/udp \ -p 5778:5778 \ -p 16686:16686 \ -p 14268:14268 \ -p 9411:9411 \ jaegertracing/all-in-one:1.8
See Jaeger Getting Started for more information.
Start Gatsby
build
ordevelop
with--open-tracing-config-file
pointing at the Jaeger configuration file. An example file is provided in the Gatsby project under node_modules/gatsby/dist/utils/tracer/jaeger-local.js that will send tracing spans to your local Docker instance over HTTP. E.ggatsby build --open-tracing-config-file node_modules/gatsby/dist/utils/tracer/jaeger-local.js
Once the build is complete, view your tracing information at http://localhost:16686. On the left menu, select the
build
operation to see your build’s root trace.
local Zipkin with Docker
Zipkin is an open source tracing system that can be run locally using Docker.
Add following dependencies to your site’s
package.json
Run Zipkin’s all-in-one Docker instance with
docker run -d -p 9411:9411 openzipkin/zipkin
. See Zipkin Getting Started for more information.Start Gatsby
build
ordevelop
with--open-tracing-config-file
pointing at the Zipkin configuration file. An example file is provided in the Gatsby project undernode_modules/gatsby/dist/utils/tracer/zipkin-local.js
that will send tracing spans to your local Docker instance. E.ggatsby build --open-tracing-config-file node_modules/gatsby/dist/utils/tracer/zipkin-local.js
Once the build is complete, view your tracing information at http://localhost:9411
Adding your own tracing
The default tracing that comes with Gatsby can give you a good idea of which plugins or stages of the build are slowing down your site. But sometimes, you’ll want to trace the internals of your site. Or if you’re a plugin author, you might want to trace long operations.
To provide custom tracing, you can use the tracing
object, which is present in the args passed to API implementers. This tracing object contains a function called startSpan
. This simply wraps OpenTracing startSpan, but provides the default childOf: parentSpan
span args. startSpan
returns a span object that you must explicitly end by calling its .finish()
method. For example:
exports.sourceNodes = async ({ actions, tracing }) => {
const span = tracing.startSpan(`foo`)
// Perform any span operations. E.g add a tag to your span
span.setTag(`bar`, `baz`)
// Rest of your plugin code
span.finish()
}
With this span, you can perform any OpenTracing span operation such as span.setTag. Just make sure that the tracing backend supports these operations. You can provide an optional second span options argument to startSpan
which will be passed to the underlying OpenTracing call.
For advanced use cases, the tracing
object also provides tracer
and parentSpan
fields. You can use these to construct independent spans, or your own child spans (see the OpenTracing project for more info).
Edit this page on GitHub