We are excited to announce Grafana Labs is to acquire Kausal. Read more

Prometheus Tab-completion For Everybody

Twitter profile image
on Nov 22, 2017

I still remember my first steps with PromQL. Even after I learned more about the available functions and the Prometheus data model, the queries just would not flow as quickly as I liked. At Kausal, we believe making the writing of those queries easier will benefit the general adoption of Prometheus. That is why we decided to make our PromQL query editor open source.

Usage overview

The editor comes with tab-completion for metric names, label keys, label values, ranges, etc. It is now available as prom-editor at our public mono-repo: https://github.com/kausalco/public, wrapped inside an example React application. We previously wrote about Slate and Prism, the underlying editor libraries. This blog post will dive a little deeper into the mechanics of the editor and its integration into an application.

Editor Mechanics

The query field component wraps a Slate.js editor. That editor handles all the browser events that occur while typing and keeps a state object of the editor content. What should happen on typing input is determined by implementing API handlers or plugins. Currently, the query field uses both, eventually I would like it to be entirely plugin-based.

For event handling via plugins, consider the Runner plugin. Its sole purpose is to handle Return key presses. Based on which meta keys were pressed at the same time, it will enter a soft newline, or call the onPressEnter handler that was provided to the editor component itself. Plugins are evaluated in order: The first one to return a new state will stop the chain evaluation and cause the editor to apply the returned state.

The query field also implements handlers directly, via props to the editor component. An example is the onKeyDown handler, which is in charge of controlling the interaction with the tab-completion, e.g., arrow up and tab, as well as some helpers that automatically close parenthesis.

Typeahead Suggestions

How do we know what to suggest? We need a mechanism that tells us which part of a query we are currently typing, e.g., a function name, a metric name, a label value, etc. What comes in handy here is the Prism.js plugin, which does the syntax highlighting. We have structured the syntax rules not only to mark the tokens of a query, but also added some context markers. Consider this query, just after the = has been typed:


The Prism pattern 'context-labels': /\{[^}]*(?=})/ establishes that we are typing labels. After we hit =, the typeahead handler knows that a label value must follow. The handler now looks left for the label key based on the 'label-key' class that has been applied by Prism to the label key. It does the same for the first metric name it sees to its left. The metric name plus label key can now be used to look up the label values that the label key supports. Those values will then be listed in as suggestions in the typeahead overlay.

The lookup of the label keys and values happens dynamically, as soon as the editor sees a {} it starts querying for the available labels. Naturally, there will be a slight delay in showing the suggestions based on how fast the Prometheus server responds.

Try It Yourself

We made the PromQL editor open source. Here is the link to our public repository for our Open Source projects. In that repo, the query field is in the prom-editor project. This project comes with an example React application that integrates the query field, shows the JSON results of a query, and prints a couple of query evaluation stats that have recently been added to the Prometheus API. By default, the example application points to your local Prometheus installation (running on http://localhost:9090/). If you need a different URL, just patch the api proxy in package.json. To try it out, clone the repo, install its dependencies, and start it. See the README for more details.

Upcoming Improvements

We are continuously improving the query editor. Here is a non-comprehensive list of things that still need work:

  • Add support from Prometheus function name completion with docs snippet.
  • The query analysis in not done with a proper lexer, so does not support all conceivable PromQL queries.
  • A new slate.js version is available, consider upgrading.
  • Wrapping issues with long queries.
  • It’s too easy to end up with doubly-quoted label values.

Give it a try, and contributions are welcome!

Kausal's mission is to enable software developers to better understand the behaviour of their code. We combine Prometheus monitoring, log aggregation and OpenTracing-compatible distributed tracing into a hosted observability service for developers.
Contact us to get started.