From 41a3570a85896ea3dded4511f9e8c5980da9662e Mon Sep 17 00:00:00 2001 From: Lorenzo Mangani Date: Sun, 11 Dec 2022 13:36:25 +0100 Subject: [PATCH 1/7] Create index.js Signed-off-by: Lorenzo Mangani --- plugins/mongo_filter/index.js | 59 +++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 plugins/mongo_filter/index.js diff --git a/plugins/mongo_filter/index.js b/plugins/mongo_filter/index.js new file mode 100644 index 00000000..d0ddb9e2 --- /dev/null +++ b/plugins/mongo_filter/index.js @@ -0,0 +1,59 @@ +const { PluginLoaderBase } = require('plugnplay') +const { compileMongoQuery } = require('mongo-query-compiler') + +/** + +Mongodb-like JSON filtering output processor. +Usage: mongo({age: {$exists: true}}, {type="people"} + +**/ + +/** + * @class Plugin + * @property {string} query + * @property start {number} start in NS + * @property end {string} end in NS + * @property type {string} promql or logql + * @property limit {number} + * @property {{ + * logql: (query: string, startNS: number, endNS: number, limit: number) => Promise + * }} API + * promql: (query: string, startNS: number, endNS: number, limit: number) => Promise //not implemented + */ +class Plugin { + /** + * @method + * @name check + * @this {Plg} + * @returns {boolean} if this plugin is usable for the query + */ + check () { + return this.query.match(/^mongo\(.+\)\s*$/) + } + + /** + * @method + * @name process + * @this {Plg} + * @returns {Promise<{type: string, out: string}>} The raw output + */ + async process () { + const match = this.query.match(/^mongo\({(.+)}, (.+)\)$/) + const response = await this.API.logql(match[2], this.start, this.end, this.limit) + // Filter using Mongo Query Compiler + let query = match[2]; + let filterer = compileMongoQuery(query); + let results = response.data.result.filter(filterer); + return { + type: 'application/json', + out: results + } + } +} +class Plg extends PluginLoaderBase { + exportSync (api) { + return new Plugin() + } +} + +module.exports = Plg From 42cf5af19057ec77052cffe0d4d5be9cb716bca3 Mon Sep 17 00:00:00 2001 From: Lorenzo Mangani Date: Sun, 11 Dec 2022 13:37:32 +0100 Subject: [PATCH 2/7] Create plugnplay.yml Signed-off-by: Lorenzo Mangani --- plugins/mongo_filter/plugnplay.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 plugins/mongo_filter/plugnplay.yml diff --git a/plugins/mongo_filter/plugnplay.yml b/plugins/mongo_filter/plugnplay.yml new file mode 100644 index 00000000..bd33ddfc --- /dev/null +++ b/plugins/mongo_filter/plugnplay.yml @@ -0,0 +1,5 @@ +id: mongo_filter +name: Format Output +description: Filter JSON using MongoDB functions +loader: index.js +type: custom_processor From 3467f3b08dafa9438d8763941a040d0387017fd5 Mon Sep 17 00:00:00 2001 From: Lorenzo Mangani Date: Sun, 11 Dec 2022 13:41:56 +0100 Subject: [PATCH 3/7] Create README.md Signed-off-by: Lorenzo Mangani --- plugins/mongo_filter/README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 plugins/mongo_filter/README.md diff --git a/plugins/mongo_filter/README.md b/plugins/mongo_filter/README.md new file mode 100644 index 00000000..9abd1e42 --- /dev/null +++ b/plugins/mongo_filter/README.md @@ -0,0 +1,18 @@ +## qryn-plugin + +### mongo + +This plugin uses the [Mongo Query Compiler](https://github.com/aptivator/mongo-query-compiler-docs) library to transpile mongodb-like +query objects into a JavaScript filtering functions to be used with any array's .filter() method to isolate the needed data subset. + +### Example + +Original LogQL Selector: +``` +{type="people"} |="alive" | json +``` + +Mongo Filter: +``` +mongo({age: {$exists: true}}, {type="people"} |="alive" | json) +``` From e796bfa56e8f73125a9f6a1dd5e175a906414114 Mon Sep 17 00:00:00 2001 From: Lorenzo Mangani Date: Sun, 11 Dec 2022 13:43:44 +0100 Subject: [PATCH 4/7] add mongo-query-compiler to package Signed-off-by: Lorenzo Mangani --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 587d102b..dc6a52e4 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "handlebars": "^4.7.7", "handlebars-helpers": "^0.9.8", "logfmt": "^1.3.2", + "mongo-query-compiler": "^1.0.4", "json-stable-stringify": "^1.0.1", "jsonic": "^0.3.1", "patch-package": "^6.4.7", From 80eca1f96a02b702ced8294c52539664e8e082a4 Mon Sep 17 00:00:00 2001 From: Lorenzo Mangani Date: Sun, 11 Dec 2022 13:51:41 +0100 Subject: [PATCH 5/7] Update index.js Signed-off-by: Lorenzo Mangani --- plugins/mongo_filter/index.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/mongo_filter/index.js b/plugins/mongo_filter/index.js index d0ddb9e2..990df0df 100644 --- a/plugins/mongo_filter/index.js +++ b/plugins/mongo_filter/index.js @@ -38,10 +38,14 @@ class Plugin { * @returns {Promise<{type: string, out: string}>} The raw output */ async process () { - const match = this.query.match(/^mongo\({(.+)}, (.+)\)$/) + const match = this.query.match(/^mongo\({(.+)},\s*(.+)\)$/) const response = await this.API.logql(match[2], this.start, this.end, this.limit) + + // Sanity Check. What error should this return? + if (!match || !match[1] || !match[2]) return response; + // Filter using Mongo Query Compiler - let query = match[2]; + let query = match[1]; let filterer = compileMongoQuery(query); let results = response.data.result.filter(filterer); return { From 56f4a21fd18d0f23d718c21646a302504b47d90e Mon Sep 17 00:00:00 2001 From: Lorenzo Mangani Date: Fri, 16 Dec 2022 18:56:03 +0100 Subject: [PATCH 6/7] Update index.js Signed-off-by: Lorenzo Mangani --- plugins/mongo_filter/index.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/mongo_filter/index.js b/plugins/mongo_filter/index.js index 990df0df..e7bacf2d 100644 --- a/plugins/mongo_filter/index.js +++ b/plugins/mongo_filter/index.js @@ -39,18 +39,17 @@ class Plugin { */ async process () { const match = this.query.match(/^mongo\({(.+)},\s*(.+)\)$/) - const response = await this.API.logql(match[2], this.start, this.end, this.limit) + let response = await this.API.logql(match[2], this.start, this.end, this.limit) // Sanity Check. What error should this return? if (!match || !match[1] || !match[2]) return response; // Filter using Mongo Query Compiler - let query = match[1]; - let filterer = compileMongoQuery(query); - let results = response.data.result.filter(filterer); + let filterer = compileMongoQuery(match[1]); + response.data.result = response.data.result.filter(filterer); return { type: 'application/json', - out: results + out: response } } } From 32afb0d553481f4ab96a7e136dad8a45e7afb9a1 Mon Sep 17 00:00:00 2001 From: Lorenzo Mangani Date: Fri, 16 Dec 2022 19:18:52 +0100 Subject: [PATCH 7/7] Update README.md Signed-off-by: Lorenzo Mangani --- plugins/mongo_filter/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/mongo_filter/README.md b/plugins/mongo_filter/README.md index 9abd1e42..ddbbb21a 100644 --- a/plugins/mongo_filter/README.md +++ b/plugins/mongo_filter/README.md @@ -14,5 +14,8 @@ Original LogQL Selector: Mongo Filter: ``` -mongo({age: {$exists: true}}, {type="people"} |="alive" | json) +mongo({stream: { event: { $exists: true }}}, {type="people"} |="alive" | json) +``` +``` +mongo({$where: 'this.stream.event === "user"'}, {type="people"} |="alive" | json ) ```