Today we're going to discuss how you can leverage your logs for third-party tools using Grafana's API and Node.js 😍.
💡 The idea that starts it all
Several months ago, I started thinking about how to use our logs to build a personalized CLI experience.
After a bit of searching, I quickly found that Grafana had an API for queryings Loki logs. I immediately went crazy at the thought of what could be done with it 🔥.
import{GrafanaLoki}from"@myunisoft/loki";constapi=newGrafanaLoki({// Note: if not provided, it will load process.env.GRAFANA_API_TOKENapiToken:"...",remoteApiURL:"https://name.loki.com"});constlogs=awaitapi.queryRange(`{app="serviceName", env="production"}`,{start:"1d",limit:200});console.log(logs);
👀 Notice the support of duration for options like start and end.
It already supports Stream and Matrix and several other APIs:
GET /loki/api/v1/labels
GET /loki/api/v1/label/:name/values
GET /loki/api/v1/series
We've also added datasource APIs (which may be required depending on what you'r building).
It also include a LogParser inspired by Loki pattern.
// can be provided as an option to queryRangeconstparser=newLogParser<{method:string,endpoint:string,statusCode:number}>("<method:httpMethod> <endpoint> <statusCode:httpStatusCode>");constlogs=awaitapi.queryRange(`... LogQL here ...`,{parser});for (constlogLineoflogs){console.log(logLine.method);console.log(logLine.endpoint);}
It's still far from perfect, don't hesitate to contribute 💪.
A reverse-proxy to safely expose Loki to internet (if required).
🚀 Getting Started
This package is available in the Node Package Repository and can be easily installed with npm or yarn
$ npm i @myunisoft/loki
# or
$ yarn add @myunisoft/loki
📚 Usage
import{GrafanaApi}from"@myunisoft/loki";import{LogQL,StreamSelector}from"@sigyn/logql";constapi=newGrafanaApi({// Note: if not provided, it will load process.env.GRAFANA_API_TOKENapiToken: "...",remoteApiURL: "https://name.loki.com"});constql=newLogQL(newStreamSelector({app: "serviceName",env: "production"}));constlogs=awaitapi.Loki.queryRange(ql,// or string `{app="serviceName", env="production"}`{start: "1d",limit: 200});console
I'm not alone and didn't do all the work 👯. Thanks to Pierre Demailly and Sofian Doual for their contribution/support.
🙏 Conclusion
These two tools have enabled us to initiate the development of new tools. One of them is an alerting agent for Loki named Sigyn, to whom I'll be dedicating an article in the near future.
Having APIs really opens up a lot of opportunities and it'll be interesting to see what me and my team are able to produce in the future with them.