From e10df0b061530945c4c1364e358a093c016966d8 Mon Sep 17 00:00:00 2001 From: akvlad Date: Wed, 3 Jan 2024 14:47:57 +0200 Subject: [PATCH] write nan values as NaN on ingestion --- lib/db/clickhouse.js | 6 +++++- lib/handlers/common.js | 12 ++++++++++++ lib/handlers/influx_write.js | 6 ++++-- lib/handlers/prom_push.js | 6 ++++-- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/db/clickhouse.js b/lib/db/clickhouse.js index 9a4d2bb4..b5629656 100644 --- a/lib/db/clickhouse.js +++ b/lib/db/clickhouse.js @@ -38,7 +38,11 @@ const { parseLabels, hashLabels, isCustomSamplesOrderingRule, isOmitTablesCreati const { Worker, isMainThread } = require('worker_threads') -const jsonSerializer = (k, val) => typeof val === 'bigint' ? val.toString() : val +const jsonSerializer = (k, val) => typeof val === 'bigint' + ? val.toString() + : typeof val === 'number' && isNaN(val) + ? 'NaN' + : val const createCsvArrayWriter = require('csv-writer').createArrayCsvStringifier diff --git a/lib/handlers/common.js b/lib/handlers/common.js index 04c46974..7d903d15 100644 --- a/lib/handlers/common.js +++ b/lib/handlers/common.js @@ -59,6 +59,18 @@ module.exports.checkCustomPlugins = async (options) => { } } +/** + * + * @param value {number} + * @returns {[number,boolean]} new value and if I should ingest it + */ +module.exports.checkNanValue = (value) => { + if (typeof value === 'number' && isNaN(value)) { + return [NaN, true] + } + return [value, true] +} + const newResponse = () => { let head = null let onWriteHead = new EventEmitter() diff --git a/lib/handlers/influx_write.js b/lib/handlers/influx_write.js index dd3e33f5..a9a86111 100644 --- a/lib/handlers/influx_write.js +++ b/lib/handlers/influx_write.js @@ -43,6 +43,7 @@ const DATABASE = require('../db/clickhouse') const { bulk_labels, bulk, labels } = DATABASE.cache const { fingerPrint } = require('../utils') const { readonly } = require('../../common') +const { checkNanValue } = require('./common') async function handler (req, res) { if (!req.body && !req.body.metrics) { @@ -108,13 +109,14 @@ async function handler (req, res) { asyncLogError('no bulkable data', req.log) return res.code(204).send('') } - if (typeof value === 'number' && isNaN(value)) { + const [_value, ingest] = checkNanValue(value) + if (!ingest) { return } const values = [ finger, BigInt(pad('0000000000000000000', timestamp, true)), - value || 0, + _value || 0, key || '' ] bulk.add([values]) diff --git a/lib/handlers/prom_push.js b/lib/handlers/prom_push.js index e2712053..6caab169 100644 --- a/lib/handlers/prom_push.js +++ b/lib/handlers/prom_push.js @@ -17,6 +17,7 @@ const DATABASE = require('../db/clickhouse') const { bulk_labels, bulk, labels } = DATABASE.cache const { fingerPrint } = require('../utils') const { readonly } = require('../../common') +const { checkNanValue } = require('./common') async function handler (req, res) { const self = this @@ -59,14 +60,15 @@ async function handler (req, res) { asyncLogError({ entry }, req.log) return } - if (isNaN(entry.value)) { + const [value, ingest] = checkNanValue(entry.value) + if (!ingest) { return } const ts = BigInt(entry.timestamp) const values = [ finger, ts, - entry.value, + value, JSONLabels.__name__ || 'undefined' ] dates[