diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0267fe2..27e7716 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,14 +14,20 @@ You need: ### Building +### All the stack + +```shell +./build_and_start.sh +``` + #### Frontend ```bash -$ yarn install -$ yarn build +$ npm install +$ npm run build ``` -When developing the front, use `yarn dev`. +When developing the front, use `npm run dev`. #### Backend @@ -49,7 +55,6 @@ $ npm run test $ go test -v ./pkg/... ``` - ## Release TODO diff --git a/build_and_start.sh b/build_and_start.sh new file mode 100755 index 0000000..efbdaf6 --- /dev/null +++ b/build_and_start.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +npm install +npm run build +mage -v +docker-compose up --build --force-recreate diff --git a/docker-compose.yaml b/docker-compose.yaml index 5061f7d..75a87ab 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -12,7 +12,9 @@ services: volumes: - ./:/var/lib/grafana/plugins/grafana-quickwit-datasource - ./provisioning:/etc/grafana/provisioning - # - ./grafana/storage:/var/lib/grafana - # - ./grafana/grafana.ini:/etc/grafana/grafana.ini + - gquickwit:/var/lib/grafana extra_hosts: - "host.docker.internal:host-gateway" + +volumes: + gquickwit: diff --git a/package-lock.json b/package-lock.json index 23e5df8..940b05c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,10 +10,10 @@ "license": "AGPL-3.0", "dependencies": { "@emotion/css": "^11.1.3", - "@grafana/data": "9.5.1", + "@grafana/data": "9.5.14", "@grafana/experimental": "^1.1.0", - "@grafana/runtime": "9.5.1", - "@grafana/ui": "9.5.1", + "@grafana/runtime": "9.5.14", + "@grafana/ui": "9.5.14", "@reduxjs/toolkit": "^1.9.5", "react": "17.0.2", "react-dom": "17.0.2", @@ -1961,17 +1961,21 @@ "license": "MIT" }, "node_modules/@babel/runtime": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", - "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", - "license": "MIT", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz", + "integrity": "sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==", "dependencies": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, "node_modules/@babel/template": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", @@ -2587,13 +2591,12 @@ "license": "0BSD" }, "node_modules/@grafana/data": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/@grafana/data/-/data-9.5.1.tgz", - "integrity": "sha512-XXOV6cSGtBYQkSlQzVG4LaCjCdM49qacajTMU7a1wOKmDY9QJsFiKTbom7vQ1hHd+X83RqjndSJJiCFt7JX9LA==", - "license": "Apache-2.0", + "version": "9.5.14", + "resolved": "https://registry.npmjs.org/@grafana/data/-/data-9.5.14.tgz", + "integrity": "sha512-+AuogdRjmmHfazltEvuInMaH+wqvvpkhUAQXr92rharA59Lb++JIGp/iqOLdUMJSLBMag0bbK1azA8kmcPtiJQ==", "dependencies": { "@braintree/sanitize-url": "6.0.2", - "@grafana/schema": "9.5.1", + "@grafana/schema": "9.5.14", "@types/d3-interpolate": "^3.0.0", "d3-interpolate": "3.0.1", "date-fns": "2.29.3", @@ -2957,15 +2960,14 @@ } }, "node_modules/@grafana/runtime": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/@grafana/runtime/-/runtime-9.5.1.tgz", - "integrity": "sha512-8cnn+21JXbDaIQL7uEAPETRFMB4s0Im1TJRctL5eteafkU+xaqELwvZFHQnwXRNodkTd/MM4zCMq1R1PJBbxEA==", - "license": "Apache-2.0", + "version": "9.5.14", + "resolved": "https://registry.npmjs.org/@grafana/runtime/-/runtime-9.5.14.tgz", + "integrity": "sha512-H01nhzR+89kjVZIC4zgNCtwdeed6WplJdZ3ARJiLXwhqBIbLAd+3lHoeaxqgJnEwMrd2o/KO3y6Qkg3mrbEYxg==", "dependencies": { - "@grafana/data": "9.5.1", - "@grafana/e2e-selectors": "9.5.1", + "@grafana/data": "9.5.14", + "@grafana/e2e-selectors": "9.5.14", "@grafana/faro-web-sdk": "1.0.2", - "@grafana/ui": "9.5.1", + "@grafana/ui": "9.5.14", "@sentry/browser": "6.19.7", "history": "4.10.1", "lodash": "4.17.21", @@ -2979,10 +2981,9 @@ } }, "node_modules/@grafana/runtime/node_modules/@grafana/e2e-selectors": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/@grafana/e2e-selectors/-/e2e-selectors-9.5.1.tgz", - "integrity": "sha512-M8W0qw+mBZVKWVWtDTos+ttu5/NEGiHxsJk75J2dT5gPG+UvhsZvKKYB7DDDUof9a0QoKhgRYjok3EHMr2/bpQ==", - "license": "Apache-2.0", + "version": "9.5.14", + "resolved": "https://registry.npmjs.org/@grafana/e2e-selectors/-/e2e-selectors-9.5.14.tgz", + "integrity": "sha512-IcVSWq6F13I6/ub0yr7hWsfCwlg8FzJ/wPrnf6mGUprC6j/vVJihqWLHgXXdqVIWJ8zJC34u/sHDgCtmKoBgfQ==", "dependencies": { "@grafana/tsconfig": "^1.2.0-rc1", "tslib": "2.5.0", @@ -2995,10 +2996,9 @@ "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "node_modules/@grafana/schema": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/@grafana/schema/-/schema-9.5.1.tgz", - "integrity": "sha512-mLLeybp4HFqwmDbbu5lrJFq8cagHIPcRlvTlFllJfUO5KFNyCAUt2wERTZo85tKsuYQUxMgcR3qFkecH0aRrBw==", - "license": "Apache-2.0", + "version": "9.5.14", + "resolved": "https://registry.npmjs.org/@grafana/schema/-/schema-9.5.14.tgz", + "integrity": "sha512-CuntAhellcdR5VHDrrMgSLcNS10nQOySBCPHeaJVgiLdwCFovGrniV+dNtGXyutCEDzXo/SwK5iK9aWU38k0jA==", "dependencies": { "tslib": "2.5.0" } @@ -3015,17 +3015,16 @@ "license": "Apache-2.0" }, "node_modules/@grafana/ui": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/@grafana/ui/-/ui-9.5.1.tgz", - "integrity": "sha512-J0fA5KJnIRiQF+frlA8Az1h9onVgduoJgxvfsanc9CBeFpjM6ugCzdCgkmS7OrfEXoLnGxHfmzSKTyJ4dlMkEA==", - "license": "Apache-2.0", + "version": "9.5.14", + "resolved": "https://registry.npmjs.org/@grafana/ui/-/ui-9.5.14.tgz", + "integrity": "sha512-q6VsLqM32rAiQ2cfnuIu5DuY/7Foisf7rz9UyeXa2H04ik/gS84WbG/m+p7oHy7TsmZZEo5UJQdWHQ5T+2/WNQ==", "dependencies": { "@emotion/css": "11.10.6", "@emotion/react": "11.10.6", - "@grafana/data": "9.5.1", - "@grafana/e2e-selectors": "9.5.1", + "@grafana/data": "9.5.14", + "@grafana/e2e-selectors": "9.5.14", "@grafana/faro-web-sdk": "1.0.2", - "@grafana/schema": "9.5.1", + "@grafana/schema": "9.5.14", "@leeoniya/ufuzzy": "1.0.6", "@monaco-editor/react": "4.4.6", "@popperjs/core": "2.11.6", @@ -3199,10 +3198,9 @@ "license": "MIT" }, "node_modules/@grafana/ui/node_modules/@grafana/e2e-selectors": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/@grafana/e2e-selectors/-/e2e-selectors-9.5.1.tgz", - "integrity": "sha512-M8W0qw+mBZVKWVWtDTos+ttu5/NEGiHxsJk75J2dT5gPG+UvhsZvKKYB7DDDUof9a0QoKhgRYjok3EHMr2/bpQ==", - "license": "Apache-2.0", + "version": "9.5.14", + "resolved": "https://registry.npmjs.org/@grafana/e2e-selectors/-/e2e-selectors-9.5.14.tgz", + "integrity": "sha512-IcVSWq6F13I6/ub0yr7hWsfCwlg8FzJ/wPrnf6mGUprC6j/vVJihqWLHgXXdqVIWJ8zJC34u/sHDgCtmKoBgfQ==", "dependencies": { "@grafana/tsconfig": "^1.2.0-rc1", "tslib": "2.5.0", @@ -4360,18 +4358,6 @@ "react-dom": ">=16.9.0" } }, - "node_modules/@rc-component/portal/node_modules/@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.13.11" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@rc-component/portal/node_modules/rc-util": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.30.0.tgz", @@ -9689,8 +9675,7 @@ "node_modules/eventemitter3": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.0.tgz", - "integrity": "sha512-riuVbElZZNXLeLEoprfNYoDSwTBRR44X3mnhdI1YcnENpWTCsTTVZ2zFuqQcpoyqPQIUXdiPEU0ECAq0KQRaHg==", - "license": "MIT" + "integrity": "sha512-riuVbElZZNXLeLEoprfNYoDSwTBRR44X3mnhdI1YcnENpWTCsTTVZ2zFuqQcpoyqPQIUXdiPEU0ECAq0KQRaHg==" }, "node_modules/events": { "version": "3.3.0", @@ -10830,18 +10815,6 @@ "@babel/runtime": "^7.20.6" } }, - "node_modules/i18next/node_modules/@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.13.11" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -13280,7 +13253,6 @@ "version": "4.2.12", "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz", "integrity": "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==", - "license": "MIT", "bin": { "marked": "bin/marked.js" }, @@ -13740,7 +13712,6 @@ "version": "0.5.41", "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.41.tgz", "integrity": "sha512-e0jGNZDOHfBXJGz8vR/sIMXvBIGJJcqFjmlg9lmE+5KX1U7/RZNMswfD8nKnNCnQdKTIj50IaRKwl1fvMLyyRg==", - "license": "MIT", "dependencies": { "moment": "^2.29.4" }, @@ -14217,8 +14188,7 @@ "node_modules/papaparse": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.2.tgz", - "integrity": "sha512-6dNZu0Ki+gyV0eBsFKJhYr+MdQYAzFUGlBMNj3GNrmHxmz1lfRa24CjFObPXtjcetlOv5Ad299MhIK0znp3afw==", - "license": "MIT" + "integrity": "sha512-6dNZu0Ki+gyV0eBsFKJhYr+MdQYAzFUGlBMNj3GNrmHxmz1lfRa24CjFObPXtjcetlOv5Ad299MhIK0znp3afw==" }, "node_modules/parent-module": { "version": "1.0.1", @@ -15613,18 +15583,6 @@ "react-dom": "*" } }, - "node_modules/rc-virtual-list/node_modules/@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.13.11" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -15819,18 +15777,6 @@ } } }, - "node_modules/react-i18next/node_modules/@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.13.11" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/react-immutable-proptypes": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz", @@ -20460,11 +20406,18 @@ "dev": true }, "@babel/runtime": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", - "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz", + "integrity": "sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + } } }, "@babel/template": { @@ -20977,12 +20930,12 @@ } }, "@grafana/data": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/@grafana/data/-/data-9.5.1.tgz", - "integrity": "sha512-XXOV6cSGtBYQkSlQzVG4LaCjCdM49qacajTMU7a1wOKmDY9QJsFiKTbom7vQ1hHd+X83RqjndSJJiCFt7JX9LA==", + "version": "9.5.14", + "resolved": "https://registry.npmjs.org/@grafana/data/-/data-9.5.14.tgz", + "integrity": "sha512-+AuogdRjmmHfazltEvuInMaH+wqvvpkhUAQXr92rharA59Lb++JIGp/iqOLdUMJSLBMag0bbK1azA8kmcPtiJQ==", "requires": { "@braintree/sanitize-url": "6.0.2", - "@grafana/schema": "9.5.1", + "@grafana/schema": "9.5.14", "@types/d3-interpolate": "^3.0.0", "d3-interpolate": "3.0.1", "date-fns": "2.29.3", @@ -21262,14 +21215,14 @@ } }, "@grafana/runtime": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/@grafana/runtime/-/runtime-9.5.1.tgz", - "integrity": "sha512-8cnn+21JXbDaIQL7uEAPETRFMB4s0Im1TJRctL5eteafkU+xaqELwvZFHQnwXRNodkTd/MM4zCMq1R1PJBbxEA==", + "version": "9.5.14", + "resolved": "https://registry.npmjs.org/@grafana/runtime/-/runtime-9.5.14.tgz", + "integrity": "sha512-H01nhzR+89kjVZIC4zgNCtwdeed6WplJdZ3ARJiLXwhqBIbLAd+3lHoeaxqgJnEwMrd2o/KO3y6Qkg3mrbEYxg==", "requires": { - "@grafana/data": "9.5.1", - "@grafana/e2e-selectors": "9.5.1", + "@grafana/data": "9.5.14", + "@grafana/e2e-selectors": "9.5.14", "@grafana/faro-web-sdk": "1.0.2", - "@grafana/ui": "9.5.1", + "@grafana/ui": "9.5.14", "@sentry/browser": "6.19.7", "history": "4.10.1", "lodash": "4.17.21", @@ -21279,9 +21232,9 @@ }, "dependencies": { "@grafana/e2e-selectors": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/@grafana/e2e-selectors/-/e2e-selectors-9.5.1.tgz", - "integrity": "sha512-M8W0qw+mBZVKWVWtDTos+ttu5/NEGiHxsJk75J2dT5gPG+UvhsZvKKYB7DDDUof9a0QoKhgRYjok3EHMr2/bpQ==", + "version": "9.5.14", + "resolved": "https://registry.npmjs.org/@grafana/e2e-selectors/-/e2e-selectors-9.5.14.tgz", + "integrity": "sha512-IcVSWq6F13I6/ub0yr7hWsfCwlg8FzJ/wPrnf6mGUprC6j/vVJihqWLHgXXdqVIWJ8zJC34u/sHDgCtmKoBgfQ==", "requires": { "@grafana/tsconfig": "^1.2.0-rc1", "tslib": "2.5.0", @@ -21296,9 +21249,9 @@ } }, "@grafana/schema": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/@grafana/schema/-/schema-9.5.1.tgz", - "integrity": "sha512-mLLeybp4HFqwmDbbu5lrJFq8cagHIPcRlvTlFllJfUO5KFNyCAUt2wERTZo85tKsuYQUxMgcR3qFkecH0aRrBw==", + "version": "9.5.14", + "resolved": "https://registry.npmjs.org/@grafana/schema/-/schema-9.5.14.tgz", + "integrity": "sha512-CuntAhellcdR5VHDrrMgSLcNS10nQOySBCPHeaJVgiLdwCFovGrniV+dNtGXyutCEDzXo/SwK5iK9aWU38k0jA==", "requires": { "tslib": "2.5.0" }, @@ -21316,16 +21269,16 @@ "integrity": "sha512-+SgQeBQ1pT6D/E3/dEdADqTrlgdIGuexUZ8EU+8KxQFKUeFeU7/3z/ayI2q/wpJ/Kr6WxBBNlrST6aOKia19Ag==" }, "@grafana/ui": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/@grafana/ui/-/ui-9.5.1.tgz", - "integrity": "sha512-J0fA5KJnIRiQF+frlA8Az1h9onVgduoJgxvfsanc9CBeFpjM6ugCzdCgkmS7OrfEXoLnGxHfmzSKTyJ4dlMkEA==", + "version": "9.5.14", + "resolved": "https://registry.npmjs.org/@grafana/ui/-/ui-9.5.14.tgz", + "integrity": "sha512-q6VsLqM32rAiQ2cfnuIu5DuY/7Foisf7rz9UyeXa2H04ik/gS84WbG/m+p7oHy7TsmZZEo5UJQdWHQ5T+2/WNQ==", "requires": { "@emotion/css": "11.10.6", "@emotion/react": "11.10.6", - "@grafana/data": "9.5.1", - "@grafana/e2e-selectors": "9.5.1", + "@grafana/data": "9.5.14", + "@grafana/e2e-selectors": "9.5.14", "@grafana/faro-web-sdk": "1.0.2", - "@grafana/schema": "9.5.1", + "@grafana/schema": "9.5.14", "@leeoniya/ufuzzy": "1.0.6", "@monaco-editor/react": "4.4.6", "@popperjs/core": "2.11.6", @@ -21486,9 +21439,9 @@ "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" }, "@grafana/e2e-selectors": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/@grafana/e2e-selectors/-/e2e-selectors-9.5.1.tgz", - "integrity": "sha512-M8W0qw+mBZVKWVWtDTos+ttu5/NEGiHxsJk75J2dT5gPG+UvhsZvKKYB7DDDUof9a0QoKhgRYjok3EHMr2/bpQ==", + "version": "9.5.14", + "resolved": "https://registry.npmjs.org/@grafana/e2e-selectors/-/e2e-selectors-9.5.14.tgz", + "integrity": "sha512-IcVSWq6F13I6/ub0yr7hWsfCwlg8FzJ/wPrnf6mGUprC6j/vVJihqWLHgXXdqVIWJ8zJC34u/sHDgCtmKoBgfQ==", "requires": { "@grafana/tsconfig": "^1.2.0-rc1", "tslib": "2.5.0", @@ -22347,14 +22300,6 @@ "rc-util": "^5.24.4" }, "dependencies": { - "@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", - "requires": { - "regenerator-runtime": "^0.13.11" - } - }, "rc-util": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.30.0.tgz", @@ -26961,16 +26906,6 @@ "integrity": "sha512-yYudtbFrrmWKLEhl6jvKUYyYunj4bTBCe2qIUYAxbXoPusY7YmdwPvOE6fx6UIfWvmlbCWDItr7wIs8KEBZ5Zg==", "requires": { "@babel/runtime": "^7.20.6" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", - "requires": { - "regenerator-runtime": "^0.13.11" - } - } } }, "iconv-lite": { @@ -30301,16 +30236,6 @@ "classnames": "^2.2.6", "rc-resize-observer": "^1.0.0", "rc-util": "^5.15.0" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", - "requires": { - "regenerator-runtime": "^0.13.11" - } - } } }, "react": { @@ -30433,16 +30358,6 @@ "requires": { "@babel/runtime": "^7.20.6", "html-parse-stringify": "^3.0.1" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", - "requires": { - "regenerator-runtime": "^0.13.11" - } - } } }, "react-immutable-proptypes": { diff --git a/package.json b/package.json index 9dffae2..84818f3 100644 --- a/package.json +++ b/package.json @@ -61,10 +61,10 @@ }, "dependencies": { "@emotion/css": "^11.1.3", - "@grafana/data": "9.5.1", + "@grafana/data": "9.5.14", "@grafana/experimental": "^1.1.0", - "@grafana/runtime": "9.5.1", - "@grafana/ui": "9.5.1", + "@grafana/runtime": "9.5.14", + "@grafana/ui": "9.5.14", "@reduxjs/toolkit": "^1.9.5", "react": "17.0.2", "react-dom": "17.0.2", diff --git a/pkg/quickwit/client/client.go b/pkg/quickwit/client/client.go index 1a3d0d1..8124781 100644 --- a/pkg/quickwit/client/client.go +++ b/pkg/quickwit/client/client.go @@ -166,6 +166,13 @@ func (c *baseClientImpl) ExecuteMultisearch(r *MultiSearchRequest) (*MultiSearch c.logger.Debug("Received multisearch response", "code", res.StatusCode, "status", res.Status, "content-length", res.ContentLength) + if res.StatusCode >= 400 { + jsonResponseBody, _ := json.Marshal(res.Body) + jsonQueryParam, _ := json.Marshal(queryParams) + jsonRequestBody, _ := json.Marshal(r.Requests) + c.logger.Error("Error on multisearch: statusCode = " + strconv.Itoa(res.StatusCode) + ", responseBody = " + string(jsonResponseBody) + ", queryParam = " + string(jsonQueryParam) + ", requestBody = " + string(jsonRequestBody)) + } + start := time.Now() c.logger.Debug("Decoding multisearch json response") @@ -190,7 +197,6 @@ func (c *baseClientImpl) createMultiSearchRequests(searchRequests []*SearchReque for _, searchReq := range searchRequests { mr := multiRequest{ header: map[string]interface{}{ - "search_type": "query_then_fetch", "ignore_unavailable": true, "index": c.index, }, diff --git a/pkg/quickwit/client/client_test.go b/pkg/quickwit/client/client_test.go index 9dbbbc0..6098864 100644 --- a/pkg/quickwit/client/client_test.go +++ b/pkg/quickwit/client/client_test.go @@ -95,7 +95,6 @@ func TestClient_ExecuteMultisearch(t *testing.T) { assert.Equal(t, "my-index", jHeader.Get("index").MustString()) assert.True(t, jHeader.Get("ignore_unavailable").MustBool(false)) - assert.Equal(t, "query_then_fetch", jHeader.Get("search_type").MustString()) assert.Empty(t, jHeader.Get("max_concurrent_shard_requests")) assert.False(t, jHeader.Get("ignore_throttled").MustBool()) diff --git a/pkg/quickwit/client/search_request.go b/pkg/quickwit/client/search_request.go index 1c327c7..efe268a 100644 --- a/pkg/quickwit/client/search_request.go +++ b/pkg/quickwit/client/search_request.go @@ -101,11 +101,11 @@ func (b *SearchRequestBuilder) Sort(order SortOrder, field string, unmappedType return b } -func (b *SearchRequestBuilder) AddSearchAfter(value interface{}) *SearchRequestBuilder { +func (b *SearchRequestBuilder) AddSearchAfter(value any) *SearchRequestBuilder { if b.customProps["search_after"] == nil { - b.customProps["search_after"] = []interface{}{value} + b.customProps["search_after"] = []any{value} } else { - b.customProps["search_after"] = append(b.customProps["search_after"].([]interface{}), value) + b.customProps["search_after"] = append(b.customProps["search_after"].([]any), value) } return b diff --git a/pkg/quickwit/data_query.go b/pkg/quickwit/data_query.go index 32ee1f8..0bfb0be 100644 --- a/pkg/quickwit/data_query.go +++ b/pkg/quickwit/data_query.go @@ -335,17 +335,23 @@ func processLogsQuery(q *Query, b *es.SearchRequestBuilder, from, to int64, defa sort = es.SortOrderAsc } b.Sort(sort, defaultTimeField, "boolean") - // FIXME: check if sort by _doc is needed. - // b.Sort(sort, "_doc", "") + b.Sort(sort, "_doc", "") b.Size(stringToIntWithDefaultValue(metric.Settings.Get("limit").MustString(), defaultSize)) // TODO when hightlight is supported in quickwit // b.AddHighlight() + + // This is currently used only for log context query to get + // log lines before and after the selected log line + searchAfter := metric.Settings.Get("searchAfter").MustArray() + for _, value := range searchAfter { + b.AddSearchAfter(value) + } } func processDocumentQuery(q *Query, b *es.SearchRequestBuilder, from, to int64, defaultTimeField string) { metric := q.Metrics[0] b.Sort(es.SortOrderDesc, defaultTimeField, "boolean") - // b.Sort(es.SortOrderDesc, "_doc", "") + b.Sort(es.SortOrderDesc, "_doc", "") // Note: not supported in Quickwit // b.AddDocValueField(defaultTimeField) b.Size(stringToIntWithDefaultValue(metric.Settings.Get("size").MustString(), defaultSize)) diff --git a/pkg/quickwit/response_parser.go b/pkg/quickwit/response_parser.go index 990ca23..818d0bc 100644 --- a/pkg/quickwit/response_parser.go +++ b/pkg/quickwit/response_parser.go @@ -108,6 +108,7 @@ func processLogsResponse(res *es.SearchResponse, target *Query, configuredFields doc := map[string]interface{}{ "_source": flattened, + "sort": hit["sort"], } for k, v := range flattened { diff --git a/pkg/quickwit/response_parser_test.go b/pkg/quickwit/response_parser_test.go index 27d7658..e7f111d 100644 --- a/pkg/quickwit/response_parser_test.go +++ b/pkg/quickwit/response_parser_test.go @@ -304,7 +304,7 @@ func TestProcessLogsResponse(t *testing.T) { require.Len(t, dataframes, 1) frame := dataframes[0] - require.Equal(t, 11, len(frame.Fields)) + require.Equal(t, 12, len(frame.Fields)) // Fields have the correct length require.Equal(t, 2, frame.Fields[0].Len()) // First field is timeField @@ -324,7 +324,7 @@ func TestProcessLogsResponse(t *testing.T) { require.Equal(t, "nested.field.double_nested", frame.Fields[8].Name) require.Equal(t, data.FieldTypeNullableString, frame.Fields[8].Type()) // Correctly detects type even if first value is null - require.Equal(t, data.FieldTypeNullableString, frame.Fields[10].Type()) + require.Equal(t, data.FieldTypeNullableJSON, frame.Fields[10].Type()) }) } diff --git a/pkg/quickwit/snapshot_test.go b/pkg/quickwit/snapshot_test.go index 96aa06d..6758a48 100644 --- a/pkg/quickwit/snapshot_test.go +++ b/pkg/quickwit/snapshot_test.go @@ -82,8 +82,7 @@ package quickwit // queryHeader := []byte(` // { // "ignore_unavailable": true, -// "index": ["testdb-2022.11.14"], -// "search_type": "query_then_fetch" +// "index": ["testdb-2022.11.14"] // } // `) diff --git a/src/datasource.ts b/src/datasource.ts index 59bf6fd..36af503 100644 --- a/src/datasource.ts +++ b/src/datasource.ts @@ -4,32 +4,36 @@ import { catchError, mergeMap, map } from 'rxjs/operators'; import { AbstractQuery, + CoreApp, DataFrame, + DataQueryError, DataQueryRequest, DataQueryResponse, DataSourceApi, DataSourceInstanceSettings, DataSourceJsonData, + DataSourceWithLogsContextSupport, DataSourceWithQueryImportSupport, DataSourceWithSupplementaryQueriesSupport, + dateTime, FieldColorModeId, FieldType, getDefaultTimeRange, LoadingState, LogLevel, + LogRowModel, LogsVolumeCustomMetaData, LogsVolumeType, MetricFindValue, QueryFixAction, + rangeUtil, ScopedVars, SupplementaryQueryType, TimeRange, } from '@grafana/data'; -import { BucketAggregation, DataLinkConfig, ElasticsearchQuery, Field, FieldMapping, IndexMetadata, TermsQuery } from './types'; -import { - DataSourceWithBackend, getTemplateSrv, TemplateSrv, -} from '@grafana/runtime'; -import { QuickwitOptions } from 'quickwit'; +import { BucketAggregation, DataLinkConfig, ElasticsearchQuery, Field, FieldMapping, IndexMetadata, Logs, TermsQuery } from './types'; +import { DataSourceWithBackend, getTemplateSrv, TemplateSrv } from '@grafana/runtime'; +import { LogRowContextOptions, LogRowContextQueryDirection, QuickwitOptions } from 'quickwit'; import { ElasticQueryBuilder } from 'QueryBuilder'; import { colors } from '@grafana/ui'; @@ -39,7 +43,7 @@ import { isMetricAggregationWithField } from 'components/QueryEditor/MetricAggre import { bucketAggregationConfig } from 'components/QueryEditor/BucketAggregationsEditor/utils'; import { isBucketAggregationWithField } from 'components/QueryEditor/BucketAggregationsEditor/aggregations'; import ElasticsearchLanguageProvider from 'LanguageProvider'; - +import { ReactNode } from 'react'; export const REF_ID_STARTER_LOG_VOLUME = 'log-volume-'; @@ -48,6 +52,7 @@ export type ElasticDatasource = QuickwitDataSource; export class QuickwitDataSource extends DataSourceWithBackend implements + DataSourceWithLogsContextSupport, DataSourceWithSupplementaryQueriesSupport, DataSourceWithQueryImportSupport { @@ -427,6 +432,77 @@ export class QuickwitDataSource return text; } + private makeLogContextDataRequest = (row: LogRowModel, options?: LogRowContextOptions) => { + const direction = options?.direction || LogRowContextQueryDirection.Backward; + const searchAfter = row.dataFrame.fields.find((f) => f.name === 'sort')?.values.get(row.rowIndex) ?? [row.timeEpochNs] + + const logQuery: Logs = { + type: 'logs', + id: '1', + settings: { + limit: options?.limit ? options?.limit.toString() : '10', + // Sorting of results in the context query + sortDirection: direction === LogRowContextQueryDirection.Backward ? 'desc' : 'asc', + // Used to get the next log lines before/after the current log line using sort field of selected log line + searchAfter: searchAfter, + }, + }; + + const query: ElasticsearchQuery = { + refId: `log-context-${row.dataFrame.refId}-${direction}`, + metrics: [logQuery], + query: '', + }; + + const timeRange = createContextTimeRange(row.timeEpochMs, direction); + const range = { + from: timeRange.from, + to: timeRange.to, + raw: timeRange, + }; + + const interval = rangeUtil.calculateInterval(range, 1); + + const contextRequest: DataQueryRequest = { + requestId: `log-context-request-${row.dataFrame.refId}-${options?.direction}`, + targets: [query], + interval: interval.interval, + intervalMs: interval.intervalMs, + range, + scopedVars: {}, + timezone: 'UTC', + app: CoreApp.Explore, + startTime: Date.now(), + hideFromInspector: true, + }; + return contextRequest; + }; + + getLogRowContext = async (row: LogRowModel, options?: LogRowContextOptions): Promise<{ data: DataFrame[] }> => { + const contextRequest = this.makeLogContextDataRequest(row, options); + + return lastValueFrom( + this.query(contextRequest).pipe( + catchError((err) => { + const error: DataQueryError = { + message: 'Error during context query. Please check JS console logs.', + status: err.status, + statusText: err.statusText, + }; + throw error; + }) + ) + ); + }; + + showContextToggle(row?: LogRowModel | undefined): boolean { + return true; + } + + getLogRowContextUi?(row: LogRowModel, runContextQuery?: (() => void) | undefined): ReactNode { + return true; + } + /** * Returns false if the query should be skipped */ @@ -740,3 +816,20 @@ function luceneEscape(value: string) { return value.replace(/([\!\*\+\-\=<>\s\&\|\(\)\[\]\{\}\^\~\?\:\\/"])/g, '\\$1'); } + +function createContextTimeRange(rowTimeEpochMs: number, direction: string) { + const offset = 7; + // For log context, we want to request data from 7 subsequent/previous indices + if (direction === LogRowContextQueryDirection.Forward) { + return { + from: dateTime(rowTimeEpochMs).utc(), + to: dateTime(rowTimeEpochMs).add(offset, 'hours').utc(), + }; + } else { + return { + from: dateTime(rowTimeEpochMs).subtract(offset, 'hours').utc(), + to: dateTime(rowTimeEpochMs).utc(), + }; + } +} +