mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-05 13:00:41 +08:00
commit
ee421af95c
31
.github/workflows/jest-coverage-changes.yml
vendored
Normal file
31
.github/workflows/jest-coverage-changes.yml
vendored
Normal file
@ -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
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -22,4 +22,4 @@ rule_files:
|
||||
scrape_configs: []
|
||||
|
||||
remote_read:
|
||||
- url: tcp://clickhouse:9000/?database=signoz_metrics
|
||||
- url: tcp://clickhouse:9000/signoz_metrics
|
||||
|
@ -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",
|
||||
|
@ -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:
|
||||
[
|
||||
|
@ -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:
|
||||
|
@ -22,4 +22,4 @@ rule_files:
|
||||
scrape_configs: []
|
||||
|
||||
remote_read:
|
||||
- url: tcp://clickhouse:9000/?database=signoz_metrics
|
||||
- url: tcp://clickhouse:9000/signoz_metrics
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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<ColumnsType | undefined>(
|
||||
@ -83,6 +85,8 @@ function DynamicColumnTable({
|
||||
|
||||
return (
|
||||
<div className="DynamicColumnTable">
|
||||
<Flex justify="flex-end" align="center" gap={8}>
|
||||
{facingIssueBtn && <FacingIssueBtn {...facingIssueBtn} />}
|
||||
{dynamicColumns && (
|
||||
<Dropdown
|
||||
getPopupContainer={popupContainer}
|
||||
@ -96,6 +100,7 @@ function DynamicColumnTable({
|
||||
/>
|
||||
</Dropdown>
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
<ResizeTable
|
||||
columns={columnsData}
|
||||
|
@ -2,6 +2,7 @@
|
||||
import { TableProps } from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table';
|
||||
import { ColumnGroupType, ColumnType } from 'antd/lib/table';
|
||||
import { FacingIssueBtnProps } from 'components/facingIssueBtn/FacingIssueBtn';
|
||||
|
||||
import { TableDataSource } from './contants';
|
||||
|
||||
@ -12,6 +13,7 @@ export interface DynamicColumnTableProps extends TableProps<any> {
|
||||
tablesource: typeof TableDataSource[keyof typeof TableDataSource];
|
||||
dynamicColumns: TableProps<any>['columns'];
|
||||
onDragColumn?: (fromIndex: number, toIndex: number) => void;
|
||||
facingIssueBtn?: FacingIssueBtnProps;
|
||||
}
|
||||
|
||||
export type GetVisibleColumnsFunction = (
|
||||
|
@ -0,0 +1,9 @@
|
||||
.facing-issue-button {
|
||||
color: var(--bg-amber-500);
|
||||
border-color: var(--bg-amber-500);
|
||||
|
||||
.ant-btn:hover {
|
||||
color: var(--bg-amber-400) !important;
|
||||
border-color: var(--bg-amber-300) !important;
|
||||
}
|
||||
}
|
57
frontend/src/components/facingIssueBtn/FacingIssueBtn.tsx
Normal file
57
frontend/src/components/facingIssueBtn/FacingIssueBtn.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import './FacingIssueBtn.style.scss';
|
||||
|
||||
import { Button } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import cx from 'classnames';
|
||||
import { FeatureKeys } from 'constants/features';
|
||||
import useFeatureFlags from 'hooks/useFeatureFlag';
|
||||
import { defaultTo } from 'lodash-es';
|
||||
import { HelpCircle } from 'lucide-react';
|
||||
import { isCloudUser } from 'utils/app';
|
||||
|
||||
export interface FacingIssueBtnProps {
|
||||
eventName: string;
|
||||
attributes: Record<string, unknown>;
|
||||
message?: string;
|
||||
buttonText?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function FacingIssueBtn({
|
||||
attributes,
|
||||
eventName,
|
||||
message = '',
|
||||
buttonText = '',
|
||||
className = '',
|
||||
}: FacingIssueBtnProps): JSX.Element | null {
|
||||
const handleFacingIssuesClick = (): void => {
|
||||
logEvent(eventName, attributes);
|
||||
|
||||
if (window.Intercom) {
|
||||
window.Intercom('showNewMessage', defaultTo(message, ''));
|
||||
}
|
||||
};
|
||||
|
||||
const isChatSupportEnabled = useFeatureFlags(FeatureKeys.CHAT_SUPPORT)?.active;
|
||||
const isCloudUserVal = isCloudUser();
|
||||
|
||||
return isCloudUserVal && isChatSupportEnabled ? ( // Note: we would need to move this condition to license based in future
|
||||
<div className="facing-issue-button">
|
||||
<Button
|
||||
className={cx('periscope-btn', 'facing-issue-button', className)}
|
||||
onClick={handleFacingIssuesClick}
|
||||
icon={<HelpCircle size={14} />}
|
||||
>
|
||||
{buttonText || 'Facing issues?'}
|
||||
</Button>
|
||||
</div>
|
||||
) : null;
|
||||
}
|
||||
|
||||
FacingIssueBtn.defaultProps = {
|
||||
message: '',
|
||||
buttonText: '',
|
||||
className: '',
|
||||
};
|
||||
|
||||
export default FacingIssueBtn;
|
@ -1,4 +1,5 @@
|
||||
.billing-container {
|
||||
margin-bottom: 40px;
|
||||
padding-top: 36px;
|
||||
width: 65%;
|
||||
|
||||
|
@ -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<AlertDef | null>(null);
|
||||
const [alertType, setAlertType] = useState<AlertTypes>(
|
||||
AlertTypes.METRICS_BASED_ALERT,
|
||||
);
|
||||
const [alertType, setAlertType] = useState<AlertTypes>();
|
||||
|
||||
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]);
|
||||
|
@ -43,3 +43,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.facing-issue-btn {
|
||||
margin-top: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -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,6 +139,11 @@ function FormAlertRules({
|
||||
|
||||
useEffect(() => {
|
||||
// Set selectedQueryName based on the length of queryOptions
|
||||
const selectedQueryName = alertDef?.condition?.selectedQueryName;
|
||||
if (
|
||||
!selectedQueryName ||
|
||||
!queryOptions.some((option) => option.value === selectedQueryName)
|
||||
) {
|
||||
setAlertDef((def) => ({
|
||||
...def,
|
||||
condition: {
|
||||
@ -146,7 +152,8 @@ function FormAlertRules({
|
||||
queryOptions.length > 0 ? String(queryOptions[0].value) : undefined,
|
||||
},
|
||||
}));
|
||||
}, [currentQuery?.queryType, queryOptions]);
|
||||
}
|
||||
}, [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({
|
||||
</StyledLeftContainer>
|
||||
<Col flex="1 1 300px">
|
||||
<UserGuide queryType={currentQuery.queryType} />
|
||||
<FacingIssueBtn
|
||||
attributes={{
|
||||
alert: alertDef?.alert,
|
||||
alertType: alertDef?.alertType,
|
||||
id: ruleId,
|
||||
ruleType: alertDef?.ruleType,
|
||||
state: (alertDef as any)?.state,
|
||||
panelType,
|
||||
screen: isRuleCreated ? 'Edit Alert' : 'New Alert',
|
||||
}}
|
||||
className="facing-issue-btn"
|
||||
eventName="Alert: Facing Issues in alert"
|
||||
buttonText="Facing Issues in alert"
|
||||
message={`Hi Team,
|
||||
|
||||
I am facing issues configuring alerts in SigNoz. Here are my alert rule details
|
||||
|
||||
Name: ${alertDef?.alert || ''}
|
||||
Alert Type: ${alertDef?.alertType || ''}
|
||||
State: ${(alertDef as any)?.state || ''}
|
||||
Alert Id: ${ruleId}
|
||||
|
||||
Thanks`}
|
||||
/>
|
||||
</Col>
|
||||
</PanelContainer>
|
||||
</>
|
||||
|
@ -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,6 +170,24 @@ function GraphLayout({ onAddPanelHandler }: GraphLayoutProps): JSX.Element {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex justify="flex-end" gap={8} align="center">
|
||||
<FacingIssueBtn
|
||||
attributes={{
|
||||
uuid: selectedDashboard?.uuid,
|
||||
title: data?.title,
|
||||
screen: 'Dashboard Details',
|
||||
}}
|
||||
eventName="Dashboard: Facing Issues in dashboard"
|
||||
buttonText="Facing Issues in dashboard"
|
||||
message={`Hi Team,
|
||||
|
||||
I am facing issues configuring dashboard in SigNoz. Here are my dashboard details
|
||||
|
||||
Name: ${data?.title || ''}
|
||||
Dashboard Id: ${selectedDashboard?.uuid || ''}
|
||||
|
||||
Thanks`}
|
||||
/>
|
||||
<ButtonContainer>
|
||||
<Tooltip title="Open in Full Screen">
|
||||
<Button
|
||||
@ -191,6 +210,7 @@ function GraphLayout({ onAddPanelHandler }: GraphLayoutProps): JSX.Element {
|
||||
</Button>
|
||||
)}
|
||||
</ButtonContainer>
|
||||
</Flex>
|
||||
|
||||
<FullScreen handle={handle} className="fullscreen-grid-container">
|
||||
<ReactGridLayout
|
||||
|
@ -358,6 +358,18 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
|
||||
pagination={{
|
||||
defaultCurrent: Number(paginationParam) || 1,
|
||||
}}
|
||||
facingIssueBtn={{
|
||||
attributes: {
|
||||
screen: 'Alert list page',
|
||||
},
|
||||
eventName: 'Alert: Facing Issues in alert',
|
||||
buttonText: 'Facing Issues in alert',
|
||||
message: `Hi Team,
|
||||
|
||||
I am facing issues with alerts.
|
||||
|
||||
Thanks`,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
@ -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`,
|
||||
}}
|
||||
/>
|
||||
</TableContainer>
|
||||
</Card>
|
||||
|
@ -1,99 +1,21 @@
|
||||
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: [
|
||||
{
|
||||
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,
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
onSuccess: (data) => {
|
||||
if (data.payload) {
|
||||
handleToggleDashboardSlider(false);
|
||||
const queryParamsLog = {
|
||||
graphType: name,
|
||||
@ -132,15 +54,6 @@ function DashboardGraphSlider(): JSX.Element {
|
||||
`${history.location.pathname}/new?${createQueryParams(queryParams)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
onError: () => {
|
||||
notifications.success({
|
||||
message: SOMETHING_WENT_WRONG,
|
||||
});
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -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,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<DashboardWidgetPageParams>();
|
||||
|
||||
const [isNewDashboard, setIsNewDashboard] = useState<boolean>(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,6 +402,27 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Flex justify="space-between" align="center">
|
||||
<FacingIssueBtn
|
||||
attributes={{
|
||||
uuid: selectedDashboard?.uuid,
|
||||
title: selectedDashboard?.data.title,
|
||||
panelType: graphType,
|
||||
widgetId: query.get('widgetId'),
|
||||
queryType: currentQuery.queryType,
|
||||
}}
|
||||
eventName="Dashboard: Facing Issues in dashboard"
|
||||
buttonText="Facing Issues in dashboard"
|
||||
message={`Hi Team,
|
||||
|
||||
I am facing issues configuring dashboard in SigNoz. Here are my dashboard details
|
||||
|
||||
Name: ${selectedDashboard?.data.title || ''}
|
||||
Panel type: ${graphType}
|
||||
Dashboard Id: ${selectedDashboard?.uuid || ''}
|
||||
|
||||
Thanks`}
|
||||
/>
|
||||
<ButtonContainer>
|
||||
{isSaveDisabled && (
|
||||
<Tooltip title={MESSAGE.PANEL}>
|
||||
@ -390,6 +450,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||
)}
|
||||
<Button onClick={onClickDiscardHandler}>Discard Changes</Button>
|
||||
</ButtonContainer>
|
||||
</Flex>
|
||||
|
||||
<PanelContainer>
|
||||
<LeftContainerWrapper flex={5}>
|
||||
|
@ -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,
|
||||
],
|
||||
});
|
||||
|
@ -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,
|
||||
|
@ -105,8 +105,8 @@ export default function QBEntityOptions({
|
||||
onQueryFunctionsUpdates && (
|
||||
<QueryFunctions
|
||||
query={query}
|
||||
queryFunctions={query.functions}
|
||||
key={query.functions.toString()}
|
||||
queryFunctions={query.functions || []}
|
||||
key={query.functions?.toString()}
|
||||
onChange={onQueryFunctionsUpdates}
|
||||
maxFunctions={isLogsDataSource ? 1 : 3}
|
||||
/>
|
||||
|
@ -24,7 +24,14 @@ export const getTraceLink = (record: RowData): string =>
|
||||
export const getListColumns = (
|
||||
selectedColumns: BaseAutocompleteData[],
|
||||
): ColumnsType<RowData> => {
|
||||
const initialColumns: ColumnsType<RowData> = [];
|
||||
const initialColumns: ColumnsType<RowData> = [
|
||||
{
|
||||
dataIndex: 'date',
|
||||
key: 'date',
|
||||
title: 'Timestamp',
|
||||
width: 145,
|
||||
},
|
||||
];
|
||||
|
||||
const columns: ColumnsType<RowData> =
|
||||
selectedColumns.map(({ dataType, key, type }) => ({
|
||||
|
@ -49,15 +49,11 @@ function DashboardWidget(): JSX.Element | null {
|
||||
);
|
||||
}
|
||||
|
||||
if (selectedWidget === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<NewWidget
|
||||
yAxisUnit={selectedWidget.yAxisUnit}
|
||||
yAxisUnit={selectedWidget?.yAxisUnit}
|
||||
selectedGraph={selectedGraph}
|
||||
fillSpans={selectedWidget.fillSpans}
|
||||
fillSpans={selectedWidget?.fillSpans}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -176,8 +176,6 @@ export function DashboardProvider({
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
console.log(variablesToGetUpdated);
|
||||
const dashboardResponse = useQuery(
|
||||
[REACT_QUERY_KEY.DASHBOARD_BY_ID, isDashboardPage?.params],
|
||||
{
|
||||
|
11
go.mod
11
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
|
||||
|
26
go.sum
26
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=
|
||||
|
@ -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 =
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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 =
|
||||
|
@ -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,
|
||||
|
@ -22,4 +22,4 @@ rule_files:
|
||||
scrape_configs: []
|
||||
|
||||
remote_read:
|
||||
- url: tcp://localhost:9000/?database=signoz_metrics
|
||||
- url: tcp://localhost:9000/signoz_metrics
|
||||
|
@ -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:
|
||||
[
|
||||
|
@ -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:
|
||||
|
@ -22,4 +22,4 @@ rule_files:
|
||||
scrape_configs: []
|
||||
|
||||
remote_read:
|
||||
- url: tcp://clickhouse:9000/?database=signoz_metrics
|
||||
- url: tcp://clickhouse:9000/signoz_metrics
|
||||
|
Loading…
x
Reference in New Issue
Block a user