2021-08-20 21:31:05 +02:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
2018-12-26 15:06:39 +01:00
|
|
|
/*
|
2022-06-11 19:58:14 +02:00
|
|
|
* LogQL API to Clickhouse Gateway
|
2022-02-07 18:01:33 +01:00
|
|
|
* (C) 2018-2022 QXIP BV
|
2018-12-26 15:06:39 +01:00
|
|
|
*/
|
|
|
|
|
2021-11-08 11:43:59 -06:00
|
|
|
this.readonly = process.env.READONLY || false
|
2022-06-12 11:20:32 +00:00
|
|
|
this.http_user = process.env.QRYN_LOGIN || process.env.CLOKI_LOGIN || undefined
|
|
|
|
this.http_password = process.env.QRYN_PASSWORD || process.env.CLOKI_PASSWORD || undefined
|
2018-12-26 15:06:39 +01:00
|
|
|
|
2022-08-23 23:03:39 +02:00
|
|
|
this.maxListeners = process.env.MAXLISTENERS || 0;
|
2023-03-14 16:23:34 +02:00
|
|
|
|
2022-08-23 23:03:39 +02:00
|
|
|
process.setMaxListeners(this.maxListeners)
|
|
|
|
|
2021-11-08 11:43:59 -06:00
|
|
|
require('./plugins/engine')
|
2021-10-19 16:18:25 +03:00
|
|
|
|
2021-11-08 11:43:59 -06:00
|
|
|
const DATABASE = require('./lib/db/clickhouse')
|
|
|
|
const UTILS = require('./lib/utils')
|
2018-12-26 15:06:39 +01:00
|
|
|
|
2022-01-09 21:44:47 +01:00
|
|
|
/* ProtoBuf Helpers */
|
2021-11-08 11:43:59 -06:00
|
|
|
const fs = require('fs')
|
2022-01-21 11:48:27 -06:00
|
|
|
const path = require('path')
|
2022-08-23 23:03:39 +02:00
|
|
|
|
2022-02-07 11:13:17 +00:00
|
|
|
const logger = require('./lib/logger')
|
|
|
|
|
2022-01-09 21:44:47 +01:00
|
|
|
/* Alerting */
|
|
|
|
const { startAlerting, stop } = require('./lib/db/alerting')
|
2018-12-27 03:22:06 +01:00
|
|
|
|
2018-12-26 15:06:39 +01:00
|
|
|
/* Fingerprinting */
|
2021-11-08 11:43:59 -06: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 */
|
2021-11-08 11:43:59 -06:00
|
|
|
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-11-08 11:43:59 -06:00
|
|
|
this.labelParser = UTILS.labelParser
|
2018-12-28 02:12:45 +01:00
|
|
|
|
2021-11-08 11:43:59 -06:00
|
|
|
const init = DATABASE.init
|
|
|
|
this.reloadFingerprints = DATABASE.reloadFingerprints
|
|
|
|
this.scanFingerprints = DATABASE.scanFingerprints
|
2022-08-24 15:40:19 +02:00
|
|
|
this.scanTempo = DATABASE.scanTempo
|
2021-11-22 17:11:49 +02:00
|
|
|
this.instantQueryScan = DATABASE.instantQueryScan
|
2021-12-30 14:37:38 +00:00
|
|
|
this.tempoQueryScan = DATABASE.tempoQueryScan
|
2021-11-08 11:43:59 -06:00
|
|
|
this.scanMetricFingerprints = DATABASE.scanMetricFingerprints
|
2021-12-29 10:23:03 +02:00
|
|
|
this.tempoQueryScan = DATABASE.tempoQueryScan
|
2022-02-01 09:26:47 +02:00
|
|
|
this.scanClickhouse = DATABASE.scanClickhouse
|
2022-09-13 17:40:02 +00:00
|
|
|
this.pushZipkin = DATABASE.pushZipkin
|
2022-10-17 23:14:16 +03:00
|
|
|
this.pushOTLP = DATABASE.pushOTLP
|
2022-09-13 17:40:02 +00:00
|
|
|
this.queryTempoTags = DATABASE.queryTempoTags
|
|
|
|
this.queryTempoValues = DATABASE.queryTempoValues
|
2022-02-01 09:26:47 +02:00
|
|
|
let profiler = null
|
|
|
|
|
2022-10-17 23:14:16 +03:00
|
|
|
const {
|
|
|
|
shaper,
|
|
|
|
parsers,
|
|
|
|
lokiPushJSONParser, lokiPushProtoParser, jsonParser, rawStringParser, tempoPushParser, tempoPushNDJSONParser,
|
2022-12-06 19:30:26 +02:00
|
|
|
yamlParser, prometheusPushProtoParser, combinedParser, otlpPushProtoParser, wwwFormParser
|
2022-12-10 23:40:25 +02:00
|
|
|
} = require('./parsers')
|
2023-03-14 16:23:34 +02:00
|
|
|
|
2023-01-26 14:00:48 +02:00
|
|
|
const fastifyPlugin = require('fastify-plugin')
|
2023-03-14 16:23:34 +02:00
|
|
|
|
2022-10-17 23:14:16 +03:00
|
|
|
let fastify = require('fastify')({
|
2022-02-07 11:13:17 +00:00
|
|
|
logger,
|
2022-12-22 17:01:27 +01:00
|
|
|
bodyLimit: parseInt(process.env.FASTIFY_BODYLIMIT) || 5242880,
|
2021-12-09 09:11:20 +02:00
|
|
|
requestTimeout: parseInt(process.env.FASTIFY_REQUESTTIMEOUT) || 0,
|
2021-11-29 13:57:54 +01:00
|
|
|
maxRequestsPerSocket: parseInt(process.env.FASTIFY_MAXREQUESTS) || 0
|
2022-12-10 23:40:25 +02:00
|
|
|
});
|
|
|
|
(async () => {
|
|
|
|
try {
|
|
|
|
if (!this.readonly) {
|
|
|
|
await init(process.env.CLICKHOUSE_DB || 'cloki')
|
|
|
|
await startAlerting()
|
|
|
|
}
|
2023-03-01 16:40:20 +02:00
|
|
|
await DATABASE.checkDB()
|
2022-12-10 23:40:25 +02:00
|
|
|
if (!this.readonly && process.env.PROFILE) {
|
|
|
|
const tag = JSON.stringify({ profiler_id: process.env.PROFILE, label: 'RAM usage' })
|
|
|
|
const fp = this.fingerPrint(tag)
|
|
|
|
profiler = setInterval(() => {
|
|
|
|
this.bulk_labels.add([[new Date().toISOString().split('T')[0], fp, tag, '']])
|
|
|
|
this.bulk.add([[fp,
|
|
|
|
[['label', 'RAM usage'], ['profiler_id', process.env.PROFILE]],
|
|
|
|
BigInt(Date.now()) * BigInt(1000000),
|
|
|
|
process.memoryUsage().rss / 1024 / 1024, ''
|
|
|
|
]])
|
|
|
|
}, 1000)
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
logger.error(err, 'Error starting qryn')
|
|
|
|
process.exit(1)
|
|
|
|
}
|
2021-06-26 21:50:56 +03:00
|
|
|
|
2023-01-26 14:00:48 +02:00
|
|
|
await fastify.register(fastifyPlugin((fastify, opts, done) => {
|
|
|
|
const snappyPaths = [
|
|
|
|
'/api/v1/prom/remote/write',
|
|
|
|
'/api/prom/remote/write',
|
|
|
|
'/prom/remote/write',
|
|
|
|
'/loki/api/v1/push'
|
|
|
|
]
|
|
|
|
fastify.addHook('preParsing', (request, reply, payload, done) => {
|
|
|
|
if (snappyPaths.indexOf(request.routerPath) !== -1) {
|
|
|
|
if (request.headers['content-encoding'] === 'snappy') {
|
|
|
|
delete request.headers['content-encoding']
|
|
|
|
}
|
|
|
|
}
|
|
|
|
done(null, payload)
|
|
|
|
})
|
|
|
|
done()
|
|
|
|
}))
|
2022-12-10 23:40:25 +02:00
|
|
|
await fastify.register(require('@fastify/compress'))
|
|
|
|
await fastify.register(require('fastify-url-data'))
|
|
|
|
await fastify.register(require('@fastify/websocket'))
|
2021-06-26 21:50:56 +03:00
|
|
|
|
2022-12-10 23:40:25 +02:00
|
|
|
/* Fastify local metrics exporter */
|
|
|
|
if (process.env.FASTIFY_METRICS) {
|
|
|
|
const metricsPlugin = require('fastify-metrics')
|
|
|
|
fastify.register(metricsPlugin, { endpoint: '/metrics' })
|
2023-10-06 14:49:55 +03:00
|
|
|
} else {
|
|
|
|
fastify.get('/metrics', () => 'not supported')
|
2022-02-07 11:13:17 +00:00
|
|
|
}
|
2023-10-06 14:49:55 +03:00
|
|
|
fastify.get('/config', () => 'not supported')
|
|
|
|
fastify.get('/influx/api/v2/write/health', () => 'ok')
|
2022-12-10 23:40:25 +02:00
|
|
|
/* CORS Helper */
|
|
|
|
const CORS = process.env.CORS_ALLOW_ORIGIN || '*'
|
|
|
|
fastify.register(require('@fastify/cors'), {
|
|
|
|
origin: CORS
|
|
|
|
})
|
|
|
|
|
|
|
|
fastify.after((err) => {
|
|
|
|
if (err) {
|
|
|
|
logger.error({ err }, 'Error creating http response')
|
|
|
|
throw err
|
|
|
|
}
|
|
|
|
})
|
2018-12-27 01:02:51 +01:00
|
|
|
|
2022-12-10 23:40:25 +02:00
|
|
|
fastify.__post = fastify.post
|
|
|
|
fastify.post = (route, handler, _parsers) => {
|
|
|
|
if (_parsers) {
|
|
|
|
for (const t of Object.keys(_parsers)) {
|
|
|
|
parsers.register('post', route, t, _parsers[t])
|
|
|
|
}
|
2022-10-17 23:14:16 +03:00
|
|
|
}
|
2022-12-10 23:40:25 +02:00
|
|
|
return fastify.__post(route, handler)
|
2022-10-17 23:14:16 +03:00
|
|
|
}
|
|
|
|
|
2022-12-10 23:40:25 +02:00
|
|
|
fastify.__put = fastify.put
|
|
|
|
fastify.put = (route, handler, _parsers) => {
|
|
|
|
const __parsers = handler.parsers || _parsers
|
|
|
|
if (__parsers) {
|
|
|
|
for (const t of Object.keys(__parsers)) {
|
|
|
|
parsers.register('put', route, t, __parsers[t])
|
|
|
|
}
|
2022-10-17 23:14:16 +03:00
|
|
|
}
|
2022-12-10 23:40:25 +02:00
|
|
|
return fastify.__put(route, handler)
|
2022-10-17 23:14:16 +03:00
|
|
|
}
|
|
|
|
|
2022-12-10 23:40:25 +02:00
|
|
|
fastify.__all = fastify.all
|
|
|
|
fastify.all = (route, handler, _parsers) => {
|
|
|
|
const __parsers = handler.parsers || _parsers
|
|
|
|
if (__parsers) {
|
|
|
|
for (const t of Object.keys(__parsers)) {
|
|
|
|
parsers.register('post', route, t, __parsers[t])
|
|
|
|
parsers.register('put', route, t, __parsers[t])
|
|
|
|
}
|
2022-10-17 23:14:16 +03:00
|
|
|
}
|
2022-12-10 23:40:25 +02:00
|
|
|
return fastify.__all(route, handler)
|
2022-10-17 23:14:16 +03:00
|
|
|
}
|
|
|
|
|
2022-12-10 23:40:25 +02:00
|
|
|
/* Enable Simple Authentication */
|
|
|
|
if (this.http_user && this.http_password) {
|
|
|
|
function checkAuth (username, password, req, reply, done) {
|
|
|
|
if (username === this.http_user && password === this.http_password) {
|
|
|
|
done()
|
|
|
|
} else {
|
|
|
|
done(new Error('Unauthorized!: Wrong username/password.'))
|
|
|
|
}
|
2021-10-31 19:46:46 +01:00
|
|
|
}
|
2022-12-10 23:40:25 +02:00
|
|
|
|
|
|
|
const validate = checkAuth.bind(this)
|
|
|
|
|
|
|
|
fastify.register(require('fastify-basic-auth'), {
|
|
|
|
validate,
|
|
|
|
authenticate: true
|
|
|
|
})
|
|
|
|
fastify.after(() => {
|
|
|
|
fastify.addHook('preHandler', fastify.basicAuth)
|
|
|
|
})
|
2021-11-08 11:43:59 -06:00
|
|
|
}
|
|
|
|
|
2022-12-10 23:40:25 +02:00
|
|
|
/* 404 Handler */
|
|
|
|
const handler404 = require('./lib/handlers/404.js').bind(this)
|
|
|
|
fastify.setNotFoundHandler(handler404)
|
|
|
|
fastify.setErrorHandler(require('./lib/handlers/errors').handler.bind(this))
|
|
|
|
|
|
|
|
/* Hello qryn test API */
|
|
|
|
const handlerHello = require('./lib/handlers/ready').bind(this)
|
|
|
|
fastify.get('/hello', handlerHello)
|
|
|
|
fastify.get('/ready', handlerHello)
|
|
|
|
|
|
|
|
/* Write Handler */
|
|
|
|
const handlerPush = require('./lib/handlers/push.js').bind(this)
|
|
|
|
fastify.post('/loki/api/v1/push', handlerPush, {
|
|
|
|
'application/json': lokiPushJSONParser,
|
|
|
|
'application/x-protobuf': lokiPushProtoParser,
|
|
|
|
'*': lokiPushJSONParser
|
|
|
|
})
|
|
|
|
|
|
|
|
/* Elastic Write Handler */
|
|
|
|
const handlerElasticPush = require('./lib/handlers/elastic_index.js').bind(this)
|
|
|
|
fastify.post('/:target/_doc', handlerElasticPush, {
|
|
|
|
'application/json': jsonParser,
|
|
|
|
'*': rawStringParser
|
2021-11-08 11:43:59 -06:00
|
|
|
})
|
2022-12-10 23:40:25 +02:00
|
|
|
fastify.post('/:target/_create/:id', handlerElasticPush, {
|
|
|
|
'application/json': jsonParser,
|
|
|
|
'*': rawStringParser
|
|
|
|
})
|
|
|
|
fastify.put('/:target/_doc/:id', handlerElasticPush, {
|
|
|
|
'application/json': jsonParser,
|
|
|
|
'*': rawStringParser
|
|
|
|
})
|
|
|
|
fastify.put('/:target/_create/:id', handlerElasticPush, {
|
|
|
|
'application/json': jsonParser,
|
|
|
|
'*': rawStringParser
|
|
|
|
})
|
|
|
|
const handlerElasticBulk = require('./lib/handlers/elastic_bulk.js').bind(this)
|
|
|
|
fastify.post('/_bulk', handlerElasticBulk, {
|
2022-12-27 13:03:24 -06:00
|
|
|
'application/json': jsonParser,
|
2022-12-10 23:40:25 +02:00
|
|
|
'*': rawStringParser
|
|
|
|
})
|
|
|
|
fastify.post('/:target/_bulk', handlerElasticBulk, {
|
2022-12-27 13:03:24 -06:00
|
|
|
'application/json': jsonParser,
|
2022-12-10 23:40:25 +02:00
|
|
|
'*': rawStringParser
|
2021-11-08 11:43:59 -06:00
|
|
|
})
|
2019-05-30 23:03:12 +03:00
|
|
|
|
2022-12-10 23:40:25 +02:00
|
|
|
/* Tempo Write Handler */
|
|
|
|
this.tempo_tagtrace = process.env.TEMPO_TAGTRACE || false
|
|
|
|
const handlerTempoPush = require('./lib/handlers/tempo_push.js').bind(this)
|
|
|
|
fastify.post('/tempo/api/push', handlerTempoPush, {
|
|
|
|
'application/json': tempoPushParser,
|
|
|
|
'application/x-ndjson': tempoPushNDJSONParser,
|
|
|
|
'*': tempoPushParser
|
2022-02-07 18:01:33 +01:00
|
|
|
})
|
2022-12-10 23:40:25 +02:00
|
|
|
fastify.post('/tempo/spans', handlerTempoPush, {
|
|
|
|
'application/json': tempoPushParser,
|
|
|
|
'application/x-ndjson': tempoPushNDJSONParser,
|
|
|
|
'*': tempoPushParser
|
|
|
|
})
|
|
|
|
fastify.post('/api/v2/spans', handlerTempoPush, {
|
|
|
|
'application/json': tempoPushParser,
|
|
|
|
'application/x-ndjson': tempoPushNDJSONParser,
|
|
|
|
'*': tempoPushParser
|
|
|
|
})
|
|
|
|
|
|
|
|
/* Tempo Traces Query Handler */
|
|
|
|
this.tempo_span = process.env.TEMPO_SPAN || 24
|
|
|
|
const handlerTempoTraces = require('./lib/handlers/tempo_traces.js').bind(this)
|
|
|
|
fastify.get('/api/traces/:traceId', handlerTempoTraces)
|
|
|
|
fastify.get('/api/traces/:traceId/:json', handlerTempoTraces)
|
2023-01-27 17:51:24 +02:00
|
|
|
fastify.get('/tempo/api/traces/:traceId', handlerTempoTraces)
|
|
|
|
fastify.get('/tempo/api/traces/:traceId/:json', handlerTempoTraces)
|
2022-02-07 18:01:33 +01:00
|
|
|
|
2022-12-10 23:40:25 +02:00
|
|
|
/* Tempo Tag Handlers */
|
|
|
|
|
|
|
|
const handlerTempoLabel = require('./lib/handlers/tempo_tags').bind(this)
|
|
|
|
fastify.get('/api/search/tags', handlerTempoLabel)
|
2023-01-27 17:51:24 +02:00
|
|
|
fastify.get('/tempo/api/search/tags', handlerTempoLabel)
|
2022-12-10 23:40:25 +02:00
|
|
|
|
|
|
|
/* Tempo Tag Value Handler */
|
|
|
|
const handlerTempoLabelValues = require('./lib/handlers/tempo_values').bind(this)
|
|
|
|
fastify.get('/api/search/tag/:name/values', handlerTempoLabelValues)
|
2023-01-27 17:51:24 +02:00
|
|
|
fastify.get('/tempo/api/search/tag/:name/values', handlerTempoLabelValues)
|
2022-12-10 23:40:25 +02:00
|
|
|
|
|
|
|
/* Tempo Traces Query Handler */
|
|
|
|
const handlerTempoSearch = require('./lib/handlers/tempo_search.js').bind(this)
|
|
|
|
fastify.get('/api/search', handlerTempoSearch)
|
2023-01-27 17:51:24 +02:00
|
|
|
fastify.get('/tempo/api/search', handlerTempoSearch)
|
2022-12-10 23:40:25 +02:00
|
|
|
|
|
|
|
/* Tempo Echo Handler */
|
|
|
|
const handlerTempoEcho = require('./lib/handlers/echo.js').bind(this)
|
|
|
|
fastify.get('/api/echo', handlerTempoEcho)
|
2023-01-27 17:51:24 +02:00
|
|
|
fastify.get('/tempo/api/echo', handlerTempoEcho)
|
2022-12-10 23:40:25 +02:00
|
|
|
|
|
|
|
/* Telegraf HTTP Bulk handler */
|
|
|
|
const handlerTelegraf = require('./lib/handlers/telegraf.js').bind(this)
|
|
|
|
fastify.post('/telegraf', handlerTelegraf, {
|
|
|
|
'*': jsonParser
|
|
|
|
})
|
|
|
|
|
2023-03-14 11:48:51 +02:00
|
|
|
/* Datadog Log Push Handler */
|
|
|
|
const handlerDatadogLogPush = require('./lib/handlers/datadog_log_push.js').bind(this)
|
|
|
|
fastify.post('/api/v2/logs', handlerDatadogLogPush, {
|
|
|
|
'application/json': jsonParser,
|
|
|
|
'*': rawStringParser
|
|
|
|
})
|
|
|
|
|
|
|
|
/* Datadog Series Push Handler */
|
|
|
|
const handlerDatadogSeriesPush = require('./lib/handlers/datadog_series_push.js').bind(this)
|
|
|
|
fastify.post('/api/v2/series', handlerDatadogSeriesPush, {
|
|
|
|
'application/json': jsonParser,
|
|
|
|
'*': rawStringParser
|
|
|
|
})
|
|
|
|
|
2022-12-10 23:40:25 +02:00
|
|
|
/* Query Handler */
|
|
|
|
const handlerQueryRange = require('./lib/handlers/query_range.js').bind(this)
|
|
|
|
fastify.get('/loki/api/v1/query_range', handlerQueryRange)
|
|
|
|
|
|
|
|
/* Label Handlers */
|
|
|
|
/* Label Value Handler via query (test) */
|
|
|
|
const handlerQuery = require('./lib/handlers/query.js').bind(this)
|
|
|
|
fastify.get('/loki/api/v1/query', handlerQuery)
|
|
|
|
|
|
|
|
/* Label Handlers */
|
|
|
|
const handlerLabel = require('./lib/handlers/label.js').bind(this)
|
|
|
|
fastify.get('/loki/api/v1/label', handlerLabel)
|
|
|
|
fastify.get('/loki/api/v1/labels', handlerLabel)
|
|
|
|
|
|
|
|
/* Label Value Handler */
|
|
|
|
const handlerLabelValues = require('./lib/handlers/label_values.js').bind(this)
|
|
|
|
fastify.get('/loki/api/v1/label/:name/values', handlerLabelValues)
|
|
|
|
|
|
|
|
/* Series Handler - experimental support for both Loki and Prometheus */
|
|
|
|
const handlerSeries = require('./lib/handlers/series.js').bind(this)
|
|
|
|
fastify.get('/loki/api/v1/series', handlerSeries)
|
|
|
|
const handlerPromSeries = require('./lib/handlers/prom_series.js').bind(this)
|
|
|
|
fastify.get('/api/v1/series', handlerPromSeries)
|
2023-01-03 15:59:35 -06:00
|
|
|
fastify.post('/api/v1/series', handlerPromSeries, {
|
|
|
|
'application/x-www-form-urlencoded': wwwFormParser
|
|
|
|
})
|
2022-12-10 23:40:25 +02:00
|
|
|
|
|
|
|
fastify.register(async (fastify) => {
|
|
|
|
fastify.get('/loki/api/v1/tail', { websocket: true }, require('./lib/handlers/tail').bind(this))
|
2022-02-07 18:01:33 +01:00
|
|
|
})
|
|
|
|
|
2022-12-10 23:40:25 +02:00
|
|
|
/* ALERT MANAGER Handlers */
|
|
|
|
fastify.get('/api/prom/rules', require('./lib/handlers/alerts/get_rules').bind(this))
|
|
|
|
fastify.get('/api/prom/rules/:ns/:group', require('./lib/handlers/alerts/get_group').bind(this))
|
|
|
|
fastify.post('/api/prom/rules/:ns', require('./lib/handlers/alerts/post_group').bind(this), {
|
|
|
|
'*': yamlParser
|
|
|
|
})
|
|
|
|
fastify.delete('/api/prom/rules/:ns/:group', require('./lib/handlers/alerts/del_group').bind(this))
|
|
|
|
fastify.delete('/api/prom/rules/:ns', require('./lib/handlers/alerts/del_ns').bind(this))
|
|
|
|
fastify.get('/prometheus/api/v1/rules', require('./lib/handlers/alerts/prom_get_rules').bind(this))
|
|
|
|
|
|
|
|
/* PROMETHEUS REMOTE WRITE Handlers */
|
|
|
|
const promWriteHandler = require('./lib/handlers/prom_push.js').bind(this)
|
|
|
|
fastify.post('/api/v1/prom/remote/write', promWriteHandler, {
|
|
|
|
'application/x-protobuf': prometheusPushProtoParser,
|
|
|
|
'application/json': jsonParser,
|
|
|
|
'*': combinedParser(prometheusPushProtoParser, jsonParser)
|
|
|
|
})
|
|
|
|
fastify.post('/api/prom/remote/write', promWriteHandler, {
|
|
|
|
'application/x-protobuf': prometheusPushProtoParser,
|
|
|
|
'application/json': jsonParser,
|
|
|
|
'*': combinedParser(prometheusPushProtoParser, jsonParser)
|
|
|
|
})
|
|
|
|
fastify.post('/prom/remote/write', promWriteHandler, {
|
|
|
|
'application/x-protobuf': prometheusPushProtoParser,
|
|
|
|
'application/json': jsonParser,
|
|
|
|
'*': combinedParser(prometheusPushProtoParser, jsonParser)
|
|
|
|
})
|
|
|
|
|
|
|
|
/* PROMQETHEUS API EMULATION */
|
|
|
|
const handlerPromQueryRange = require('./lib/handlers/prom_query_range.js').bind(this)
|
|
|
|
fastify.post('/api/v1/query_range', handlerPromQueryRange, {
|
|
|
|
'application/x-www-form-urlencoded': wwwFormParser
|
|
|
|
})
|
|
|
|
fastify.get('/api/v1/query_range', handlerPromQueryRange)
|
|
|
|
const handlerPromQuery = require('./lib/handlers/prom_query.js').bind(this)
|
|
|
|
fastify.post('/api/v1/query', handlerPromQuery, {
|
|
|
|
'application/x-www-form-urlencoded': wwwFormParser
|
|
|
|
})
|
|
|
|
fastify.get('/api/v1/query', handlerPromQuery)
|
|
|
|
const handlerPromLabel = require('./lib/handlers/promlabel.js').bind(this)
|
|
|
|
const handlerPromLabelValues = require('./lib/handlers/promlabel_values.js').bind(this)
|
|
|
|
fastify.get('/api/v1/labels', handlerPromLabel) // piggyback on qryn labels
|
|
|
|
fastify.get('/api/v1/label/:name/values', handlerPromLabelValues) // piggyback on qryn values
|
|
|
|
fastify.post('/api/v1/labels', handlerPromLabel, {
|
|
|
|
'*': rawStringParser
|
|
|
|
}) // piggyback on qryn labels
|
|
|
|
fastify.post('/api/v1/label/:name/values', handlerPromLabelValues, {
|
|
|
|
'*': rawStringParser
|
|
|
|
}) // piggyback on qryn values
|
|
|
|
const handlerPromDefault = require('./lib/handlers/prom_default.js')
|
|
|
|
fastify.get('/api/v1/metadata', handlerPromDefault.misc.bind(this)) // default handler TBD
|
|
|
|
fastify.get('/api/v1/rules', handlerPromDefault.rules.bind(this)) // default handler TBD
|
|
|
|
fastify.get('/api/v1/query_exemplars', handlerPromDefault.misc.bind(this)) // default handler TBD
|
2023-01-03 15:59:35 -06:00
|
|
|
fastify.post('/api/v1/query_exemplars', handlerPromDefault.misc.bind(this), {
|
|
|
|
'application/x-www-form-urlencoded': wwwFormParser
|
|
|
|
}) // default handler TBD
|
|
|
|
fastify.get('/api/v1/format_query', handlerPromDefault.misc.bind(this)) // default handler TBD
|
|
|
|
fastify.post('/api/v1/format_query', handlerPromDefault.misc.bind(this), {
|
|
|
|
'application/x-www-form-urlencoded': wwwFormParser
|
|
|
|
}) // default handler TBD
|
2022-12-10 23:40:25 +02:00
|
|
|
fastify.get('/api/v1/status/buildinfo', handlerPromDefault.buildinfo.bind(this)) // default handler TBD
|
|
|
|
|
|
|
|
/* NewRelic Log Handler */
|
|
|
|
const handlerNewrelicLogPush = require('./lib/handlers/newrelic_log_push.js').bind(this)
|
|
|
|
fastify.post('/log/v1', handlerNewrelicLogPush, {
|
|
|
|
'text/plain': jsonParser,
|
|
|
|
'*': jsonParser
|
|
|
|
})
|
|
|
|
|
|
|
|
/* INFLUX WRITE Handlers */
|
|
|
|
const handlerInfluxWrite = require('./lib/handlers/influx_write.js').bind(this)
|
|
|
|
fastify.post('/write', handlerInfluxWrite, {
|
|
|
|
'*': rawStringParser
|
|
|
|
})
|
|
|
|
fastify.post('/influx/api/v2/write', handlerInfluxWrite, {
|
|
|
|
'*': rawStringParser
|
|
|
|
})
|
|
|
|
/* INFLUX HEALTH Handlers */
|
|
|
|
const handlerInfluxHealth = require('./lib/handlers/influx_health.js').bind(this)
|
|
|
|
fastify.get('/health', handlerInfluxHealth)
|
|
|
|
fastify.get('/influx/health', handlerInfluxHealth)
|
|
|
|
|
|
|
|
const handlerOTLPPush = require('./lib/handlers/otlp_push').bind(this)
|
|
|
|
fastify.post('/v1/traces', handlerOTLPPush, {
|
|
|
|
'*': otlpPushProtoParser
|
|
|
|
})
|
|
|
|
|
|
|
|
fastify = parsers.init(fastify)
|
|
|
|
|
|
|
|
/* QRYN-VIEW Optional Handler */
|
|
|
|
if (fs.existsSync(path.join(__dirname, 'view/index.html'))) {
|
|
|
|
fastify.register(require('@fastify/static'), {
|
|
|
|
root: path.join(__dirname, 'view'),
|
|
|
|
prefix: '/'
|
|
|
|
})
|
2021-11-08 11:43:59 -06:00
|
|
|
}
|
2022-12-10 23:40:25 +02:00
|
|
|
|
|
|
|
// Run API Service
|
|
|
|
fastify.listen(
|
|
|
|
{
|
|
|
|
port: process.env.PORT || 3100,
|
|
|
|
host: process.env.HOST || '0.0.0.0'
|
|
|
|
},
|
|
|
|
(err, address) => {
|
|
|
|
if (err) throw err
|
|
|
|
logger.info('Qryn API up')
|
|
|
|
fastify.log.info(`Qryn API listening on ${address}`)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})()
|
2021-06-26 21:50:56 +03:00
|
|
|
|
|
|
|
module.exports.stop = () => {
|
2022-02-01 09:26:47 +02:00
|
|
|
shaper.stop()
|
|
|
|
profiler && clearInterval(profiler)
|
2021-11-08 11:43:59 -06:00
|
|
|
fastify.close()
|
|
|
|
DATABASE.stop()
|
2021-12-20 12:05:44 +02:00
|
|
|
require('./parser/transpiler').stop()
|
2021-12-13 11:31:49 +02:00
|
|
|
stop()
|
2021-11-08 11:43:59 -06:00
|
|
|
}
|