Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Tutorial: Modifying Grafana's Source Code

Posted on Aug 7 So this blog is a little different from my usual tutorials…A little background: I have been working with Jacob Marble to test and “demo-fy” his work with Influxdb 3.0 and the OpenTelemetry ecosystem (If you would like to learn more I highly recommend checking out this blog).During the project, we identified a need to enable specific Grafana features for InfluxDB data sources, particularly the trace to logs functionality. Grafana is an open-source platform, and one of its major advantages is the ability to modify its source code to suit our unique requirements. However, diving into the codebase of such a robust tool can be overwhelming, even for the most seasoned developers.Despite the complexity, we embraced the challenge and dove headfirst into Grafana's source code. We tumbled, we stumbled, and we learned a great deal along the way. And now, having successfully modified Grafana to meet our specific project needs, I believe it's time to share this acquired knowledge with you all.The purpose of this blog is not just to provide you with a step-by-step guide for tweaking Grafana's source code, but also to inspire you to explore and adapt open-source projects to your needs. It's about imparting a method and a mindset, cultivating a culture of curiosity, and encouraging more hands-on learning and problem-solving.I hope that this guide will empower you to modify Grafana's source code for your projects, thereby expanding the horizons of what's possible with open-source platforms. It’s time to roll up your sleeves and venture into the depths of Grafana's code. So our problem lies within the Trace visualisation of Grafana.As you can see the visualisation performs rather well with InfluxDB except for one button which appears to be disabled:** Logs for this span**. This button is automatically disabled when our trace data source (in this case, Jaeger with InfluxDB 3.0 acting as the gRPC storage engine) has not been configured with a log data source. A log data source within Grafana is usually represented by default using the log explorer interface, common log data sources are; Loki, OpenSearch and ElasticSearch. So let's head across to the Jaeger data source and configure that…Data sources can be navigated to via Connections -> Data Sources. We currently have three configured; FlightSQL, InfluxDB and Jaeger. If we open the Jaeger configuration and navigate to the Trace to Logs section we want to essentially be able yo select either InfluxDB or FlightSQL as our Data source. Houston, we have a problem. It appears Grafana doesn’t recognise InfluxDB as a log data source. Fair enough; only recently has InfluxDB become a viable option for logs. So, what are our options?Well, by now you know what option we chose.In this section, I will summarize the steps I took to discover what changes needed to be made. How to implement the changes for your own data source and finally how to build your own custom build of Grafana OSS.So the first step is to understand where to even begin. Grafana is a huge Open Source platform with many components so I needed to narrow down the search. So the first thing I did was search the Grafana repository for signs of life.As you can see I made this little discovery by using the keyword trace. Which led me to the directory TraceToLogs. This led me to this section of code within TraceToLogsSettings.tsx:This section of code seems to create a static list of data sources supported by the Trace to Logs feature. We can confirm this by some of the common suspects within the list (Loki, Elasticsearch, etc.). Based on this our first alteration to the Grafana source code should be to add our data sources to this list.Now as the coding pessimist that I am, I knew this probably wouldn’t be the only change we needed to make but it's a good place to start. So I did the following:Cloned the repo:Before I made those modifications I wanted to do some more searching to see if there are any changes I should be making. One line stood out to me in TraceToLogsSettings file:It was TraceToLogsOptionsV2. When I searched for places this interface was used I found the following entry.So it appears we might also have work to do in the createSpanLink.tsx file. Within I found this section of code, so my question was what exactly is this code doing?To cut a long story short the case statement essentially tells the trace visualisation to check what log data source has been defined (if any) and to define a query interface relevant to that data source. If the specified data source is not found within this case statement then the button is simply disabled which meant changing the original file won’t be enough as we suspected.Okay, we have now completed our investigation. Let's move on to the code changes.We have two files to modify:Let's start with the simplest to tackle and go from there. So this file was relatively simple to change. All we needed to do was modify the static list of supported log input sources like so:As you can see I have added two. I ran a quick build of the Grafana project to see how this affected our data source configuration (we will discuss how to build at the end).Hey presto! We have a result. Now this still didn’t enable the button within our Trace View but we already knew this would requiremore work. Now, onto the meat of our modification. For the record, I am not a TypeScript developer. What I do know is that the file has a whole bunch of examples we can use to attempt a blind copy-and-paste job with a few modifications. I ended up doing this for both plugins but to keep the blog short we will focus on the InfluxDB official plugin. My hypothesis was to use the Grafana Loki interface as the basis for the InfluxDB interface. The first included adding data source types:These are easy to locate when Grafana has an official plugin for your data source since it's embedded within the official repository. For our community plugin I had two options: define a static interface within the file or provide more query parameters. I chose the latter.The next step was to modify the case statement:As you can see I added two new cases:** influxdata-flightsql-datasource and influxdb. I then copied from Loki the two function calls within the case: getFormattedTags and getQueryFor. It appeared one I could leave alone (getFormattedTags) as this seemed to be the same for the majority of the cases. However,I would need to define my own getQueryFor function. Let's take a look at the new getQueryForInfluxQL function that’s called in the influxdb case statement:So there is quite a lot here, but let me highlight the important parts. First of all, I started with an exact copy of the Loki function. Then, I made the following changes:Next, I focused on the return payload. After some digging within the InfluxQuery type file, I came up with this:The InfluxDB data source had a hany parameter which allowed me to define the result format (usually metrics) and also I now knew the data source would be expecting a raw query rather than an expression.Lastly, I had to define the queries which would run when the user clicked the button. These depended on what filter features the user had toggled within the data source settings (filter by traceID, spanID or both). So I modified the if statement defined within the Loki function and constructed static InfluxQL queries. From there, I then used the Grafana placeholder variables found within other data sources to make the queries dynamic. Here is an example:Full disclosure, it took me a good minute to find out about the **>=${from}ms and



This post first appeared on VedVyas Articles, please read the originial post: here

Share the post

Tutorial: Modifying Grafana's Source Code

×

Subscribe to Vedvyas Articles

Get updates delivered right to your inbox!

Thank you for your subscription

×