diff --git a/.github/workflows/jest-coverage-changes.yml b/.github/workflows/jest-coverage-changes.yml new file mode 100644 index 0000000000..56d4cf1b70 --- /dev/null +++ b/.github/workflows/jest-coverage-changes.yml @@ -0,0 +1,31 @@ +name: Jest Coverage - changed files + +on: + pull_request: + branches: develop + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: "refs/heads/develop" + token: ${{ secrets.GITHUB_TOKEN }} # Provide the GitHub token for authentication + + - name: Fetch branch + run: git fetch origin ${{ github.event.pull_request.head.ref }} + + - run: | + git checkout ${{ github.event.pull_request.head.sha }} + + - uses: actions/setup-node@v4 + with: + node-version: lts/* + + - name: Install dependencies + run: cd frontend && npm install -g yarn && yarn + + - name: npm run test:changedsince + run: cd frontend && npm run i18n:generate-hash && npm run test:changedsince diff --git a/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml b/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml index 6ef82a62db..2422674dbc 100644 --- a/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml +++ b/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml @@ -22,7 +22,7 @@ x-clickhouse-defaults: &clickhouse-defaults "wget", "--spider", "-q", - "localhost:8123/ping" + "0.0.0.0:8123/ping" ] interval: 30s timeout: 5s @@ -146,7 +146,7 @@ services: condition: on-failure query-service: - image: signoz/query-service:0.43.0 + image: signoz/query-service:0.44.0 command: [ "-config=/root/config/prometheus.yml", @@ -186,7 +186,7 @@ services: <<: *db-depend frontend: - image: signoz/frontend:0.43.0 + image: signoz/frontend:0.44.0 deploy: restart_policy: condition: on-failure @@ -199,7 +199,7 @@ services: - ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf otel-collector: - image: signoz/signoz-otel-collector:0.88.20 + image: signoz/signoz-otel-collector:0.88.21 command: [ "--config=/etc/otel-collector-config.yaml", @@ -237,7 +237,7 @@ services: - query-service otel-collector-migrator: - image: signoz/signoz-schema-migrator:0.88.20 + image: signoz/signoz-schema-migrator:0.88.21 deploy: restart_policy: condition: on-failure diff --git a/deploy/docker-swarm/clickhouse-setup/otel-collector-config.yaml b/deploy/docker-swarm/clickhouse-setup/otel-collector-config.yaml index f8a710d535..32cd007d3a 100644 --- a/deploy/docker-swarm/clickhouse-setup/otel-collector-config.yaml +++ b/deploy/docker-swarm/clickhouse-setup/otel-collector-config.yaml @@ -111,18 +111,18 @@ processors: exporters: clickhousetraces: - datasource: tcp://clickhouse:9000/?database=signoz_traces + datasource: tcp://clickhouse:9000/signoz_traces docker_multi_node_cluster: ${DOCKER_MULTI_NODE_CLUSTER} low_cardinal_exception_grouping: ${LOW_CARDINAL_EXCEPTION_GROUPING} clickhousemetricswrite: - endpoint: tcp://clickhouse:9000/?database=signoz_metrics + endpoint: tcp://clickhouse:9000/signoz_metrics resource_to_telemetry_conversion: enabled: true clickhousemetricswrite/prometheus: - endpoint: tcp://clickhouse:9000/?database=signoz_metrics + endpoint: tcp://clickhouse:9000/signoz_metrics # logging: {} clickhouselogsexporter: - dsn: tcp://clickhouse:9000/ + dsn: tcp://clickhouse:9000/signoz_logs docker_multi_node_cluster: ${DOCKER_MULTI_NODE_CLUSTER} timeout: 10s extensions: diff --git a/deploy/docker-swarm/clickhouse-setup/prometheus.yml b/deploy/docker-swarm/clickhouse-setup/prometheus.yml index 6a796ea1d0..d7c52893c5 100644 --- a/deploy/docker-swarm/clickhouse-setup/prometheus.yml +++ b/deploy/docker-swarm/clickhouse-setup/prometheus.yml @@ -22,4 +22,4 @@ rule_files: scrape_configs: [] remote_read: - - url: tcp://clickhouse:9000/?database=signoz_metrics + - url: tcp://clickhouse:9000/signoz_metrics diff --git a/deploy/docker/clickhouse-setup/docker-compose-core.yaml b/deploy/docker/clickhouse-setup/docker-compose-core.yaml index ba9047ddf8..c16a0e0db0 100644 --- a/deploy/docker/clickhouse-setup/docker-compose-core.yaml +++ b/deploy/docker/clickhouse-setup/docker-compose-core.yaml @@ -46,7 +46,7 @@ services: "wget", "--spider", "-q", - "localhost:8123/ping" + "0.0.0.0:8123/ping" ] interval: 30s timeout: 5s @@ -66,7 +66,7 @@ services: - --storage.path=/data otel-collector-migrator: - image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.20} + image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.21} container_name: otel-migrator command: - "--dsn=tcp://clickhouse:9000" @@ -81,7 +81,7 @@ services: # Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md` otel-collector: container_name: signoz-otel-collector - image: signoz/signoz-otel-collector:0.88.20 + image: signoz/signoz-otel-collector:0.88.21 command: [ "--config=/etc/otel-collector-config.yaml", diff --git a/deploy/docker/clickhouse-setup/docker-compose.yaml b/deploy/docker/clickhouse-setup/docker-compose.yaml index f7702fa6c1..30ee165805 100644 --- a/deploy/docker/clickhouse-setup/docker-compose.yaml +++ b/deploy/docker/clickhouse-setup/docker-compose.yaml @@ -21,7 +21,7 @@ x-clickhouse-defaults: &clickhouse-defaults "wget", "--spider", "-q", - "localhost:8123/ping" + "0.0.0.0:8123/ping" ] interval: 30s timeout: 5s @@ -164,7 +164,7 @@ services: # Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md` query-service: - image: signoz/query-service:${DOCKER_TAG:-0.43.0} + image: signoz/query-service:${DOCKER_TAG:-0.44.0} container_name: signoz-query-service command: [ @@ -203,7 +203,7 @@ services: <<: *db-depend frontend: - image: signoz/frontend:${DOCKER_TAG:-0.43.0} + image: signoz/frontend:${DOCKER_TAG:-0.44.0} container_name: signoz-frontend restart: on-failure depends_on: @@ -215,7 +215,7 @@ services: - ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf otel-collector-migrator: - image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.20} + image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.21} container_name: otel-migrator command: - "--dsn=tcp://clickhouse:9000" @@ -229,7 +229,7 @@ services: otel-collector: - image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.88.20} + image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.88.21} container_name: signoz-otel-collector command: [ diff --git a/deploy/docker/clickhouse-setup/otel-collector-config.yaml b/deploy/docker/clickhouse-setup/otel-collector-config.yaml index d382a252e5..7a103d10bf 100644 --- a/deploy/docker/clickhouse-setup/otel-collector-config.yaml +++ b/deploy/docker/clickhouse-setup/otel-collector-config.yaml @@ -122,21 +122,20 @@ extensions: exporters: clickhousetraces: - datasource: tcp://clickhouse:9000/?database=signoz_traces + datasource: tcp://clickhouse:9000/signoz_traces docker_multi_node_cluster: ${DOCKER_MULTI_NODE_CLUSTER} low_cardinal_exception_grouping: ${LOW_CARDINAL_EXCEPTION_GROUPING} clickhousemetricswrite: - endpoint: tcp://clickhouse:9000/?database=signoz_metrics + endpoint: tcp://clickhouse:9000/signoz_metrics resource_to_telemetry_conversion: enabled: true clickhousemetricswrite/prometheus: - endpoint: tcp://clickhouse:9000/?database=signoz_metrics - # logging: {} - + endpoint: tcp://clickhouse:9000/signoz_metrics clickhouselogsexporter: - dsn: tcp://clickhouse:9000/ + dsn: tcp://clickhouse:9000/signoz_logs docker_multi_node_cluster: ${DOCKER_MULTI_NODE_CLUSTER} timeout: 10s + # logging: {} service: telemetry: diff --git a/deploy/docker/clickhouse-setup/prometheus.yml b/deploy/docker/clickhouse-setup/prometheus.yml index 6a796ea1d0..d7c52893c5 100644 --- a/deploy/docker/clickhouse-setup/prometheus.yml +++ b/deploy/docker/clickhouse-setup/prometheus.yml @@ -22,4 +22,4 @@ rule_files: scrape_configs: [] remote_read: - - url: tcp://clickhouse:9000/?database=signoz_metrics + - url: tcp://clickhouse:9000/signoz_metrics diff --git a/frontend/jest.config.ts b/frontend/jest.config.ts index 7b52ca5cf6..8737901922 100644 --- a/frontend/jest.config.ts +++ b/frontend/jest.config.ts @@ -35,6 +35,14 @@ const config: Config.InitialOptions = { browsers: ['chromium', 'firefox', 'webkit'], }, }, + coverageThreshold: { + global: { + statements: 80, + branches: 65, + functions: 80, + lines: 80, + }, + }, }; export default config; diff --git a/frontend/package.json b/frontend/package.json index 6040b2e3f0..86a7a80328 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -21,7 +21,9 @@ "playwright:codegen:local": "playwright codegen http://localhost:3301", "playwright:codegen:local:auth": "yarn playwright:codegen:local --load-storage=tests/auth.json", "husky:configure": "cd .. && husky install frontend/.husky && cd frontend && chmod ug+x .husky/*", - "commitlint": "commitlint --edit $1" + "commitlint": "commitlint --edit $1", + "test": "jest --coverage", + "test:changedsince": "jest --changedSince=develop --coverage --silent" }, "engines": { "node": ">=16.15.0" diff --git a/frontend/src/components/ResizeTable/DynamicColumnTable.tsx b/frontend/src/components/ResizeTable/DynamicColumnTable.tsx index 401517206f..fb5d734ee8 100644 --- a/frontend/src/components/ResizeTable/DynamicColumnTable.tsx +++ b/frontend/src/components/ResizeTable/DynamicColumnTable.tsx @@ -1,8 +1,9 @@ /* eslint-disable react/jsx-props-no-spreading */ import './DynamicColumnTable.syles.scss'; -import { Button, Dropdown, MenuProps, Switch } from 'antd'; +import { Button, Dropdown, Flex, MenuProps, Switch } from 'antd'; import { ColumnsType } from 'antd/lib/table'; +import FacingIssueBtn from 'components/facingIssueBtn/FacingIssueBtn'; import { SlidersHorizontal } from 'lucide-react'; import { memo, useEffect, useState } from 'react'; import { popupContainer } from 'utils/selectPopupContainer'; @@ -20,6 +21,7 @@ function DynamicColumnTable({ columns, dynamicColumns, onDragColumn, + facingIssueBtn, ...restProps }: DynamicColumnTableProps): JSX.Element { const [columnsData, setColumnsData] = useState( @@ -83,19 +85,22 @@ function DynamicColumnTable({ return (
- {dynamicColumns && ( - - +
+ ) : null; +} + +FacingIssueBtn.defaultProps = { + message: '', + buttonText: '', + className: '', +}; + +export default FacingIssueBtn; diff --git a/frontend/src/container/BillingContainer/BillingContainer.styles.scss b/frontend/src/container/BillingContainer/BillingContainer.styles.scss index 05a672b18c..e4c7deec06 100644 --- a/frontend/src/container/BillingContainer/BillingContainer.styles.scss +++ b/frontend/src/container/BillingContainer/BillingContainer.styles.scss @@ -1,4 +1,5 @@ .billing-container { + margin-bottom: 40px; padding-top: 36px; width: 65%; diff --git a/frontend/src/container/CreateAlertRule/index.tsx b/frontend/src/container/CreateAlertRule/index.tsx index a5924531b2..5a98cd2d8e 100644 --- a/frontend/src/container/CreateAlertRule/index.tsx +++ b/frontend/src/container/CreateAlertRule/index.tsx @@ -2,6 +2,7 @@ import { Form, Row } from 'antd'; import { ENTITY_VERSION_V4 } from 'constants/app'; import FormAlertRules from 'container/FormAlertRules'; import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam'; +import { isEqual } from 'lodash-es'; import { useEffect, useState } from 'react'; import { useLocation } from 'react-router-dom'; import { AlertTypes } from 'types/api/alerts/alertTypes'; @@ -18,9 +19,7 @@ import SelectAlertType from './SelectAlertType'; function CreateRules(): JSX.Element { const [initValues, setInitValues] = useState(null); - const [alertType, setAlertType] = useState( - AlertTypes.METRICS_BASED_ALERT, - ); + const [alertType, setAlertType] = useState(); const location = useLocation(); const queryParams = new URLSearchParams(location.search); @@ -56,10 +55,10 @@ function CreateRules(): JSX.Element { } const dataSource = compositeQuery?.builder?.queryData[0]?.dataSource; - const alertType = ALERT_TYPE_VS_SOURCE_MAPPING[dataSource]; + const alertTypeFromQuery = ALERT_TYPE_VS_SOURCE_MAPPING[dataSource]; - if (alertType) { - onSelectType(alertType); + if (alertTypeFromQuery && !isEqual(alertType, alertTypeFromQuery)) { + onSelectType(alertTypeFromQuery); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [compositeQuery]); diff --git a/frontend/src/container/FormAlertRules/FormAlertRules.styles.scss b/frontend/src/container/FormAlertRules/FormAlertRules.styles.scss index 4ebb81c146..68d36c561f 100644 --- a/frontend/src/container/FormAlertRules/FormAlertRules.styles.scss +++ b/frontend/src/container/FormAlertRules/FormAlertRules.styles.scss @@ -1,45 +1,50 @@ .create-alert-modal { - .ant-modal-content { - background-color: var(--bg-ink-300); - .ant-modal-confirm-title { - color: var(--bg-vanilla-100); - } + .ant-modal-content { + background-color: var(--bg-ink-300); + .ant-modal-confirm-title { + color: var(--bg-vanilla-100); + } - .ant-modal-confirm-content { - .ant-typography { - color: var(--bg-vanilla-100); - } - } + .ant-modal-confirm-content { + .ant-typography { + color: var(--bg-vanilla-100); + } + } - .ant-modal-confirm-btns { - button:nth-of-type(1) { - background-color: var(--bg-slate-400); - border: none; - color: var(--bg-vanilla-100); - } - } - } + .ant-modal-confirm-btns { + button:nth-of-type(1) { + background-color: var(--bg-slate-400); + border: none; + color: var(--bg-vanilla-100); + } + } + } } .lightMode { - .ant-modal-content { - background-color: var(--bg-vanilla-100); - .ant-modal-confirm-title { - color: var(--bg-ink-500); - } + .ant-modal-content { + background-color: var(--bg-vanilla-100); + .ant-modal-confirm-title { + color: var(--bg-ink-500); + } - .ant-modal-confirm-content { - .ant-typography { - color: var(--bg-ink-500); - } - } + .ant-modal-confirm-content { + .ant-typography { + color: var(--bg-ink-500); + } + } - .ant-modal-confirm-btns { - button:nth-of-type(1) { - background-color: var(--bg-vanilla-300); - border: none; - color: var(--bg-ink-500); - } - } - } -} \ No newline at end of file + .ant-modal-confirm-btns { + button:nth-of-type(1) { + background-color: var(--bg-vanilla-300); + border: none; + color: var(--bg-ink-500); + } + } + } +} + +.facing-issue-btn { + margin-top: 20px; + width: 100%; +} diff --git a/frontend/src/container/FormAlertRules/index.tsx b/frontend/src/container/FormAlertRules/index.tsx index 09d4a957a7..70c035feb7 100644 --- a/frontend/src/container/FormAlertRules/index.tsx +++ b/frontend/src/container/FormAlertRules/index.tsx @@ -11,6 +11,7 @@ import { } from 'antd'; import saveAlertApi from 'api/alerts/save'; import testAlertApi from 'api/alerts/testAlert'; +import FacingIssueBtn from 'components/facingIssueBtn/FacingIssueBtn'; import { FeatureKeys } from 'constants/features'; import { QueryParams } from 'constants/query'; import { PANEL_TYPES } from 'constants/queryBuilder'; @@ -138,15 +139,21 @@ function FormAlertRules({ useEffect(() => { // Set selectedQueryName based on the length of queryOptions - setAlertDef((def) => ({ - ...def, - condition: { - ...def.condition, - selectedQueryName: - queryOptions.length > 0 ? String(queryOptions[0].value) : undefined, - }, - })); - }, [currentQuery?.queryType, queryOptions]); + const selectedQueryName = alertDef?.condition?.selectedQueryName; + if ( + !selectedQueryName || + !queryOptions.some((option) => option.value === selectedQueryName) + ) { + setAlertDef((def) => ({ + ...def, + condition: { + ...def.condition, + selectedQueryName: + queryOptions.length > 0 ? String(queryOptions[0].value) : undefined, + }, + })); + } + }, [alertDef, currentQuery?.queryType, queryOptions]); const onCancelHandler = useCallback(() => { history.replace(ROUTES.LIST_ALL_ALERT); @@ -482,6 +489,8 @@ function FormAlertRules({ alertDef?.broadcastToAll || (alertDef.preferredChannels && alertDef.preferredChannels.length > 0); + const isRuleCreated = !ruleId || ruleId === 0; + return ( <> {Element} @@ -563,6 +572,30 @@ function FormAlertRules({ + diff --git a/frontend/src/container/GridCardLayout/GridCardLayout.tsx b/frontend/src/container/GridCardLayout/GridCardLayout.tsx index b84e88b292..24f13ec9e2 100644 --- a/frontend/src/container/GridCardLayout/GridCardLayout.tsx +++ b/frontend/src/container/GridCardLayout/GridCardLayout.tsx @@ -1,7 +1,8 @@ import './GridCardLayout.styles.scss'; import { PlusOutlined } from '@ant-design/icons'; -import { Tooltip } from 'antd'; +import { Flex, Tooltip } from 'antd'; +import FacingIssueBtn from 'components/facingIssueBtn/FacingIssueBtn'; import { SOMETHING_WENT_WRONG } from 'constants/api'; import { QueryParams } from 'constants/query'; import { PANEL_TYPES } from 'constants/queryBuilder'; @@ -169,28 +170,47 @@ function GraphLayout({ onAddPanelHandler }: GraphLayoutProps): JSX.Element { return ( <> - - - - )} - + + + + + + )} + + ); diff --git a/frontend/src/container/ListOfDashboard/DashboardsList.tsx b/frontend/src/container/ListOfDashboard/DashboardsList.tsx index 7e904c6d26..cb975f9f2c 100644 --- a/frontend/src/container/ListOfDashboard/DashboardsList.tsx +++ b/frontend/src/container/ListOfDashboard/DashboardsList.tsx @@ -385,6 +385,18 @@ function DashboardsList(): JSX.Element { dataSource={data} onChange={handleChange} showSorterTooltip + facingIssueBtn={{ + attributes: { + screen: 'Dashboard list page', + }, + eventName: 'Dashboard: Facing Issues in dashboard', + buttonText: 'Facing Issues in dashboard', + message: `Hi Team, + +I am facing issues with dashboards. + +Thanks`, + }} /> diff --git a/frontend/src/container/NewDashboard/ComponentsSlider/index.tsx b/frontend/src/container/NewDashboard/ComponentsSlider/index.tsx index 10adefa7c1..a61255705a 100644 --- a/frontend/src/container/NewDashboard/ComponentsSlider/index.tsx +++ b/frontend/src/container/NewDashboard/ComponentsSlider/index.tsx @@ -1,146 +1,59 @@ -import { SOMETHING_WENT_WRONG } from 'constants/api'; import { QueryParams } from 'constants/query'; import { PANEL_TYPES } from 'constants/queryBuilder'; -import { useUpdateDashboard } from 'hooks/dashboard/useUpdateDashboard'; -import { useNotifications } from 'hooks/useNotifications'; import createQueryParams from 'lib/createQueryParams'; import history from 'lib/history'; import { useDashboard } from 'providers/Dashboard/Dashboard'; import { LogsAggregatorOperator } from 'types/common/queryBuilder'; import { v4 as uuid } from 'uuid'; -import { - listViewInitialLogQuery, - listViewInitialTraceQuery, - PANEL_TYPES_INITIAL_QUERY, -} from './constants'; +import { PANEL_TYPES_INITIAL_QUERY } from './constants'; import menuItems from './menuItems'; import { Card, Container, Text } from './styles'; function DashboardGraphSlider(): JSX.Element { - const { - handleToggleDashboardSlider, - layouts, - selectedDashboard, - } = useDashboard(); - - const { data } = selectedDashboard || {}; - - const { notifications } = useNotifications(); - - const updateDashboardMutation = useUpdateDashboard(); + const { handleToggleDashboardSlider } = useDashboard(); // eslint-disable-next-line sonarjs/cognitive-complexity const onClickHandler = (name: PANEL_TYPES) => (): void => { const id = uuid(); - - updateDashboardMutation.mutateAsync( - { - uuid: selectedDashboard?.uuid || '', - data: { - title: data?.title || '', - variables: data?.variables || {}, - description: data?.description || '', - name: data?.name || '', - tags: data?.tags || [], - version: data?.version || 'v3', - layout: [ + handleToggleDashboardSlider(false); + const queryParamsLog = { + graphType: name, + widgetId: id, + [QueryParams.compositeQuery]: JSON.stringify({ + ...PANEL_TYPES_INITIAL_QUERY[name], + builder: { + ...PANEL_TYPES_INITIAL_QUERY[name].builder, + queryData: [ { - i: id, - w: 6, - x: 0, - h: 3, - y: 0, - }, - ...(layouts.filter((layout) => layout.i !== PANEL_TYPES.EMPTY_WIDGET) || - []), - ], - widgets: [ - ...(data?.widgets || []), - { - id, - title: '', - description: '', - isStacked: false, - nullZeroValues: '', - opacity: '', - panelTypes: name, - query: - name === PANEL_TYPES.LIST - ? listViewInitialLogQuery - : PANEL_TYPES_INITIAL_QUERY[name], - timePreferance: 'GLOBAL_TIME', - softMax: null, - softMin: null, - selectedLogFields: [ - { - dataType: 'string', - type: '', - name: 'body', - }, - { - dataType: 'string', - type: '', - name: 'timestamp', - }, - ], - selectedTracesFields: [ - ...listViewInitialTraceQuery.builder.queryData[0].selectColumns, - ], + ...PANEL_TYPES_INITIAL_QUERY[name].builder.queryData[0], + aggregateOperator: LogsAggregatorOperator.NOOP, + orderBy: [{ columnName: 'timestamp', order: 'desc' }], + offset: 0, + pageSize: 100, }, ], }, - }, - { - onSuccess: (data) => { - if (data.payload) { - handleToggleDashboardSlider(false); - const queryParamsLog = { - graphType: name, - widgetId: id, - [QueryParams.compositeQuery]: JSON.stringify({ - ...PANEL_TYPES_INITIAL_QUERY[name], - builder: { - ...PANEL_TYPES_INITIAL_QUERY[name].builder, - queryData: [ - { - ...PANEL_TYPES_INITIAL_QUERY[name].builder.queryData[0], - aggregateOperator: LogsAggregatorOperator.NOOP, - orderBy: [{ columnName: 'timestamp', order: 'desc' }], - offset: 0, - pageSize: 100, - }, - ], - }, - }), - }; + }), + }; - const queryParams = { - graphType: name, - widgetId: id, - [QueryParams.compositeQuery]: JSON.stringify( - PANEL_TYPES_INITIAL_QUERY[name], - ), - }; + const queryParams = { + graphType: name, + widgetId: id, + [QueryParams.compositeQuery]: JSON.stringify( + PANEL_TYPES_INITIAL_QUERY[name], + ), + }; - if (name === PANEL_TYPES.LIST) { - history.push( - `${history.location.pathname}/new?${createQueryParams(queryParamsLog)}`, - ); - } else { - history.push( - `${history.location.pathname}/new?${createQueryParams(queryParams)}`, - ); - } - } - }, - onError: () => { - notifications.success({ - message: SOMETHING_WENT_WRONG, - }); - }, - }, - ); + if (name === PANEL_TYPES.LIST) { + history.push( + `${history.location.pathname}/new?${createQueryParams(queryParamsLog)}`, + ); + } else { + history.push( + `${history.location.pathname}/new?${createQueryParams(queryParams)}`, + ); + } }; return ( diff --git a/frontend/src/container/NewDashboard/DashboardVariablesSelection/DashboardVariableSelection.tsx b/frontend/src/container/NewDashboard/DashboardVariablesSelection/DashboardVariableSelection.tsx index 5f770e26d0..1eed8f351f 100644 --- a/frontend/src/container/NewDashboard/DashboardVariablesSelection/DashboardVariableSelection.tsx +++ b/frontend/src/container/NewDashboard/DashboardVariablesSelection/DashboardVariableSelection.tsx @@ -72,6 +72,7 @@ function DashboardVariableSelection(): JSX.Element | null { id: string, value: IDashboardVariable['selectedValue'], allSelected: boolean, + // eslint-disable-next-line sonarjs/cognitive-complexity ): void => { if (id) { updateLocalStorageDashboardVariables(name, value, allSelected); @@ -79,17 +80,29 @@ function DashboardVariableSelection(): JSX.Element | null { if (selectedDashboard) { setSelectedDashboard((prev) => { if (prev) { + const oldVariables = prev?.data.variables; + // this is added to handle case where we have two different + // schemas for variable response + if (oldVariables[id]) { + oldVariables[id] = { + ...oldVariables[id], + selectedValue: value, + allSelected, + }; + } + if (oldVariables[name]) { + oldVariables[name] = { + ...oldVariables[name], + selectedValue: value, + allSelected, + }; + } return { ...prev, data: { ...prev?.data, variables: { - ...prev?.data.variables, - [id]: { - ...prev.data.variables[id], - selectedValue: value, - allSelected, - }, + ...oldVariables, }, }, }; diff --git a/frontend/src/container/NewWidget/LeftContainer/QuerySection/index.tsx b/frontend/src/container/NewWidget/LeftContainer/QuerySection/index.tsx index 7c9fca416e..8819cbf0f9 100644 --- a/frontend/src/container/NewWidget/LeftContainer/QuerySection/index.tsx +++ b/frontend/src/container/NewWidget/LeftContainer/QuerySection/index.tsx @@ -4,6 +4,7 @@ import { Button, Tabs, Tooltip, Typography } from 'antd'; import TextToolTip from 'components/TextToolTip'; import { PANEL_TYPES } from 'constants/queryBuilder'; import { QBShortcuts } from 'constants/shortcuts/QBShortcuts'; +import { getDefaultWidgetData } from 'container/NewWidget/utils'; import { QueryBuilder } from 'container/QueryBuilder'; import { QueryBuilderProps } from 'container/QueryBuilder/QueryBuilder.interfaces'; import { useKeyboardHotkeys } from 'hooks/hotkeys/useKeyboardHotkeys'; @@ -11,6 +12,7 @@ import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl'; import { updateStepInterval } from 'hooks/queryBuilder/useStepInterval'; import useUrlQuery from 'hooks/useUrlQuery'; +import { defaultTo } from 'lodash-es'; import { Atom, Play, Terminal } from 'lucide-react'; import { useDashboard } from 'providers/Dashboard/Dashboard'; import { @@ -55,8 +57,11 @@ function QuerySection({ const getWidget = useCallback(() => { const widgetId = urlQuery.get('widgetId'); - return widgets?.find((e) => e.id === widgetId); - }, [widgets, urlQuery]); + return defaultTo( + widgets?.find((e) => e.id === widgetId), + getDefaultWidgetData(widgetId || '', selectedGraph), + ); + }, [urlQuery, widgets, selectedGraph]); const selectedWidget = getWidget() as Widgets; diff --git a/frontend/src/container/NewWidget/index.tsx b/frontend/src/container/NewWidget/index.tsx index aaf992a8dd..404d3cb335 100644 --- a/frontend/src/container/NewWidget/index.tsx +++ b/frontend/src/container/NewWidget/index.tsx @@ -1,6 +1,7 @@ /* eslint-disable sonarjs/cognitive-complexity */ import { LockFilled, WarningOutlined } from '@ant-design/icons'; -import { Button, Modal, Space, Tooltip, Typography } from 'antd'; +import { Button, Flex, Modal, Space, Tooltip, Typography } from 'antd'; +import FacingIssueBtn from 'components/facingIssueBtn/FacingIssueBtn'; import { SOMETHING_WENT_WRONG } from 'constants/api'; import { FeatureKeys } from 'constants/features'; import { QueryParams } from 'constants/query'; @@ -14,6 +15,7 @@ import { MESSAGE, useIsFeatureDisabled } from 'hooks/useFeatureFlag'; import { useNotifications } from 'hooks/useNotifications'; import useUrlQuery from 'hooks/useUrlQuery'; import history from 'lib/history'; +import { defaultTo, isUndefined } from 'lodash-es'; import { DashboardWidgetPageParams } from 'pages/DashboardWidget'; import { useDashboard } from 'providers/Dashboard/Dashboard'; import { @@ -45,7 +47,11 @@ import { RightContainerWrapper, } from './styles'; import { NewWidgetProps } from './types'; -import { getIsQueryModified, handleQueryChange } from './utils'; +import { + getDefaultWidgetData, + getIsQueryModified, + handleQueryChange, +} from './utils'; function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element { const { @@ -80,10 +86,26 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element { const { dashboardId } = useParams(); + const [isNewDashboard, setIsNewDashboard] = useState(false); + + useEffect(() => { + const widgetId = query.get('widgetId'); + const selectedWidget = widgets?.find((e) => e.id === widgetId); + const isWidgetNotPresent = isUndefined(selectedWidget); + if (isWidgetNotPresent) { + setIsNewDashboard(true); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const getWidget = useCallback(() => { const widgetId = query.get('widgetId'); - return widgets?.find((e) => e.id === widgetId); - }, [query, widgets]); + const selectedWidget = widgets?.find((e) => e.id === widgetId); + return defaultTo( + selectedWidget, + getDefaultWidgetData(widgetId || '', selectedGraph), + ); + }, [query, selectedGraph, widgets]); const [selectedWidget, setSelectedWidget] = useState(getWidget()); @@ -227,6 +249,20 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element { return; } + const widgetId = query.get('widgetId'); + let updatedLayout = selectedDashboard.data.layout || []; + if (isNewDashboard) { + updatedLayout = [ + { + i: widgetId || '', + w: 6, + x: 0, + h: 3, + y: 0, + }, + ...updatedLayout, + ]; + } const dashboard: Dashboard = { ...selectedDashboard, uuid: selectedDashboard.uuid, @@ -254,6 +290,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element { }, ...afterWidgets, ], + layout: [...updatedLayout], }, }; @@ -274,6 +311,8 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element { }); }, [ selectedDashboard, + query, + isNewDashboard, preWidgets, selectedWidget, selectedTime.enum, @@ -363,33 +402,55 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element { return ( - - {isSaveDisabled && ( - + + + + {isSaveDisabled && ( + + + + )} + + {!isSaveDisabled && ( - - )} - - {!isSaveDisabled && ( - - )} - - + )} + + + diff --git a/frontend/src/container/NewWidget/utils.ts b/frontend/src/container/NewWidget/utils.ts index bfead4a36f..64d884de15 100644 --- a/frontend/src/container/NewWidget/utils.ts +++ b/frontend/src/container/NewWidget/utils.ts @@ -3,7 +3,13 @@ import { initialQueryBuilderFormValuesMap, PANEL_TYPES, } from 'constants/queryBuilder'; +import { + listViewInitialLogQuery, + listViewInitialTraceQuery, + PANEL_TYPES_INITIAL_QUERY, +} from 'container/NewDashboard/ComponentsSlider/constants'; import { isEqual, set, unset } from 'lodash-es'; +import { Widgets } from 'types/api/dashboard/getAll'; import { IBuilderQuery, Query } from 'types/api/queryBuilder/queryBuilderData'; import { DataSource } from 'types/common/queryBuilder'; @@ -302,3 +308,38 @@ export function handleQueryChange( }, }; } + +export const getDefaultWidgetData = ( + id: string, + name: PANEL_TYPES, +): Widgets => ({ + id, + title: '', + description: '', + isStacked: false, + nullZeroValues: '', + opacity: '', + panelTypes: name, + query: + name === PANEL_TYPES.LIST + ? listViewInitialLogQuery + : PANEL_TYPES_INITIAL_QUERY[name], + timePreferance: 'GLOBAL_TIME', + softMax: null, + softMin: null, + selectedLogFields: [ + { + dataType: 'string', + type: '', + name: 'body', + }, + { + dataType: 'string', + type: '', + name: 'timestamp', + }, + ], + selectedTracesFields: [ + ...listViewInitialTraceQuery.builder.queryData[0].selectColumns, + ], +}); diff --git a/frontend/src/container/OnboardingContainer/common/ModuleStepsContainer/ModuleStepsContainer.tsx b/frontend/src/container/OnboardingContainer/common/ModuleStepsContainer/ModuleStepsContainer.tsx index 91df3591c4..bc983c9ee8 100644 --- a/frontend/src/container/OnboardingContainer/common/ModuleStepsContainer/ModuleStepsContainer.tsx +++ b/frontend/src/container/OnboardingContainer/common/ModuleStepsContainer/ModuleStepsContainer.tsx @@ -10,6 +10,7 @@ import { LeftCircleOutlined, } from '@ant-design/icons'; import { Button, Space, Steps, Typography } from 'antd'; +import logEvent from 'api/common/logEvent'; import ROUTES from 'constants/routes'; import { stepsMap } from 'container/OnboardingContainer/constants/stepsConfig'; import { DataSourceType } from 'container/OnboardingContainer/Steps/DataSource/DataSource'; @@ -381,11 +382,12 @@ export default function ModuleStepsContainer({ }; const handleFacingIssuesClick = (): void => { - trackEvent('Onboarding V2: Facing Issues Sending Data to SigNoz', { + logEvent('Onboarding V2: Facing Issues Sending Data to SigNoz', { dataSource: selectedDataSource?.id, framework: selectedFramework, environment: selectedEnvironment, module: activeStep?.module?.id, + step: activeStep?.step?.id, }); const message = `Hi Team, diff --git a/frontend/src/container/QueryBuilder/components/QBEntityOptions/QBEntityOptions.tsx b/frontend/src/container/QueryBuilder/components/QBEntityOptions/QBEntityOptions.tsx index f7a6f53a38..a2ec473921 100644 --- a/frontend/src/container/QueryBuilder/components/QBEntityOptions/QBEntityOptions.tsx +++ b/frontend/src/container/QueryBuilder/components/QBEntityOptions/QBEntityOptions.tsx @@ -105,8 +105,8 @@ export default function QBEntityOptions({ onQueryFunctionsUpdates && ( diff --git a/frontend/src/container/TracesExplorer/ListView/utils.tsx b/frontend/src/container/TracesExplorer/ListView/utils.tsx index 6a8ef4fc4c..732c8eacdf 100644 --- a/frontend/src/container/TracesExplorer/ListView/utils.tsx +++ b/frontend/src/container/TracesExplorer/ListView/utils.tsx @@ -24,7 +24,14 @@ export const getTraceLink = (record: RowData): string => export const getListColumns = ( selectedColumns: BaseAutocompleteData[], ): ColumnsType => { - const initialColumns: ColumnsType = []; + const initialColumns: ColumnsType = [ + { + dataIndex: 'date', + key: 'date', + title: 'Timestamp', + width: 145, + }, + ]; const columns: ColumnsType = selectedColumns.map(({ dataType, key, type }) => ({ diff --git a/frontend/src/pages/DashboardWidget/index.tsx b/frontend/src/pages/DashboardWidget/index.tsx index f26bc6b752..d32ded450b 100644 --- a/frontend/src/pages/DashboardWidget/index.tsx +++ b/frontend/src/pages/DashboardWidget/index.tsx @@ -49,15 +49,11 @@ function DashboardWidget(): JSX.Element | null { ); } - if (selectedWidget === undefined) { - return null; - } - return ( ); } diff --git a/frontend/src/providers/Dashboard/Dashboard.tsx b/frontend/src/providers/Dashboard/Dashboard.tsx index 9a6fe62a1c..1428e00e21 100644 --- a/frontend/src/providers/Dashboard/Dashboard.tsx +++ b/frontend/src/providers/Dashboard/Dashboard.tsx @@ -176,8 +176,6 @@ export function DashboardProvider({ return data; }; - - console.log(variablesToGetUpdated); const dashboardResponse = useQuery( [REACT_QUERY_KEY.DASHBOARD_BY_ID, isDashboardPage?.params], { diff --git a/go.mod b/go.mod index a9eae459fa..135616040c 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/ClickHouse/clickhouse-go/v2 v2.20.0 github.com/DATA-DOG/go-sqlmock v1.5.2 github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd - github.com/SigNoz/signoz-otel-collector v0.88.20 + github.com/SigNoz/signoz-otel-collector v0.88.21 github.com/SigNoz/zap_otlp/zap_otlp_encoder v0.0.0-20230822164844-1b861a431974 github.com/SigNoz/zap_otlp/zap_otlp_sync v0.0.0-20230822164844-1b861a431974 github.com/antonmedv/expr v1.15.3 @@ -46,7 +46,6 @@ require ( github.com/russellhaering/goxmldsig v1.2.0 github.com/samber/lo v1.38.1 github.com/sethvargo/go-password v0.2.0 - github.com/smartystreets/assertions v1.13.1 github.com/smartystreets/goconvey v1.8.1 github.com/soheilhy/cmux v0.1.5 github.com/srikanthccv/ClickHouse-go-mock v0.7.0 @@ -66,9 +65,9 @@ require ( go.opentelemetry.io/otel/sdk v1.23.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.19.0 + golang.org/x/crypto v0.21.0 golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 - golang.org/x/net v0.21.0 + golang.org/x/net v0.23.0 golang.org/x/oauth2 v0.16.0 google.golang.org/grpc v1.62.0 google.golang.org/protobuf v1.33.0 @@ -190,7 +189,7 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/goleak v1.3.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.17.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect gonum.org/v1/gonum v0.14.0 // indirect @@ -203,4 +202,4 @@ require ( k8s.io/utils v0.0.0-20230711102312-30195339c3c7 // indirect ) -replace github.com/prometheus/prometheus => github.com/SigNoz/prometheus v1.10.1 +replace github.com/prometheus/prometheus => github.com/SigNoz/prometheus v1.11.0 diff --git a/go.sum b/go.sum index a77629441d..8e06c1a159 100644 --- a/go.sum +++ b/go.sum @@ -96,10 +96,10 @@ github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd h1:Bk43AsDYe0fhkbj57eGXx8H3ZJ4zhmQXBnrW523ktj8= github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd/go.mod h1:nxRcH/OEdM8QxzH37xkGzomr1O0JpYBRS6pwjsWW6Pc= -github.com/SigNoz/prometheus v1.10.1 h1:2LKRtPDMgSJpgDRDy0GUQiXi+yhDNqcbptuEon4Wpls= -github.com/SigNoz/prometheus v1.10.1/go.mod h1:MffmFu2qFILQrOHehx3D0XjYtaZMVfI+Ppeiv98x4Ww= -github.com/SigNoz/signoz-otel-collector v0.88.20 h1:saC1unOxkpw4VCKyPsIIUq37vKkQ5fK/eDlnuHMm0UE= -github.com/SigNoz/signoz-otel-collector v0.88.20/go.mod h1:PThU+A6SgzEotT3ngKN4WVGWW0+eS7F1a2Rnq11aZZA= +github.com/SigNoz/prometheus v1.11.0 h1:toX7fU2wqY1TnzvPzDglIYx6OxpqrZ0NNlM/H5S5+u8= +github.com/SigNoz/prometheus v1.11.0/go.mod h1:MffmFu2qFILQrOHehx3D0XjYtaZMVfI+Ppeiv98x4Ww= +github.com/SigNoz/signoz-otel-collector v0.88.21 h1:9K1FLUncUZh7cPfOLDPuT8itU8LyCufk4QwGp18hK88= +github.com/SigNoz/signoz-otel-collector v0.88.21/go.mod h1:sT1EM9PFDaOJLbAz5npWpgXK6OhpWJ9PpSwyhHWs9rU= github.com/SigNoz/zap_otlp v0.1.0 h1:T7rRcFN87GavY8lDGZj0Z3Xv6OhJA6Pj3I9dNPmqvRc= github.com/SigNoz/zap_otlp v0.1.0/go.mod h1:lcHvbDbRgvDnPxo9lDlaL1JK2PyOyouP/C3ynnYIvyo= github.com/SigNoz/zap_otlp/zap_otlp_encoder v0.0.0-20230822164844-1b861a431974 h1:PKVgdf83Yw+lZJbFtNGBgqXiXNf3+kOXW2qZ7Ms7OaY= @@ -777,8 +777,6 @@ github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGB github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/assertions v1.13.1 h1:Ef7KhSmjZcK6AVf9YbJdvPYG9avaF0ZxudX+ThRdWfU= -github.com/smartystreets/assertions v1.13.1/go.mod h1:cXr/IwVfSo/RbCSPhoAPv73p3hlSdrBH/b3SdnW/LMY= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= @@ -946,8 +944,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1044,8 +1042,8 @@ golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1179,13 +1177,13 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/pkg/query-service/app/logs/v3/query_builder.go b/pkg/query-service/app/logs/v3/query_builder.go index e01cb95d74..75cacaa2ed 100644 --- a/pkg/query-service/app/logs/v3/query_builder.go +++ b/pkg/query-service/app/logs/v3/query_builder.go @@ -252,6 +252,8 @@ func buildLogsQuery(panelType v3.PanelType, start, end, step int64, mq *v3.Build } else if panelType == v3.PanelTypeTable { queryTmpl = "SELECT now() as ts," + // step or aggregate interval is whole time period in case of table panel + step = (utils.GetEpochNanoSecs(end) - utils.GetEpochNanoSecs(start)) / 1000000000 } else if panelType == v3.PanelTypeGraph || panelType == v3.PanelTypeValue { // Select the aggregate value for interval queryTmpl = diff --git a/pkg/query-service/app/logs/v3/query_builder_test.go b/pkg/query-service/app/logs/v3/query_builder_test.go index 58a120cd44..7a8a997be4 100644 --- a/pkg/query-service/app/logs/v3/query_builder_test.go +++ b/pkg/query-service/app/logs/v3/query_builder_test.go @@ -906,6 +906,23 @@ var testBuildLogsQueryData = []struct { TableName: "logs", ExpectedQuery: "SELECT now() as ts, attributes_string_value[indexOf(attributes_string_key, 'name')] as `name`, toFloat64(count(*)) as value from signoz_logs.distributed_logs where (timestamp >= 1680066360726210000 AND timestamp <= 1680066458000000000) AND has(attributes_string_key, 'name') group by `name` order by value DESC", }, + { + Name: "TABLE: Test rate with groupBy", + PanelType: v3.PanelTypeTable, + Start: 1680066360726210000, + End: 1680066458000000000, + BuilderQuery: &v3.BuilderQuery{ + QueryName: "A", + StepInterval: 60, + AggregateOperator: v3.AggregateOperatorRate, + Expression: "A", + GroupBy: []v3.AttributeKey{ + {Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, + }, + }, + TableName: "logs", + ExpectedQuery: "SELECT now() as ts, attributes_string_value[indexOf(attributes_string_key, 'name')] as `name`, count()/97.000000 as value from signoz_logs.distributed_logs where (timestamp >= 1680066360726210000 AND timestamp <= 1680066458000000000) AND has(attributes_string_key, 'name') group by `name` order by value DESC", + }, { Name: "TABLE: Test count with groupBy, orderBy", PanelType: v3.PanelTypeTable, diff --git a/pkg/query-service/app/opamp/otelconfig/testdata/basic.yaml b/pkg/query-service/app/opamp/otelconfig/testdata/basic.yaml index e8259a27e9..3a997c1c7f 100644 --- a/pkg/query-service/app/opamp/otelconfig/testdata/basic.yaml +++ b/pkg/query-service/app/opamp/otelconfig/testdata/basic.yaml @@ -52,10 +52,10 @@ extensions: zpages: {} exporters: clickhousetraces: - datasource: tcp://localhost:9000/?database=signoz_traces + datasource: tcp://localhost:9000/signoz_traces migrations: exporter/clickhousetracesexporter/migrations clickhousemetricswrite: - endpoint: tcp://localhost:9000/?database=signoz_metrics + endpoint: tcp://localhost:9000/signoz_metrics resource_to_telemetry_conversion: enabled: true prometheus: diff --git a/pkg/query-service/app/traces/v3/query_builder.go b/pkg/query-service/app/traces/v3/query_builder.go index 8f781b7824..efbc4d8872 100644 --- a/pkg/query-service/app/traces/v3/query_builder.go +++ b/pkg/query-service/app/traces/v3/query_builder.go @@ -262,6 +262,8 @@ func buildTracesQuery(start, end, step int64, mq *v3.BuilderQuery, tableName str } else if panelType == v3.PanelTypeTable { queryTmpl = "SELECT now() as ts," + // step or aggregate interval is whole time period in case of table panel + step = (end*getZerosForEpochNano(end) - start*getZerosForEpochNano(start))/1000000000 } else if panelType == v3.PanelTypeGraph || panelType == v3.PanelTypeValue { // Select the aggregate value for interval queryTmpl = diff --git a/pkg/query-service/app/traces/v3/query_builder_test.go b/pkg/query-service/app/traces/v3/query_builder_test.go index fd798c1530..b4b1a2574c 100644 --- a/pkg/query-service/app/traces/v3/query_builder_test.go +++ b/pkg/query-service/app/traces/v3/query_builder_test.go @@ -1017,7 +1017,7 @@ var testBuildTracesQueryData = []struct { PanelType: v3.PanelTypeValue, }, { - Name: "Test aggregate PXX", + Name: "Test aggregate PXX with groupby", Start: 1680066360726210000, End: 1680066458000000000, BuilderQuery: &v3.BuilderQuery{ @@ -1059,6 +1059,26 @@ var testBuildTracesQueryData = []struct { "where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')", PanelType: v3.PanelTypeTable, }, + { + Name: "Test aggregate rate table panel", + Start: 1680066360726210000, + End: 1680066458000000000, + BuilderQuery: &v3.BuilderQuery{ + QueryName: "A", + StepInterval: 60, + AggregateAttribute: v3.AttributeKey{Key: "durationNano", IsColumn: true, DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeTag}, + AggregateOperator: v3.AggregateOperatorRate, + Expression: "A", + Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{}}, + GroupBy: []v3.AttributeKey{}, + OrderBy: []v3.OrderBy{}, + }, + TableName: "signoz_traces.distributed_signoz_index_v2", + ExpectedQuery: "SELECT now() as ts, count(durationNano)/97.000000 as value " + + "from signoz_traces.distributed_signoz_index_v2 " + + "where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000')", + PanelType: v3.PanelTypeTable, + }, { Name: "Test Noop list view", Start: 1680066360726210000, diff --git a/pkg/query-service/config/prometheus.yml b/pkg/query-service/config/prometheus.yml index 88ee92961b..6513cd0c3f 100644 --- a/pkg/query-service/config/prometheus.yml +++ b/pkg/query-service/config/prometheus.yml @@ -22,4 +22,4 @@ rule_files: scrape_configs: [] remote_read: - - url: tcp://localhost:9000/?database=signoz_metrics + - url: tcp://localhost:9000/signoz_metrics diff --git a/pkg/query-service/tests/test-deploy/docker-compose.yaml b/pkg/query-service/tests/test-deploy/docker-compose.yaml index f9498d4e45..c00391d0f6 100644 --- a/pkg/query-service/tests/test-deploy/docker-compose.yaml +++ b/pkg/query-service/tests/test-deploy/docker-compose.yaml @@ -20,7 +20,7 @@ x-clickhouse-defaults: &clickhouse-defaults "wget", "--spider", "-q", - "localhost:8123/ping" + "0.0.0.0:8123/ping" ] interval: 30s timeout: 5s @@ -192,7 +192,7 @@ services: <<: *db-depend otel-collector-migrator: - image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.20} + image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.21} container_name: otel-migrator command: - "--dsn=tcp://clickhouse:9000" @@ -205,7 +205,7 @@ services: # condition: service_healthy otel-collector: - image: signoz/signoz-otel-collector:0.88.20 + image: signoz/signoz-otel-collector:0.88.21 container_name: signoz-otel-collector command: [ diff --git a/pkg/query-service/tests/test-deploy/otel-collector-config.yaml b/pkg/query-service/tests/test-deploy/otel-collector-config.yaml index d6ef6fcc35..d7b9f357fb 100644 --- a/pkg/query-service/tests/test-deploy/otel-collector-config.yaml +++ b/pkg/query-service/tests/test-deploy/otel-collector-config.yaml @@ -101,21 +101,20 @@ extensions: exporters: clickhousetraces: - datasource: tcp://clickhouse:9000/?database=signoz_traces + datasource: tcp://clickhouse:9000/signoz_traces docker_multi_node_cluster: ${DOCKER_MULTI_NODE_CLUSTER} low_cardinal_exception_grouping: ${LOW_CARDINAL_EXCEPTION_GROUPING} clickhousemetricswrite: - endpoint: tcp://clickhouse:9000/?database=signoz_metrics + endpoint: tcp://clickhouse:9000/signoz_metrics resource_to_telemetry_conversion: enabled: true prometheus: endpoint: 0.0.0.0:8889 - # logging: {} - clickhouselogsexporter: - dsn: tcp://clickhouse:9000/ + dsn: tcp://clickhouse:9000/signoz_logs docker_multi_node_cluster: ${DOCKER_MULTI_NODE_CLUSTER} timeout: 10s + # logging: {} service: telemetry: diff --git a/pkg/query-service/tests/test-deploy/prometheus.yml b/pkg/query-service/tests/test-deploy/prometheus.yml index 6a796ea1d0..d7c52893c5 100644 --- a/pkg/query-service/tests/test-deploy/prometheus.yml +++ b/pkg/query-service/tests/test-deploy/prometheus.yml @@ -22,4 +22,4 @@ rule_files: scrape_configs: [] remote_read: - - url: tcp://clickhouse:9000/?database=signoz_metrics + - url: tcp://clickhouse:9000/signoz_metrics