Skip to content

Commit

Permalink
Merge branch 'develop' into improve-qc
Browse files Browse the repository at this point in the history
  • Loading branch information
srikanthccv authored Sep 19, 2024
2 parents 18c8054 + 8eb2cf1 commit 3e0427d
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 58 deletions.
49 changes: 20 additions & 29 deletions .github/ISSUE_TEMPLATE/request_dashboard.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,49 @@
---
name: Request Dashboard
about: Request a new dashboard for the SigNoz Dashboards repository
title: ''
title: '[Dashboard Request] '
labels: 'dashboard-template'
assignees: ''

---

## 📝 Dashboard Request Template
<!-- Use this template to request a new dashboard for the SigNoz Dashboards repository. Providing detailed information will help us understand your needs better and speed up the dashboard creation process. -->

*Use this template to request a new dashboard for the SigNoz Dashboards repository. Please provide as much detail as possible to help us understand your needs.*
## Dashboard Name

---

### 1. Dashboard Name
<!-- Provide the name for the requested dashboard. Be specific (e.g., "MySQL Monitoring Dashboard"). -->

Name of the requested dashboard (e.g., MySQL Monitoring Dashboard):
## Expected Dashboard Sections and Panels

---
(Can be tweaked (add or remove panels/sections) according to available metrics)

### 2. Expected Dashboard Sections and Panels
### Section Name

#### Section Name
<!-- Brief description of what this section should display (e.g., "Resource usage metrics for MySQL database"). -->

Brief description of the section (e.g., "Resource usage metrics for MySQL database").
### Panel Name

#### Panel Name
<!-- Description of the panel (e.g., "Displays current CPU usage, memory usage, etc."). -->

Panel description (e.g., "Value-type panels displaying current CPU usage, memory usage, etc.").

- **Example:**
<!-- - **Example:**
- **Section**: Resource Metrics
- **Panel**: CPU Usage - Displays the current CPU usage across all database instances.
- **Panel**: Memory Usage - Displays the total memory used by the MySQL process.

(Repeat this format for additional sections and panels)
- **Panel**: Memory Usage - Displays the total memory used by the MySQL process. -->

---
<!-- Repeat this format for any additional sections or panels. -->

### 3. Expected Variables
## Expected Dashboard Variables

List any variables you expect to use in the dashboard (e.g., `deployment.environment`, `hostname`, etc.).
<!-- List any dashboard variables that should be included in the dashboard. Examples could be `deployment.environment`, `hostname`, `region`, etc. -->

---
## Additional Comments or Requirements

### 4. Additional Comments or Requirements
<!-- Include any other details, special requirements, or specific visualizations you'd like to request for this dashboard. -->

Any additional details or special requirements for the dashboard?
## References or Screenshots

---
<!-- Add any references or screenshots of requested dashboard if available. -->

### 📋 Notes
## 📋 Notes

