2018-12-26 15:06:39 +01:00
|
|
|
/*
|
|
|
|
* Loki API to Clickhouse Gateway
|
2021-01-22 23:23:39 +01:00
|
|
|
* (C) 2018-2021 QXIP BV
|
2018-12-26 15:06:39 +01:00
|
|
|
*/
|
|
|
|
|
2018-12-27 13:26:15 +01:00
|
|
|
/* TODO: split into modules and prioritize performance! contributors help yourselves :) */
|
2021-06-15 00:28:51 +02:00
|
|
|
this.debug = process.env.DEBUG || false;
|
|
|
|
var debug = this.debug;
|
2018-12-27 13:26:15 +01:00
|
|
|
|
2021-06-15 00:28:51 +02:00
|
|
|
this.readonly = process.env.READONLY || false;
|
|
|
|
this.http_user = process.env.CLOKI_LOGIN || false;
|
|
|
|
this.http_pass = process.env.CLOKI_PASSWORD || false;
|
2018-12-26 15:06:39 +01:00
|
|
|
|
2021-02-05 13:47:49 -05:00
|
|
|
var DATABASE = require("./lib/db/clickhouse");
|
|
|
|
var UTILS = require("./lib/utils");
|
2018-12-26 15:06:39 +01:00
|
|
|
|
2018-12-27 03:22:06 +01:00
|
|
|
/* ProtoBuf Helper */
|
2021-02-05 13:47:49 -05:00
|
|
|
var fs = require("fs");
|
2018-12-27 03:22:06 +01:00
|
|
|
var protoBuff = require("protocol-buffers");
|
2021-02-05 13:47:49 -05:00
|
|
|
var messages = protoBuff(fs.readFileSync("lib/loki.proto"));
|
2018-12-27 03:22:06 +01:00
|
|
|
|
2018-12-26 15:06:39 +01:00
|
|
|
/* Fingerprinting */
|
2021-06-15 00:28:51 +02:00
|
|
|
this.fingerPrint = UTILS.fingerPrint;
|
|
|
|
this.toJSON = UTILS.toJSON;
|
2018-12-26 16:55:13 +01:00
|
|
|
|
2021-06-15 00:28:51 +02:00
|
|
|
/* Database this.bulk Helpers */
|
|
|
|
this.bulk = DATABASE.cache.bulk; // samples
|
|
|
|
this.bulk_labels = DATABASE.cache.bulk_labels; // labels
|
|
|
|
this.labels = DATABASE.cache.labels; // in-memory labels
|
2018-12-26 15:06:39 +01:00
|
|
|
|
|
|
|
/* Function Helpers */
|
2021-06-15 00:28:51 +02:00
|
|
|
this.labelParser = UTILS.labelParser;
|
2018-12-28 02:12:45 +01:00
|
|
|
|
2018-12-29 02:30:14 +01:00
|
|
|
var init = DATABASE.init;
|
2021-06-15 00:28:51 +02:00
|
|
|
this.reloadFingerprints = DATABASE.reloadFingerprints;
|
|
|
|
this.scanFingerprints = DATABASE.scanFingerprints;
|
|
|
|
this.scanMetricFingerprints = DATABASE.scanMetricFingerprints;
|
|
|
|
this.scanClickhouse = DATABASE.scanClickhouse;
|
2018-12-27 02:14:00 +01:00
|
|
|
|
2021-06-15 00:28:51 +02:00
|
|
|
if (!this.readonly) init(process.env.CLICKHOUSE_TSDB || "loki");
|
2018-12-26 15:06:39 +01:00
|
|
|
|
|
|
|
/* Fastify Helper */
|
2021-02-05 13:47:49 -05:00
|
|
|
const fastify = require("fastify")({
|
2021-06-15 00:28:51 +02:00
|
|
|
logger: false,
|
2021-02-05 13:47:49 -05:00
|
|
|
});
|
2018-12-26 15:06:39 +01:00
|
|
|
|
2021-02-05 13:47:49 -05:00
|
|
|
const path = require("path");
|
|
|
|
fastify.register(require("fastify-url-data"), (err) => {
|
2021-06-15 00:28:51 +02:00
|
|
|
if (err) throw err;
|
2021-02-05 13:47:49 -05:00
|
|
|
});
|
2018-12-27 01:02:51 +01:00
|
|
|
|
2019-05-30 22:08:07 +02:00
|
|
|
/* Enable Simple Authentication */
|
2021-06-15 00:28:51 +02:00
|
|
|
if (this.http_ && this.http_password) {
|
|
|
|
fastify.register(require("fastify-basic-auth"), {
|
|
|
|
validate
|
|
|
|
});
|
|
|
|
fastify.after(() => {
|
|
|
|
fastify.addHook("preHandler", fastify.basicAuth);
|
|
|
|
});
|
2019-05-30 22:08:07 +02:00
|
|
|
}
|
2021-02-05 13:47:49 -05:00
|
|
|
function validate(username, password, req, reply, done) {
|
2021-06-15 00:28:51 +02:00
|
|
|
if (username === this.http_user && password === this.http_password) {
|
|
|
|
done();
|
|
|
|
} else {
|
|
|
|
done(new Error("Unauthorized!: Wrong username/password."));
|
|
|
|
}
|
2019-05-30 23:03:12 +03:00
|
|
|
}
|
|
|
|
|
2021-06-15 00:28:51 +02:00
|
|
|
fastify.addContentTypeParser("text/plain", {
|
|
|
|
parseAs: "string"
|
|
|
|
}, function(req, body, done) {
|
|
|
|
try {
|
|
|
|
var json = JSON.parse(body);
|
|
|
|
done(null, json);
|
|
|
|
} catch (err) {
|
|
|
|
err.statusCode = 400;
|
|
|
|
done(err, undefined);
|
|
|
|
}
|
2021-02-05 13:47:49 -05:00
|
|
|
});
|
2018-12-26 15:06:39 +01:00
|
|
|
|
2021-06-15 00:28:51 +02:00
|
|
|
/* Protobuf Handler */
|
|
|
|
fastify.addContentTypeParser("application/x-protobuf", function(req, done) {
|
|
|
|
var data = "";
|
|
|
|
req.on("data", (chunk) => {
|
|
|
|
data += chunk;
|
|
|
|
});
|
|
|
|
req.on("error", (error) => {
|
|
|
|
console.log(error);
|
|
|
|
});
|
|
|
|
req.on("end", () => {
|
|
|
|
done(messages.PushRequest.decode(data));
|
|
|
|
});
|
2021-02-05 13:47:49 -05:00
|
|
|
});
|
2018-12-29 02:30:14 +01:00
|
|
|
|
2021-06-15 00:28:51 +02:00
|
|
|
/* 404 Handler */
|
|
|
|
const handler_404 = require('./lib/handlers/404.js').bind(this);
|
|
|
|
fastify.setNotFoundHandler(handler_404);
|
2018-12-29 02:30:14 +01:00
|
|
|
|
2021-06-15 00:28:51 +02:00
|
|
|
/* Hello cloki test API */
|
|
|
|
const handler_hello = require('./lib/handlers/hello.js').bind(this);
|
|
|
|
fastify.get("/hello", handler_hello);
|
2021-02-04 21:42:15 +01:00
|
|
|
|
2021-06-15 00:28:51 +02:00
|
|
|
/* Write Handler */
|
|
|
|
const handler_push = require('./lib/handlers/push.js').bind(this);
|
|
|
|
fastify.post("/loki/api/v1/push", handler_push);
|
2020-11-23 15:26:14 +01:00
|
|
|
|
|
|
|
/* Telegraf HTTP Bulk handler */
|
2021-06-15 00:28:51 +02:00
|
|
|
const handler_telegraf = require('./lib/handlers/telegraf.js').bind(this);
|
|
|
|
fastify.post("/telegraf", handler_telegraf);
|
2018-12-26 15:06:39 +01:00
|
|
|
|
|
|
|
/* Query Handler */
|
2021-06-15 00:28:51 +02:00
|
|
|
const handler_query_range = require('./lib/handlers/query_range.js').bind(this);
|
|
|
|
fastify.get("/loki/api/v1/query_range", handler_query_range);
|
2018-12-26 15:06:39 +01:00
|
|
|
|
|
|
|
/* Label Handlers */
|
2020-10-13 19:26:46 +02:00
|
|
|
/* Label Value Handler via query (test) */
|
2021-06-15 00:28:51 +02:00
|
|
|
const handler_query = require('./lib/handlers/query.js').bind(this);
|
|
|
|
fastify.get("/loki/api/v1/query", handler_query);
|
2020-10-13 19:26:46 +02:00
|
|
|
|
2021-06-15 00:28:51 +02:00
|
|
|
/* Label Handlers */
|
|
|
|
const handler_label = require('./lib/handlers/label.js').bind(this);
|
|
|
|
fastify.get("/loki/api/v1/label", handler_label);
|
|
|
|
fastify.get("/loki/api/v1/labels", handler_label);
|
2018-12-26 15:06:39 +01:00
|
|
|
|
|
|
|
/* Label Value Handler */
|
2021-06-15 00:28:51 +02:00
|
|
|
const handler_label_values = require('./lib/handlers/label_values.js').bind(this);
|
|
|
|
fastify.get("/loki/api/v1/label/:name/values", handler_label_values);
|
2018-12-26 15:06:39 +01:00
|
|
|
|
2020-10-13 19:26:46 +02:00
|
|
|
/* Series Placeholder - we do not track this as of yet */
|
2021-06-15 00:28:51 +02:00
|
|
|
const handler_series = require('./lib/handlers/series.js').bind(this);
|
|
|
|
fastify.get("/loki/api/v1/series", handler_series);
|
2020-10-13 19:26:46 +02:00
|
|
|
|
2018-12-27 02:26:49 +01:00
|
|
|
// Run API Service
|
2021-02-05 13:47:49 -05:00
|
|
|
fastify.listen(
|
2021-06-15 00:28:51 +02:00
|
|
|
process.env.PORT || 3100,
|
|
|
|
process.env.HOST || "0.0.0.0",
|
|
|
|
(err, address) => {
|
|
|
|
if (err) throw err;
|
|
|
|
console.log("cLoki API up");
|
|
|
|
fastify.log.info(`cloki API listening on ${address}`);
|
|
|
|
}
|
2021-02-05 13:47:49 -05:00
|
|
|
);
|