From f3fdd2dd6caa5a36a494d2328289956a75d680f7 Mon Sep 17 00:00:00 2001 From: Nityananda Gohain Date: Sat, 20 Jan 2024 01:24:09 +0530 Subject: [PATCH 1/6] chore: add tenantId and orgName in usage (#4399) * feat: add tenantId and orgName in usage * fix: update regex * fix: if else logic updated --- ee/query-service/app/server.go | 2 +- ee/query-service/model/usage.go | 2 ++ ee/query-service/usage/manager.go | 35 +++++++++++++++++++++++++++++-- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/ee/query-service/app/server.go b/ee/query-service/app/server.go index a5c7c1db22..ea0b0344ad 100644 --- a/ee/query-service/app/server.go +++ b/ee/query-service/app/server.go @@ -193,7 +193,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) { } // start the usagemanager - usageManager, err := usage.New("sqlite", localDB, lm.GetRepo(), reader.GetConn()) + usageManager, err := usage.New("sqlite", modelDao, lm.GetRepo(), reader.GetConn()) if err != nil { return nil, err } diff --git a/ee/query-service/model/usage.go b/ee/query-service/model/usage.go index d9129531dc..3cedb0532e 100644 --- a/ee/query-service/model/usage.go +++ b/ee/query-service/model/usage.go @@ -20,6 +20,8 @@ type Usage struct { TimeStamp time.Time `json:"timestamp"` Count int64 `json:"count"` Size int64 `json:"size"` + OrgName string `json:"orgName"` + TenantId string `json:"tenantId"` } type UsageDB struct { diff --git a/ee/query-service/usage/manager.go b/ee/query-service/usage/manager.go index 335eae8143..28d4e3020e 100644 --- a/ee/query-service/usage/manager.go +++ b/ee/query-service/usage/manager.go @@ -4,6 +4,8 @@ import ( "context" "encoding/json" "fmt" + "os" + "regexp" "strings" "sync/atomic" "time" @@ -11,10 +13,10 @@ import ( "github.com/ClickHouse/clickhouse-go/v2" "github.com/go-co-op/gocron" "github.com/google/uuid" - "github.com/jmoiron/sqlx" "go.uber.org/zap" + "go.signoz.io/signoz/ee/query-service/dao" licenseserver "go.signoz.io/signoz/ee/query-service/integrations/signozio" "go.signoz.io/signoz/ee/query-service/license" "go.signoz.io/signoz/ee/query-service/model" @@ -38,15 +40,29 @@ type Manager struct { licenseRepo *license.Repo scheduler *gocron.Scheduler + + modelDao dao.ModelDao + + tenantID string } -func New(dbType string, db *sqlx.DB, licenseRepo *license.Repo, clickhouseConn clickhouse.Conn) (*Manager, error) { +func New(dbType string, modelDao dao.ModelDao, licenseRepo *license.Repo, clickhouseConn clickhouse.Conn) (*Manager, error) { + hostNameRegex := regexp.MustCompile(`tcp://(?P.*):`) + hostNameRegexMatches := hostNameRegex.FindStringSubmatch(os.Getenv("ClickHouseUrl")) + + tenantID := "" + if len(hostNameRegexMatches) == 2 { + tenantID = hostNameRegexMatches[1] + tenantID = strings.TrimRight(tenantID, "-clickhouse") + } m := &Manager{ // repository: repo, clickhouseConn: clickhouseConn, licenseRepo: licenseRepo, scheduler: gocron.NewScheduler(time.UTC).Every(1).Day().At("00:00"), // send usage every at 00:00 UTC + modelDao: modelDao, + tenantID: tenantID, } return m, nil } @@ -123,6 +139,19 @@ func (lm *Manager) UploadUsage() { zap.S().Info("uploading usage data") + // Try to get the org name + orgName := "" + orgNames, err := lm.modelDao.GetOrgs(ctx) + if err != nil { + zap.S().Errorf("failed to get org data: %v", zap.Error(err)) + } else { + if len(orgNames) != 1 { + zap.S().Errorf("expected one org but got %d orgs", len(orgNames)) + } else { + orgName = orgNames[0].Name + } + } + usagesPayload := []model.Usage{} for _, usage := range usages { usageDataBytes, err := encryption.Decrypt([]byte(usage.ExporterID[:32]), []byte(usage.Data)) @@ -142,6 +171,8 @@ func (lm *Manager) UploadUsage() { usageData.ExporterID = usage.ExporterID usageData.Type = usage.Type usageData.Tenant = usage.Tenant + usageData.OrgName = orgName + usageData.TenantId = lm.tenantID usagesPayload = append(usagesPayload, usageData) } From 00e97fa4018f41eb71ddd25d7c01197145488e3b Mon Sep 17 00:00:00 2001 From: Vikrant Gupta Date: Mon, 22 Jan 2024 13:12:02 +0530 Subject: [PATCH 2/6] fix: trial banner moving to left screen and breaking trace detail page (#4403) * fix: trial banner moving to left screen and breaking trace detail page * fix: trial banner moving to left screen and breaking trace detail page --- frontend/src/container/AppLayout/styles.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/container/AppLayout/styles.ts b/frontend/src/container/AppLayout/styles.ts index f266087895..81d75ab76a 100644 --- a/frontend/src/container/AppLayout/styles.ts +++ b/frontend/src/container/AppLayout/styles.ts @@ -8,6 +8,7 @@ export const Layout = styled(LayoutComponent)` min-height: calc(100vh - 8rem); overflow: hidden; height: 100%; + flex-direction: column !important; } `; From 255b3dd3b05fe3a243d06c32e63bf6d787d8b34f Mon Sep 17 00:00:00 2001 From: Vikrant Gupta Date: Mon, 22 Jan 2024 14:47:25 +0530 Subject: [PATCH 3/6] fix: back btn navigation on first load (#4405) * fix: back btn navigation on first load * fix: remove console logs * chore: refactor the logic to a function and added code comments --- .../src/container/TopNav/DateTimeSelection/index.tsx | 12 ++++++++++++ frontend/src/store/actions/trace/getInitialFilter.ts | 6 +++++- frontend/src/store/actions/trace/util.ts | 3 +++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/frontend/src/container/TopNav/DateTimeSelection/index.tsx b/frontend/src/container/TopNav/DateTimeSelection/index.tsx index c72ff7b82d..785f65da8f 100644 --- a/frontend/src/container/TopNav/DateTimeSelection/index.tsx +++ b/frontend/src/container/TopNav/DateTimeSelection/index.tsx @@ -279,6 +279,18 @@ function DateTimeSelection({ setRefreshButtonHidden(updatedTime === 'custom'); updateTimeInterval(updatedTime, [preStartTime, preEndTime]); + + if (updatedTime !== 'custom') { + const { minTime, maxTime } = GetMinMax(updatedTime); + urlQuery.set(QueryParams.startTime, minTime.toString()); + urlQuery.set(QueryParams.endTime, maxTime.toString()); + } else { + urlQuery.set(QueryParams.startTime, preStartTime.toString()); + urlQuery.set(QueryParams.endTime, preEndTime.toString()); + } + const generatedUrl = `${location.pathname}?${urlQuery.toString()}`; + history.replace(generatedUrl); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [location.pathname, updateTimeInterval, globalTimeLoading]); diff --git a/frontend/src/store/actions/trace/getInitialFilter.ts b/frontend/src/store/actions/trace/getInitialFilter.ts index 5ff04b1eff..8a83a1d33f 100644 --- a/frontend/src/store/actions/trace/getInitialFilter.ts +++ b/frontend/src/store/actions/trace/getInitialFilter.ts @@ -25,6 +25,7 @@ import { parseQueryIntoPageSize, parseQueryIntoSelectedTags, parseSelectedFilter, + stripTimestampsFromQuery, } from './util'; export const GetInitialTraceFilter = ( @@ -113,8 +114,11 @@ export const GetInitialTraceFilter = ( ); if (response.payload && !isSelectionSkipped.currentValue) { + /** this is required as now we have timestamps updated in date time selection component + * so for initial filters we need to strip timestamps and check for initial load + */ const diff = - query.length === 0 + stripTimestampsFromQuery(query).length === 0 ? traces.filterToFetchData : xor(traces.filterToFetchData, getFilterToFetchData.currentValue); diff --git a/frontend/src/store/actions/trace/util.ts b/frontend/src/store/actions/trace/util.ts index 3556636f15..54cd819da5 100644 --- a/frontend/src/store/actions/trace/util.ts +++ b/frontend/src/store/actions/trace/util.ts @@ -86,3 +86,6 @@ export const getFilter = (data: GetFilterPayload): TraceReducer['filter'] => { return filter; }; + +export const stripTimestampsFromQuery = (query: string): string => + query.replace(/(\?|&)startTime=\d+/, '').replace(/&endTime=\d+/, ''); From d5637784791c526fe134c89a45e5e3fa53b35435 Mon Sep 17 00:00:00 2001 From: Rajat Dabade Date: Mon, 22 Jan 2024 16:36:03 +0530 Subject: [PATCH 4/6] [Fix]: Resolve glitch in graph due to variable and time stamp change (#4406) * refactor: resolve glitch in variable and time stamp change * refactor: removed unwanted code * refactor: updated code --- .../GridCard/FullView/index.tsx | 28 +++++++++--- .../GridCardLayout/GridCard/FullView/types.ts | 9 ++-- .../GridCard/WidgetGraphComponent.tsx | 44 +++++++++---------- .../GridCardLayout/GridCard/index.tsx | 10 +---- .../GridCardLayout/GridCard/types.ts | 5 ++- 5 files changed, 52 insertions(+), 44 deletions(-) diff --git a/frontend/src/container/GridCardLayout/GridCard/FullView/index.tsx b/frontend/src/container/GridCardLayout/GridCard/FullView/index.tsx index 4ee4c54e93..20f493f666 100644 --- a/frontend/src/container/GridCardLayout/GridCard/FullView/index.tsx +++ b/frontend/src/container/GridCardLayout/GridCard/FullView/index.tsx @@ -18,13 +18,14 @@ import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariab import { getUPlotChartOptions } from 'lib/uPlotLib/getUplotChartOptions'; import { getUPlotChartData } from 'lib/uPlotLib/utils/getUplotChartData'; import { useDashboard } from 'providers/Dashboard/Dashboard'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useSelector } from 'react-redux'; import { AppState } from 'store/reducers'; import { GlobalReducer } from 'types/reducer/globalTime'; import uPlot from 'uplot'; import { getTimeRange } from 'utils/getTimeRange'; +import { getGraphVisibilityStateOnDataChange } from '../utils'; import { PANEL_TYPES_VS_FULL_VIEW_TABLE } from './contants'; import GraphManager from './GraphManager'; // import GraphManager from './GraphManager'; @@ -36,13 +37,14 @@ function FullView({ fullViewOptions = true, onClickHandler, name, + originalName, yAxisUnit, + options, onDragSelect, isDependedDataLoaded = false, - graphsVisibilityStates, onToggleModelHandler, parentChartRef, - setGraphsVisibilityStates, + parentGraphVisibilityState, }: FullViewProps): JSX.Element { const { selectedTime: globalSelectedTime } = useSelector< AppState, @@ -55,6 +57,20 @@ function FullView({ const { selectedDashboard, isDashboardLocked } = useDashboard(); + const { graphVisibilityStates: localStoredVisibilityStates } = useMemo( + () => + getGraphVisibilityStateOnDataChange({ + options, + isExpandedName: false, + name: originalName, + }), + [options, originalName], + ); + + const [graphsVisibilityStates, setGraphsVisibilityStates] = useState( + localStoredVisibilityStates, + ); + const getSelectedTime = useCallback( () => timeItems.find((e) => e.enum === (widget?.timePreferance || 'GLOBAL_TIME')), @@ -144,9 +160,9 @@ function FullView({ useEffect(() => { graphsVisibilityStates?.forEach((e, i) => { fullViewChartRef?.current?.toggleGraph(i, e); - parentChartRef?.current?.toggleGraph(i, e); }); - }, [graphsVisibilityStates, parentChartRef]); + parentGraphVisibilityState(graphsVisibilityStates); + }, [graphsVisibilityStates, parentGraphVisibilityState]); if (response.isFetching) { return ; @@ -206,7 +222,7 @@ function FullView({ {canModifyChart && chartOptions && !isDashboardLocked && ( void; isDependedDataLoaded?: boolean; - graphsVisibilityStates?: boolean[]; onToggleModelHandler?: GraphManagerProps['onToggleModelHandler']; - setGraphsVisibilityStates: Dispatch>; parentChartRef: GraphManagerProps['lineChartRef']; + parentGraphVisibilityState: Dispatch>; } export interface GraphManagerProps extends UplotProps { @@ -64,8 +65,8 @@ export interface GraphManagerProps extends UplotProps { yAxisUnit?: string; onToggleModelHandler?: () => void; options: uPlot.Options; - setGraphsVisibilityStates: FullViewProps['setGraphsVisibilityStates']; - graphsVisibilityStates: FullViewProps['graphsVisibilityStates']; + graphsVisibilityStates?: boolean[]; + setGraphsVisibilityStates: Dispatch>; lineChartRef?: MutableRefObject; parentChartRef?: MutableRefObject; } diff --git a/frontend/src/container/GridCardLayout/GridCard/WidgetGraphComponent.tsx b/frontend/src/container/GridCardLayout/GridCard/WidgetGraphComponent.tsx index 34288a0b19..f77f714b26 100644 --- a/frontend/src/container/GridCardLayout/GridCard/WidgetGraphComponent.tsx +++ b/frontend/src/container/GridCardLayout/GridCard/WidgetGraphComponent.tsx @@ -17,7 +17,6 @@ import { SetStateAction, useCallback, useEffect, - useMemo, useRef, useState, } from 'react'; @@ -39,14 +38,15 @@ function WidgetGraphComponent({ queryResponse, errorMessage, name, - onClickHandler, threshold, headerMenuList, isWarning, data, options, + graphVisibiltyState, + onClickHandler, onDragSelect, - graphVisibility, + setGraphVisibility, }: WidgetGraphComponentProps): JSX.Element { const [deleteModal, setDeleteModal] = useState(false); const [hovered, setHovered] = useState(false); @@ -60,33 +60,28 @@ function WidgetGraphComponent({ const lineChartRef = useRef(); const graphRef = useRef(null); - const { graphVisibilityStates: localStoredVisibilityStates } = useMemo( - () => - getGraphVisibilityStateOnDataChange({ + useEffect(() => { + if (queryResponse.isSuccess) { + const { + graphVisibilityStates: localStoredVisibilityState, + } = getGraphVisibilityStateOnDataChange({ options, - isExpandedName: true, + isExpandedName: false, name, - }), - [options, name], - ); - - const [graphsVisibilityStates, setGraphsVisibilityStates] = useState< - boolean[] - >(localStoredVisibilityStates); + }); + setGraphVisibility(localStoredVisibilityState); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [queryResponse.isSuccess]); useEffect(() => { - setGraphsVisibilityStates(localStoredVisibilityStates); if (!lineChartRef.current) return; - localStoredVisibilityStates.forEach((state, index) => { + graphVisibiltyState.forEach((state, index) => { lineChartRef.current?.toggleGraph(index, state); }); - setGraphsVisibilityStates(localStoredVisibilityStates); - }, [localStoredVisibilityStates]); - - graphVisibility?.forEach((state, index) => { - lineChartRef.current?.toggleGraph(index, state); - }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const { setLayouts, selectedDashboard, setSelectedDashboard } = useDashboard(); @@ -279,13 +274,14 @@ function WidgetGraphComponent({ > diff --git a/frontend/src/container/GridCardLayout/GridCard/index.tsx b/frontend/src/container/GridCardLayout/GridCard/index.tsx index c1c1f99c93..c5dd100a03 100644 --- a/frontend/src/container/GridCardLayout/GridCard/index.tsx +++ b/frontend/src/container/GridCardLayout/GridCard/index.tsx @@ -167,13 +167,6 @@ function GridCardGraph({ Array(queryResponse.data?.payload?.data.result.length || 0).fill(true), ); - useEffect(() => { - setGraphVisibility([ - true, - ...Array(queryResponse.data?.payload?.data.result.length).fill(true), - ]); - }, [queryResponse.data?.payload?.data.result.length]); - const options = useMemo( () => getUPlotChartOptions({ @@ -227,7 +220,8 @@ function GridCardGraph({ threshold={threshold} headerMenuList={menuList} onClickHandler={onClickHandler} - graphVisibility={graphVisibility} + graphVisibiltyState={graphVisibility} + setGraphVisibility={setGraphVisibility} /> )} diff --git a/frontend/src/container/GridCardLayout/GridCard/types.ts b/frontend/src/container/GridCardLayout/GridCard/types.ts index 2298b2b070..d71b529207 100644 --- a/frontend/src/container/GridCardLayout/GridCard/types.ts +++ b/frontend/src/container/GridCardLayout/GridCard/types.ts @@ -1,7 +1,7 @@ import { ToggleGraphProps } from 'components/Graph/types'; import { UplotProps } from 'components/Uplot/Uplot'; import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin'; -import { MutableRefObject, ReactNode } from 'react'; +import { Dispatch, MutableRefObject, ReactNode, SetStateAction } from 'react'; import { UseQueryResult } from 'react-query'; import { ErrorResponse, SuccessResponse } from 'types/api'; import { Dashboard, Widgets } from 'types/api/dashboard/getAll'; @@ -28,7 +28,8 @@ export interface WidgetGraphComponentProps extends UplotProps { threshold?: ReactNode; headerMenuList: MenuItemKeys[]; isWarning: boolean; - graphVisibility?: boolean[]; + graphVisibiltyState: boolean[]; + setGraphVisibility: Dispatch>; } export interface GridCardGraphProps { From 79e6699b3750df1ebc7597841d8a788bb5059ac6 Mon Sep 17 00:00:00 2001 From: Vikrant Gupta Date: Mon, 22 Jan 2024 19:06:33 +0530 Subject: [PATCH 5/6] fix: logs page crash when special chars present in the value of query (#4408) --- .../QueryBuilder/filters/QueryBuilderSearch/utils.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearch/utils.ts b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearch/utils.ts index e767550be7..c549a6fd62 100644 --- a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearch/utils.ts +++ b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearch/utils.ts @@ -122,8 +122,17 @@ export function replaceStringWithMaxLength( if (lastSearchValue === '') { return `${mainString}${replacementString},`; } + /** + * We need to escape the special characters in the lastSearchValue else the + * new RegExp fails with error range out of order in char class + */ + const escapedLastSearchValue = lastSearchValue.replace( + /[-/\\^$*+?.()|[\]{}]/g, + '\\$&', + ); + const updatedString = mainString.replace( - new RegExp(`${lastSearchValue}(?=[^${lastSearchValue}]*$)`), + new RegExp(`${escapedLastSearchValue}(?=[^${escapedLastSearchValue}]*$)`), replacementString, ); return `${updatedString},`; From 64d854ffa2b4a901144fd6b9bc628650f292a403 Mon Sep 17 00:00:00 2001 From: Prashant Shahi Date: Mon, 22 Jan 2024 19:55:04 +0545 Subject: [PATCH 6/6] =?UTF-8?q?chore(signoz):=20=F0=9F=93=8C=20pin=20versi?= =?UTF-8?q?ons:=20SigNoz=200.37.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Prashant Shahi --- deploy/docker-swarm/clickhouse-setup/docker-compose.yaml | 4 ++-- deploy/docker/clickhouse-setup/docker-compose.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml b/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml index 71421a0196..238efaf9bc 100644 --- a/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml +++ b/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml @@ -146,7 +146,7 @@ services: condition: on-failure query-service: - image: signoz/query-service:0.37.0 + image: signoz/query-service:0.37.1 command: [ "-config=/root/config/prometheus.yml", @@ -186,7 +186,7 @@ services: <<: *db-depend frontend: - image: signoz/frontend:0.37.0 + image: signoz/frontend:0.37.1 deploy: restart_policy: condition: on-failure diff --git a/deploy/docker/clickhouse-setup/docker-compose.yaml b/deploy/docker/clickhouse-setup/docker-compose.yaml index ef41cd3ae8..d2d6f7d0ef 100644 --- a/deploy/docker/clickhouse-setup/docker-compose.yaml +++ b/deploy/docker/clickhouse-setup/docker-compose.yaml @@ -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.37.0} + image: signoz/query-service:${DOCKER_TAG:-0.37.1} container_name: signoz-query-service command: [ @@ -203,7 +203,7 @@ services: <<: *db-depend frontend: - image: signoz/frontend:${DOCKER_TAG:-0.37.0} + image: signoz/frontend:${DOCKER_TAG:-0.37.1} container_name: signoz-frontend restart: on-failure depends_on: