-
-
Notifications
You must be signed in to change notification settings - Fork 68
Influx
Table of contents
- What is InfluxDB?
- Why do we use InfluxDB?
- Setting up InfluxDB
- Influx queries
InfluxDB is a way to keep track of Skyra's metrics in real-time on an awesome dashboard.
We wanted a good platform to keep track of our metrics that also integrates well with the Skyra development stack. InfluxDB was just that. It provides both a dashboard as well as the API to feed the data. We also considered solutions such as Grafana, however the lack of a good API to provide data to Grafana and the need to store the data inside Skyra's PostgreSQL database turned us away.
You will need to install Docker if you want to easily create and manage the InfluxDB instance. You should also be sure to install docker-compose to make the process easiest.
Lastly we recommend you install PowerShell Core as we provide a PowerShell script to call various docker-compose commands. This is optional however, if you know your way around docker-compose or have an extension such as Docker for VSCode.
The following commands can be used in succession to do the initial launch of the InfluxDB instance and setting up the queries.
First create a Docker volume:
docker volume create --name=influx-data
Then start an Influx container:
# When using Powershell
yarn dockerps start influx
# When not using Powershell
docker-compose -p skyra -f ./.docker/docker-compose.yml up -d influx
Skyra can keep track of various metrics. Each of these metrics require writing queries in the Flux language. This section will list all the supported Flux queries.
A query to display the total amount of guilds Skyra is in
from(bucket: "analytics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "guilds")
|> filter(fn: (r) => r["_field"] == "value")
|> group(columns: ["_field"])
|> aggregateWindow(every: v.windowPeriod, fn: last)
|> yield(name: "last")
from(bucket: "analytics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "guilds")
|> filter(fn: (r) => r["_field"] == "value")
|> group(columns: ["_field"])
|> skew()
|> yield(name: "skew")
Click here to expand for screenshot
A query to display the difference of guilds over a span of time
from(bucket: "analytics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "guilds")
|> filter(fn: (r) => r["_field"] == "value")
|> group(columns: ["_field"])
|> difference(nonNegative: false, columns: ["_value"])
Click here to expand for screenshot
A query to the total amount of commands used with Skyra
from(bucket: "analytics") // Get all published measurements. In Skyra's case, all of their names are defined in the const enum present in "AnalyticsSchema".
|> range(start: v.timeRangeStart, stop: v.timeRangeStop) // Here we define the range/(time frame) for which we wish to see the entries. Due to the precision specified in getWriteApi the lowest time frame is a second.
|> filter(fn: (r) => r["_measurement"] == "commands") // Here we get all the aforementioned time specified values and filter out anything that isn't "AnalyticsSchema.Points.Commands".
|> sum(column: "_value") // The way I did storage was by setting the "_field" to the command name and "_value" to 1. Because of that design quick each command comes in its own column which are defined by their "_field" value. After that, we sum them all up so that there's only one entry per "_field" column.
|> group(mode: "by") // Now since they are still in their own "_field" sorted columns we need to join them into a single one.
|> sum(column: "_value") // And finally since we have all the commands in one place we can sum their "_value" up and get the total amount on used commands in a specified time frame.
Click here to expand for screenshot
A query to display the total amount users Skyra services
from(bucket: "analytics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "users")
|> filter(fn: (r) => r["_field"] == "value")
|> group(columns: ["_field"])
|> aggregateWindow(every: v.windowPeriod, fn: last)
|> yield(name: "last")
from(bucket: "analytics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "users")
|> filter(fn: (r) => r["_field"] == "value")
|> group(columns: ["_field"])
|> skew()
|> yield(name: "skew")
Click here to expand for screenshot
A query to display the total amount voice connections Skyra has - as a single stat
from(bucket: "analytics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "voice_connections")
|> filter(fn: (r) => r["_field"] == "value")
|> group(columns: ["_field"])
|> skew()
|> yield(name: "skew")
from(bucket: "analytics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "voice_connections")
|> filter(fn: (r) => r["_field"] == "value")
|> group(columns: ["_field"])
|> aggregateWindow(every: v.windowPeriod, fn: last)
|> yield(name: "last")
Click here to expand for screenshot
A query to display the total amount voice connections Skyra has - as a gauge
from(bucket: "analytics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "voice_connections")
|> filter(fn: (r) => r["_field"] == "value")
|> group(columns: ["_field"])
Click here to expand for screenshot
A query to display the total uses of a command, per command
from(bucket: "analytics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "commands")
|> sum(column: "_value")
|> group(mode:"by")