Please review the [CONTRIBUTING.md](https://github.com/SigNoz/dashboards/blob/main/CONTRIBUTING.md) for guidelines on dashboard structure, naming conventions, and how to submit a pull request.

---
Thank you for your request! We will review it and provide feedback or guidance as necessary.
13 changes: 12 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Also, have a look at these [good first issues label](https://github.com/SigNoz/s
- [To run ClickHouse setup](#41-to-run-clickhouse-setup-recommended-for-local-development)
- [Contribute to SigNoz Helm Chart](#5-contribute-to-signoz-helm-chart-)
- [To run helm chart for local development](#51-to-run-helm-chart-for-local-development)
- [Contribute to Dashboards](#6-contribute-to-dashboards-)
- [Other Ways to Contribute](#other-ways-to-contribute)

# 1. General Instructions 📝
Expand Down Expand Up @@ -369,6 +370,17 @@ curl -sL https://github.com/SigNoz/signoz/raw/develop/sample-apps/hotrod/hotrod-
---
# 6. Contribute to Dashboards 📈
**Need to Update: [https://github.com/SigNoz/dashboards](https://github.com/SigNoz/dashboards)**
To contribute a new dashboard template for any service, follow the contribution guidelines in the [Dashboard Contributing Guide](https://github.com/SigNoz/dashboards/blob/main/CONTRIBUTING.md). In brief:
1. Create a dashboard JSON file.
2. Add a README file explaining the dashboard, the metrics ingested, and the configurations needed.
3. Include screenshots of the dashboard in the `assets/` directory.
4. Submit a pull request for review.
## Other Ways to Contribute
There are many other ways to get involved with the community and to participate in this project:
Expand All @@ -379,7 +391,6 @@ There are many other ways to get involved with the community and to participate
- Help answer questions on forums such as Stack Overflow and [SigNoz Community Slack Channel](https://signoz.io/slack).
- Tell others about the project on Twitter, your blog, etc.
Again, Feel free to ping us on [`#contributing`](https://signoz-community.slack.com/archives/C01LWQ8KS7M) or [`#contributing-frontend`](https://signoz-community.slack.com/archives/C027134DM8B) on our slack community if you need any help on this :)
Thank You!
21 changes: 21 additions & 0 deletions frontend/src/container/GridCardLayout/GridCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { isEqual } from 'lodash-es';
import isEmpty from 'lodash-es/isEmpty';
import { useDashboard } from 'providers/Dashboard/Dashboard';
import { memo, useEffect, useRef, useState } from 'react';
import { useQueryClient } from 'react-query';
import { useDispatch, useSelector } from 'react-redux';
import { UpdateTimeInterval } from 'store/actions';
import { AppState } from 'store/reducers';
Expand Down Expand Up @@ -48,6 +49,7 @@ function GridCardGraph({
AppState,
GlobalReducer
>((state) => state.globalTime);
const queryClient = useQueryClient();

const handleBackNavigation = (): void => {
const searchParams = new URLSearchParams(window.location.search);
Expand Down Expand Up @@ -136,6 +138,25 @@ function GridCardGraph({
};
});

// TODO [vikrantgupta25] remove this useEffect with refactor as this is prone to race condition
// this is added to tackle the case of async communication between VariableItem.tsx and GridCard.tsx
useEffect(() => {
if (variablesToGetUpdated.length > 0) {
queryClient.cancelQueries([
maxTime,
minTime,
globalSelectedInterval,
variables,
widget?.query,
widget?.panelTypes,
widget.timePreferance,
widget.fillSpans,
requestData,
]);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [variablesToGetUpdated]);

useEffect(() => {
if (!isEqual(updatedQuery, requestData.query)) {
setRequestData((prev) => ({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import '@testing-library/jest-dom/extend-expect';

import {
act,
fireEvent,
render,
screen,
waitFor,
} from '@testing-library/react';
import MockQueryClientProvider from 'providers/test/MockQueryClientProvider';
import React, { useEffect } from 'react';
import { act, fireEvent, render, screen, waitFor } from 'tests/test-utils';
import { IDashboardVariable } from 'types/api/dashboard/getAll';

import VariableItem from './VariableItem';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable sonarjs/cognitive-complexity */
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable @typescript-eslint/no-explicit-any */
Expand Down Expand Up @@ -25,8 +26,11 @@ import { debounce, isArray, isString } from 'lodash-es';
import map from 'lodash-es/map';
import { ChangeEvent, memo, useEffect, useMemo, useState } from 'react';
import { useQuery } from 'react-query';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { IDashboardVariable } from 'types/api/dashboard/getAll';
import { VariableResponseProps } from 'types/api/dashboard/variables/query';
import { GlobalReducer } from 'types/reducer/globalTime';
import { popupContainer } from 'utils/selectPopupContainer';

import { variablePropsToPayloadVariables } from '../utils';
Expand Down Expand Up @@ -80,6 +84,23 @@ function VariableItem({
[],
);

const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);

useEffect(() => {
if (variableData.allSelected && variableData.type === 'QUERY') {
setVariablesToGetUpdated((prev) => {
const variablesQueue = [...prev.filter((v) => v !== variableData.name)];
if (variableData.name) {
variablesQueue.push(variableData.name);
}
return variablesQueue;
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [minTime, maxTime]);

const [errorMessage, setErrorMessage] = useState<null | string>(null);

const getDependentVariables = (queryValue: string): string[] => {
Expand Down Expand Up @@ -111,7 +132,14 @@ function VariableItem({

const variableKey = dependentVariablesStr.replace(/\s/g, '');

return [REACT_QUERY_KEY.DASHBOARD_BY_ID, variableName, variableKey];
// added this time dependency for variables query as API respects the passed time range now
return [
REACT_QUERY_KEY.DASHBOARD_BY_ID,
variableName,
variableKey,
`${minTime}`,
`${maxTime}`,
];
};

// eslint-disable-next-line sonarjs/cognitive-complexity
Expand Down Expand Up @@ -151,10 +179,14 @@ function VariableItem({
valueNotInList = true;
}
}
// variablesData.allSelected is added for the case where on change of options we need to update the
// local storage
if (
variableData.type === 'QUERY' &&
variableData.name &&
(variablesToGetUpdated.includes(variableData.name) || valueNotInList)
(variablesToGetUpdated.includes(variableData.name) ||
valueNotInList ||
variableData.allSelected)
) {
let value = variableData.selectedValue;
let allSelected = false;
Expand Down Expand Up @@ -338,8 +370,8 @@ function VariableItem({
(Array.isArray(selectValue) && selectValue?.includes(option.toString()));

if (isChecked) {
if (mode === ToggleTagValue.Only) {
handleChange(option.toString());
if (mode === ToggleTagValue.Only && variableData.multiSelect) {
handleChange([option.toString()]);
} else if (!variableData.multiSelect) {
handleChange(option.toString());
} else {
Expand Down
16 changes: 9 additions & 7 deletions pkg/query-service/app/logs/v4/query_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,21 +146,23 @@ func buildAttributeFilter(item v3.FilterItem) (string, error) {

return fmt.Sprintf(logsOp, keyName, fmtVal), nil
case v3.FilterOperatorContains, v3.FilterOperatorNotContains:
// we also want to treat %, _ as literals for contains
val := utils.QuoteEscapedStringForContains(fmt.Sprintf("%s", item.Value))
// for body the contains is case insensitive
if keyName == BODY {
return fmt.Sprintf("lower(%s) %s lower('%%%s%%')", keyName, logsOp, val), nil
} else {
return fmt.Sprintf("%s %s '%%%s%%'", keyName, logsOp, val), nil
}
default:
// for use lower for like and ilike
if op == v3.FilterOperatorLike || op == v3.FilterOperatorNotLike {
if keyName == BODY {
keyName = fmt.Sprintf("lower(%s)", keyName)
fmtVal = fmt.Sprintf("lower(%s)", fmtVal)
}
case v3.FilterOperatorLike, v3.FilterOperatorNotLike:
// for body use lower for like and ilike
val := utils.QuoteEscapedString(fmt.Sprintf("%s", item.Value))
if keyName == BODY {
return fmt.Sprintf("lower(%s) %s lower('%s')", keyName, logsOp, val), nil
} else {
return fmt.Sprintf("%s %s '%s'", keyName, logsOp, val), nil
}
default:
return fmt.Sprintf("%s %s %s", keyName, logsOp, fmtVal), nil
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions pkg/query-service/app/logs/v4/query_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,10 @@ func Test_buildAttributeFilter(t *testing.T) {
Type: v3.AttributeKeyTypeResource,
},
Operator: v3.FilterOperatorLike,
Value: "test",
Value: "test%",
},
},
want: "resources_string['service.name'] LIKE 'test'",
want: "resources_string['service.name'] LIKE 'test%'",
},
{
name: "build attribute filter like-body",
Expand Down
17 changes: 14 additions & 3 deletions pkg/query-service/app/logs/v4/resource_query_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,13 @@ func buildResourceFilter(logsOp string, key string, op v3.FilterOperator, value
return fmt.Sprintf(logsOp, searchKey, chFmtVal)
case v3.FilterOperatorContains, v3.FilterOperatorNotContains:
// this is required as clickhouseFormattedValue add's quotes to the string
// we also want to treat %, _ as literals for contains
escapedStringValue := utils.QuoteEscapedStringForContains(fmt.Sprintf("%s", value))
return fmt.Sprintf("%s %s '%%%s%%'", searchKey, logsOp, escapedStringValue)
case v3.FilterOperatorLike, v3.FilterOperatorNotLike:
// this is required as clickhouseFormattedValue add's quotes to the string
escapedStringValue := utils.QuoteEscapedString(fmt.Sprintf("%s", value))
return fmt.Sprintf("%s %s '%s'", searchKey, logsOp, escapedStringValue)
default:
return fmt.Sprintf("%s %s %s", searchKey, logsOp, chFmtVal)
}
Expand Down Expand Up @@ -74,13 +79,19 @@ func buildIndexFilterForInOperator(key string, op v3.FilterOperator, value inter
// example:= x like '%john%' = labels like '%x%john%'
func buildResourceIndexFilter(key string, op v3.FilterOperator, value interface{}) string {
// not using clickhouseFormattedValue as we don't wan't the quotes
formattedValueEscaped := utils.QuoteEscapedStringForContains(fmt.Sprintf("%s", value))
strVal := fmt.Sprintf("%s", value)
formattedValueEscapedForContains := utils.QuoteEscapedStringForContains(strVal)
formattedValueEscaped := utils.QuoteEscapedString(strVal)

// add index filters
switch op {
case v3.FilterOperatorContains, v3.FilterOperatorEqual, v3.FilterOperatorLike:
case v3.FilterOperatorContains:
return fmt.Sprintf("labels like '%%%s%%%s%%'", key, formattedValueEscapedForContains)
case v3.FilterOperatorNotContains:
return fmt.Sprintf("labels not like '%%%s%%%s%%'", key, formattedValueEscapedForContains)
case v3.FilterOperatorLike, v3.FilterOperatorEqual:
return fmt.Sprintf("labels like '%%%s%%%s%%'", key, formattedValueEscaped)
case v3.FilterOperatorNotContains, v3.FilterOperatorNotEqual, v3.FilterOperatorNotLike:
case v3.FilterOperatorNotLike, v3.FilterOperatorNotEqual:
return fmt.Sprintf("labels not like '%%%s%%%s%%'", key, formattedValueEscaped)
case v3.FilterOperatorNotRegex:
return fmt.Sprintf("labels not like '%%%s%%'", key)
Expand Down
27 changes: 23 additions & 4 deletions pkg/query-service/app/logs/v4/resource_query_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ func Test_buildResourceFilter(t *testing.T) {
logsOp: "=",
key: "service.name",
op: v3.FilterOperatorEqual,
value: "Application",
value: "Application%",
},
want: `simpleJSONExtractString(labels, 'service.name') = 'Application'`,
want: `simpleJSONExtractString(labels, 'service.name') = 'Application%'`,
},
{
name: "test value with quotes",
Expand All @@ -75,6 +75,16 @@ func Test_buildResourceFilter(t *testing.T) {
},
want: `simpleJSONExtractString(labels, 'service.name') = 'Application\'s'`,
},
{
name: "test like",
args: args{
logsOp: "LIKE",
key: "service.name",
op: v3.FilterOperatorLike,
value: "Application%_",
},
want: `simpleJSONExtractString(labels, 'service.name') LIKE 'Application%_'`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down Expand Up @@ -119,9 +129,9 @@ func Test_buildIndexFilterForInOperator(t *testing.T) {
args: args{
key: "service.name",
op: v3.FilterOperatorIn,
value: "application",
value: "application%",
},
want: `(labels like '%"service.name":"application"%')`,
want: `(labels like '%"service.name":"application\%"%')`,
},
{
name: "test nin string",
Expand Down Expand Up @@ -180,6 +190,15 @@ func Test_buildResourceIndexFilter(t *testing.T) {
},
want: `labels not like '%service.name%application\%\_test%'`,
},
{
name: "test like with % and _",
args: args{
key: "service.name",
op: v3.FilterOperatorLike,
value: "application%_test",
},
want: `labels like '%service.name%application%_test%'`,
},
{
name: "test not regex",
args: args{
Expand Down
1 change: 0 additions & 1 deletion signoz-core-ui
Submodule signoz-core-ui deleted from f8c925

0 comments on commit 3e0427d

Please sign in to comment.