Building Datadog Widgets With Vega
While working on content for a client, we had the all-too-common executive request to make a dashboard “more snazzy”. Opinions aside on the basis of this statement, it is a request that we’ve received multiple times in the past. Part of the problem is that a good dashboard isn’t designed to be pretty, it’s designed to convey the key information needed to diagnose an issue. While Datadog has a stunning UI that in most cases executives love, a feature that we’ve often seen management and executive level stakeholders love is a fuel gauge-style widget. A small hemisphere, a dial filled based on what metric that’s being checked, colour-coded based on severity. It’s easily recognised and parsed by anyone familiar with the concept, and because each metric is different it provides enough variety visually to not be a homogenous blob when viewing it while also having consistency to allow it to all be taken in at once. At least that’s my theory on it.
![]() |
|---|
| Attribution: Petar Milošević, CC BY-SA 4.0 https://creativecommons.org/licenses/by-sa/4.0, via Wikimedia Commons |
Out of the box Datadog doesn’t have a widget that looks like this. But it does have the ability to show arbitrary widgets using the wildcard type. Wildcards use Vega-Lite or Vega to generate a visualisation using JSON that is embedded into your dashboard or report. Having never used either of these before it seemed like a decent opportunity to have a play around and see what could be possible.
A note on what I learned that might help those working with Vega: several (free) AI chatbots I worked with were awful at creating Vega diagrams. I don’t know if this was a prompting issue or a lack of available training data, I suspect a bit of both. But in all cases there was nothing I could use as a baseline to iterate on and develop into what I needed. After some searching I ended up finding a guide on buliding almost exactly what I needed. The core JSON file for this visualisation was around 350 lines and at first glance I couldn’t make heads or tails of most of it to see where I could change or update to fit with what I wanted, so I spent the next couple of hours working through the guide section by section building it out.
With the gauge in hand, I could start poking it into Datadog to see how we could use it. Embedding the code as it existed worked, but of course we want to be able to show our own data and have that update as the underlying metric changes. To achieve that we need to link the visualisation to the query. This required two changes to the code. One was to add a source for the metric in the data block of the Vega file:
{
"name": "table1"
}
table1 is the default query table when creating a metric to present. While I haven’t tried it personally, I imagine there are additional tables that can be incorporated into a visualisation if needed, and if so these would also be added into the data block.
The second change required was to update the main value being shown to use the output from this table. This meant updating the mainValue of the code in the signals section to:
{
"name": "mainValue",
"update": "data('table1')[0].query1"
}
query1 is the first query line in the associated table. If you have multiple queries or formulas you’ll need to adjust this value accordingly to find the correct output metric to visualise. In my case I had removed a few components of the gauge from the guide above that weren’t relevant to what I was looking to achieve, so this was the only change I needed to make.
Eventually I managed to get it working. I will say that during this experience, while AI was no help in generating the initial code, it is a great way of checking for syntax errors or missing punctuation in your schema. JSON is finicky at the best of times and across a few hundred lines of JSON being able to drop your code in front of an AI and say “is this syntax correct” makes troubleshooting much easier. A prime example being that for my mainValue code I had initiall set this to be a value, so it wasn’t checking for changes and needed to be replaced with update, and I had initially not included quotes around table1, so it was apparently being treated as a variable and not as a string literal to refer to. Small issues like a missing pair of quote marks would have taken me hours to figure out solo, it’s such a small change that unless you’re really disciplined, you’re likely to miss it if you don’t know to look for it.
Future plans are to recreate the code and iterate on it to be able to share more widely. While the crux of the code should be easy enough to rebuild as-is, I’d like to try and create a few variations such as colour changes of the gauge as values pass thresholds, or more generally parameterising the solution to work across multiple possible options instead of the current 1-100 scale that I’d recreated the gauge for.
_(cropped).jpg)