Wiki ▸ API Reference ▸ QuestDB
A source for QuestDB metrics. To create a source, first create a context. Then, use context.questdb to specify the URL and path to the QuestDB server:
var context = cubism.context()
.serverDelay(5 * 1000) // allow 5 seconds of collection lag
.step(10000) // ten seconds per value
.size(1440); // fetch 1440 values (24 hours at 1min intervals)
var questdb = context.questdb({"host": "http://localhost:9000", "apiPath": "/exec"});
After you create the context add some metrics:
# questdb.metric
Creates a new metric for a given QuestDB table and column. You need to specify table name, column name, and optionally aggregation function, timestamp column, and WHERE conditions:
var system_metrics = [
questdb.metric({
"table": "system_stats",
"column": "cpu_usage",
"timestampColumn": "ts",
"aggregation": "avg",
"where": "host = 'web1'"
}).alias("web1 cpu"),
questdb.metric({
"table": "system_stats",
"column": "memory_usage",
"timestampColumn": "ts",
"aggregation": "max",
"where": "host = 'web1'"
}).alias("web1 memory"),
questdb.metric({
"table": "network_stats",
"column": "bytes_per_sec",
"timestampColumn": "timestamp",
"aggregation": "sum"
}).alias("total network")
];
"timestamp")"avg")
"avg", "sum", "count", "min", "max"// Custom title generator
var customMetric = questdb.metric({
"table": "app_metrics",
"column": "response_time",
"aggregation": "percentile",
"where": "service = 'api' AND status = 200",
"titleGenerator": function(info) {
return "API P95 Response Time";
}
});
// With change callback
var monitoredMetric = questdb.metric({
"table": "alerts",
"column": "error_count",
"aggregation": "sum",
"onChangeCallback": function(start, stop) {
console.log("Alert data updated for period:", start, "to", stop);
}
});
After that you just need to add some colors to use and append the metrics into the DOM:
var horizon = context.horizon().colors(["#08519c", "#3182bd", "#6baed6", "#fee6ce", "#fdae6b", "#e6550d"]);
d3.select("body").selectAll(".axis")
.data(["top", "bottom"])
.enter().append("div").attr("class", "fluid-row")
.attr("class", function(d) { return d + " axis"; })
.each(function(d) { d3.select(this).call(context.axis().ticks(12).orient(d)); });
d3.select("body").append("div")
.attr("class", "rule")
.call(context.rule());
d3.select("body").selectAll(".horizon")
.data(system_metrics)
.enter().insert("div", ".bottom")
.attr("class", "horizon").call(horizon.extent([0, 100]));
context.on("focus", function(i) {
d3.selectAll(".value").style("right", i == null ? null : context.size() - 1 - i + "px");
});
Please note the horizon.extent([0, 100]). Those are minimum and maximum values for your metric. Choose those carefully based on your expected data range.
The QuestDB source automatically generates time-bucketed SQL queries using QuestDB’s SAMPLE BY functionality:
SELECT
dateadd('s', (cast((timestamp - timestamp('2023-01-01T00:00:00.000Z')) / 1000000 as long) / 10) * 10,
timestamp('2023-01-01T00:00:00.000Z')) as time_bucket,
avg(cpu_usage) as value
FROM system_stats
WHERE timestamp >= '2023-01-01T00:00:00.000Z'
AND timestamp < '2023-01-01T01:00:00.000Z'
AND host = 'web1'
SAMPLE BY 10s
ORDER BY time_bucket
# questdb.toString()
Returns the QuestDB server URL and API path used by the source constructor.