diff --git a/.gitignore b/.gitignore index f838c061..c2bb70cb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,8 @@ node_modules /test/e2e/ /lib/influx/.idea/ /lib/influx/influx.iml +/wasm_parts/_vendor.zip +/wasm_parts/.idea/ +/wasm_parts/vendor/ +/wasm_parts/main.wasm +/wasm_parts/wasm_parts.iml diff --git a/lib/db/clickhouse.js b/lib/db/clickhouse.js index 5c6fd056..a704fe5f 100644 --- a/lib/db/clickhouse.js +++ b/lib/db/clickhouse.js @@ -826,7 +826,13 @@ const outputTempoSearch = async (dataStream, res) => { */ const preprocessStream = (rawStream, processors) => { let dStream = StringStream.from(rawStream.data).lines().endWith(JSON.stringify({ EOF: true })) - .map(chunk => chunk ? JSON.parse(chunk) : ({}), DataStream) + .map(chunk => { + try { + return chunk ? JSON.parse(chunk) : ({}) + } catch (e) { + return {} + } + }, DataStream) .map(chunk => { try { if (!chunk || !chunk.labels) { @@ -1344,15 +1350,16 @@ const samplesReadTable = { * @param query {string} * @param data {string | Buffer | Uint8Array} * @param database {string} + * @param config {Object?} * @returns {Promise>} */ -const rawRequest = (query, data, database) => { +const rawRequest = (query, data, database, config) => { const getParams = [ (database ? `database=${encodeURIComponent(database)}` : null), (data ? `query=${encodeURIComponent(query)}` : null) ].filter(p => p) const url = `${getClickhouseUrl()}/${getParams.length ? `?${getParams.join('&')}` : ''}` - return axios.post(url, data || query) + return axios.post(url, data || query, config) } /** diff --git a/lib/handlers/prom_push.js b/lib/handlers/prom_push.js index 249317e9..b841b2fe 100644 --- a/lib/handlers/prom_push.js +++ b/lib/handlers/prom_push.js @@ -46,13 +46,11 @@ async function handler (req, res) { // Calculate Fingerprint const strJson = stringify(JSONLabels) finger = fingerPrint(strJson) - req.log.debug({ labels: stream.labels, finger }, 'LABELS FINGERPRINT') labels.add(finger.toString(), stream.labels) const dates = {} if (stream.samples) { stream.samples.forEach(function (entry) { - req.log.debug({ entry, finger }, 'BULK ROW') if ( !entry && !entry.timestamp && diff --git a/lib/handlers/prom_query.js b/lib/handlers/prom_query.js index 62938963..59935bef 100644 --- a/lib/handlers/prom_query.js +++ b/lib/handlers/prom_query.js @@ -1,13 +1,11 @@ /* Emulated PromQL Query Handler */ -const { p2l } = require('@qxip/promql2logql'); const { asyncLogError, CORS } = require('../../common') -const { instantQueryScan } = require('../db/clickhouse') +const { instantQuery } = require('../../promql') const empty = '{"status" : "success", "data" : {"resultType" : "scalar", "result" : []}}'; // to be removed const test = () => `{"status" : "success", "data" : {"resultType" : "scalar", "result" : [${Math.floor(Date.now() / 1000)}, "2"]}}`; // to be removed const exec = (val) => `{"status" : "success", "data" : {"resultType" : "scalar", "result" : [${Math.floor(Date.now() / 1000)}, val]}}`; // to be removed - async function handler (req, res) { req.log.debug('GET /loki/api/v1/query') const resp = { @@ -25,34 +23,23 @@ async function handler (req, res) { } if (req.query.query === '1+1') { return res.status(200).send(test()) - } - else if (!isNaN(parseInt(req.query.query))) { + } else if (!isNaN(parseInt(req.query.query))) { return res.status(200).send(exec(parseInt(req.query.query))) } /* remove newlines */ req.query.query = req.query.query.replace(/\n/g, ' ') + req.query.time = req.query.time ? parseInt(req.query.time) * 1000 : Date.now() /* transpile to logql */ try { - req.query.query = p2l(req.query.query) - } catch(e) { - asyncLogError({ e }, req.log) - return res.send(empty) - } - /* scan fingerprints */ - /* TODO: handle time tag + direction + limit to govern the query output */ - try { - const response = await instantQueryScan( - req.query - ) - res.code(200) - res.headers({ - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': CORS - }) - return response + const response = await instantQuery(req.query.query, req.query.time) + return res.code(200) + .headers({ + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': CORS + }).send(response) } catch (err) { asyncLogError(err, req.log) - return res.send(empty) + return res.code(500).send(JSON.stringify({ status: 'error', error: err.message })) } } diff --git a/lib/handlers/prom_query_range.js b/lib/handlers/prom_query_range.js index 987563ac..df37c1ab 100644 --- a/lib/handlers/prom_query_range.js +++ b/lib/handlers/prom_query_range.js @@ -9,49 +9,19 @@ regexp: a regex to filter the returned results, will eventually be rolled into the query language */ -const { p2l } = require('@qxip/promql2logql') -const { asyncLogError, CORS } = require('../../common') -const { scanFingerprints } = require('../db/clickhouse') +const { rangeQuery } = require('../../promql/index') async function handler (req, res) { req.log.debug('GET /api/v1/query_range') - const resp = { - status: "success", - data: { - resultType: "vector", - result: [] - } - } - if (req.method === 'POST') { - req.query = req.body - } - if (!req.query.query) { - return res.send(resp) - } - /* remove newlines */ - req.query.query = req.query.query.replace(/\n/g, ' ') - if (!req.query.query) { - return res.code(400).send('invalid query') - } - // Convert PromQL to LogQL and execute + const startMs = parseInt(req.query.start) * 1000 || Date.now() - 60000 + const endMs = parseInt(req.query.end) * 1000 || Date.now() + const stepMs = parseInt(req.query.step) * 1000 || 15000 + const query = req.query.query try { - req.query.query = p2l(req.query.query) - const response = await scanFingerprints( - { - ...req.query, - start: parseInt(req.query.start) * 1e9, - end: parseInt(req.query.end) * 1e9 - } - ) - res.code(200) - res.headers({ - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': CORS - }) - return response + const result = await rangeQuery(query, startMs, endMs, stepMs) + return res.code(200).send(result) } catch (err) { - asyncLogError(err, req.log) - return res.send(resp) + return res.code(500).send(JSON.stringify({ status: 'error', error: err.message })) } } diff --git a/lib/handlers/prom_series.js b/lib/handlers/prom_series.js index 50f2c995..d6862b7d 100644 --- a/lib/handlers/prom_series.js +++ b/lib/handlers/prom_series.js @@ -1,21 +1,8 @@ const { scanSeries } = require('../db/clickhouse') const { CORS } = require('../../common') -const { Compiler } = require('bnf') const { isArray } = require('handlebars-helpers/lib/array') const { QrynError } = require('./errors') - -const promqlSeriesBnf = ` - ::= | "{" "}" | "{" [] "}" -label ::= ( | "_") *( | "." | "_" | ) -operator ::= "=~" | "!~" | "!=" | "=" -quoted_str ::= () | () | | -metric_name ::= label -label_selector ::=