@@ -302,7 +311,9 @@ function SideNav({
item={item}
isActive={activeMenuKey === item.key}
onClick={(): void => {
- if (item) {
+ if (item.key === ROUTES.SETTINGS) {
+ history.push(settingsRoute);
+ } else if (item) {
onClickHandler(item?.key as string);
}
}}
diff --git a/frontend/src/container/TopNav/DateTimeSelection/config.ts b/frontend/src/container/TopNav/DateTimeSelection/config.ts
index 0ece952909..bc77afe7d6 100644
--- a/frontend/src/container/TopNav/DateTimeSelection/config.ts
+++ b/frontend/src/container/TopNav/DateTimeSelection/config.ts
@@ -96,3 +96,13 @@ export const routesToSkip = [
];
export const routesToDisable = [ROUTES.LOGS_EXPLORER, ROUTES.LIVE_LOGS];
+
+export interface LocalStorageTimeRange {
+ localstorageStartTime: string | null;
+ localstorageEndTime: string | null;
+}
+
+export interface TimeRange {
+ startTime: string;
+ endTime: string;
+}
diff --git a/frontend/src/container/TopNav/DateTimeSelection/index.tsx b/frontend/src/container/TopNav/DateTimeSelection/index.tsx
index 58b090abb9..12e47e9f73 100644
--- a/frontend/src/container/TopNav/DateTimeSelection/index.tsx
+++ b/frontend/src/container/TopNav/DateTimeSelection/index.tsx
@@ -15,6 +15,7 @@ import useUrlQuery from 'hooks/useUrlQuery';
import GetMinMax from 'lib/getMinMax';
import getTimeString from 'lib/getTimeString';
import history from 'lib/history';
+import { isObject } from 'lodash-es';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { connect, useSelector } from 'react-redux';
import { RouteComponentProps, withRouter } from 'react-router-dom';
@@ -27,7 +28,13 @@ import { GlobalReducer } from 'types/reducer/globalTime';
import AutoRefresh from '../AutoRefresh';
import CustomDateTimeModal, { DateTimeRangeType } from '../CustomDateTimeModal';
-import { getDefaultOption, getOptions, Time } from './config';
+import {
+ getDefaultOption,
+ getOptions,
+ LocalStorageTimeRange,
+ Time,
+ TimeRange,
+} from './config';
import RefreshText from './Refresh';
import { Form, FormContainer, FormItem } from './styles';
@@ -44,8 +51,35 @@ function DateTimeSelection({
const searchStartTime = urlQuery.get('startTime');
const searchEndTime = urlQuery.get('endTime');
- const localstorageStartTime = getLocalStorageKey('startTime');
- const localstorageEndTime = getLocalStorageKey('endTime');
+ const {
+ localstorageStartTime,
+ localstorageEndTime,
+ } = ((): LocalStorageTimeRange => {
+ const routes = getLocalStorageKey(LOCALSTORAGE.METRICS_TIME_IN_DURATION);
+
+ if (routes !== null) {
+ const routesObject = JSON.parse(routes || '{}');
+ const selectedTime = routesObject[location.pathname];
+
+ if (selectedTime) {
+ let parsedSelectedTime: TimeRange;
+ try {
+ parsedSelectedTime = JSON.parse(selectedTime);
+ } catch {
+ parsedSelectedTime = selectedTime;
+ }
+
+ if (isObject(parsedSelectedTime)) {
+ return {
+ localstorageStartTime: parsedSelectedTime.startTime,
+ localstorageEndTime: parsedSelectedTime.endTime,
+ };
+ }
+ return { localstorageStartTime: null, localstorageEndTime: null };
+ }
+ }
+ return { localstorageStartTime: null, localstorageEndTime: null };
+ })();
const getTime = useCallback((): [number, number] | undefined => {
if (searchEndTime && searchStartTime) {
@@ -118,6 +152,15 @@ function DateTimeSelection({
const selectedTime = routesObject[pathName];
if (selectedTime) {
+ let parsedSelectedTime: TimeRange;
+ try {
+ parsedSelectedTime = JSON.parse(selectedTime);
+ } catch {
+ parsedSelectedTime = selectedTime;
+ }
+ if (isObject(parsedSelectedTime)) {
+ return 'custom';
+ }
return selectedTime;
}
}
@@ -125,7 +168,7 @@ function DateTimeSelection({
return defaultSelectedOption;
};
- const updateLocalStorageForRoutes = (value: Time): void => {
+ const updateLocalStorageForRoutes = (value: Time | string): void => {
const preRoutes = getLocalStorageKey(LOCALSTORAGE.METRICS_TIME_IN_DURATION);
if (preRoutes !== null) {
const preRoutesObject = JSON.parse(preRoutes);
@@ -220,9 +263,9 @@ function DateTimeSelection({
startTimeMoment?.toDate().getTime() || 0,
endTimeMoment?.toDate().getTime() || 0,
]);
- setLocalStorageKey('startTime', startTimeMoment.toString());
- setLocalStorageKey('endTime', endTimeMoment.toString());
- updateLocalStorageForRoutes('custom');
+ updateLocalStorageForRoutes(
+ JSON.stringify({ startTime: startTimeMoment, endTime: endTimeMoment }),
+ );
if (!isLogsExplorerPage) {
urlQuery.set(
QueryParams.startTime,
diff --git a/frontend/src/lib/getChartData.ts b/frontend/src/lib/getChartData.ts
index 4bb8789ad4..3742487366 100644
--- a/frontend/src/lib/getChartData.ts
+++ b/frontend/src/lib/getChartData.ts
@@ -88,9 +88,11 @@ const getChartData = ({
const allLabels = modifiedData.map((e) => e.label);
const updatedDataSet = updatedSortedData.map((e, index) => {
+ const label = allLabels[index];
+
const datasetBaseConfig = {
index,
- label: allLabels[index],
+ label,
borderColor: colors[index % colors.length] || 'red',
data: e.second,
borderWidth: 1.5,
diff --git a/frontend/src/lib/uPlotLib/plugins/tooltipPlugin.ts b/frontend/src/lib/uPlotLib/plugins/tooltipPlugin.ts
index d714564855..713bf7958d 100644
--- a/frontend/src/lib/uPlotLib/plugins/tooltipPlugin.ts
+++ b/frontend/src/lib/uPlotLib/plugins/tooltipPlugin.ts
@@ -1,11 +1,12 @@
import { getToolTipValue } from 'components/Graph/yAxisConfig';
+import { themeColors } from 'constants/theme';
import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import getLabelName from 'lib/getLabelName';
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
-import { colors } from '../../getRandomColor';
import { placement } from '../placement';
+import { generateColor } from '../utils/generateColor';
dayjs.extend(customParseFormat);
@@ -54,12 +55,14 @@ const generateTooltipContent = (
const value = data[index][idx];
const label = getLabelName(metric, queryName || '', legend || '');
+ const color = generateColor(label, themeColors.chartcolors);
+
if (Number.isFinite(value)) {
const tooltipValue = getToolTipValue(value, yAxisUnit);
const dataObj = {
show: item.show || false,
- color: colors[(index - 1) % colors.length],
+ color,
label,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
diff --git a/frontend/src/lib/uPlotLib/utils/generateColor.ts b/frontend/src/lib/uPlotLib/utils/generateColor.ts
new file mode 100644
index 0000000000..c58fde4e62
--- /dev/null
+++ b/frontend/src/lib/uPlotLib/utils/generateColor.ts
@@ -0,0 +1,20 @@
+/* eslint-disable no-bitwise */
+export function hashFn(str: string): number {
+ let hash = 5381;
+ for (let i = 0; i < str.length; i++) {
+ hash = (hash * 33) ^ str.charCodeAt(i);
+ }
+
+ return hash >>> 0;
+}
+
+export function generateColor(
+ key: string,
+ colorMap: Record,
+): string {
+ const hashValue = hashFn(key);
+ const keys = Object.keys(colorMap);
+ const colorIndex = hashValue % keys.length;
+ const selectedKey = keys[colorIndex];
+ return colorMap[selectedKey];
+}
diff --git a/frontend/src/lib/uPlotLib/utils/getSeriesData.ts b/frontend/src/lib/uPlotLib/utils/getSeriesData.ts
index d5f985e458..16be3aa04e 100644
--- a/frontend/src/lib/uPlotLib/utils/getSeriesData.ts
+++ b/frontend/src/lib/uPlotLib/utils/getSeriesData.ts
@@ -1,8 +1,9 @@
+import { themeColors } from 'constants/theme';
import getLabelName from 'lib/getLabelName';
-import { colors } from 'lib/getRandomColor';
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
import { QueryData } from 'types/api/widgets/getQuery';
+import { generateColor } from './generateColor';
import getRenderer, { drawStyles, lineInterpolations } from './getRenderer';
const paths = (
@@ -36,8 +37,6 @@ const getSeries = (
const newGraphVisibilityStates = graphsVisibilityStates?.slice(1);
for (let i = 0; i < seriesList?.length; i += 1) {
- const color = colors[i % colors.length]; // Use modulo to loop through colors if there are more series than colors
-
const { metric = {}, queryName = '', legend = '' } = widgetMetaData[i] || {};
const label = getLabelName(
@@ -46,6 +45,8 @@ const getSeries = (
legend || '',
);
+ const color = generateColor(label, themeColors.chartcolors);
+
const pointSize = seriesList[i].values.length > 1 ? 5 : 10;
const showPoints = !(seriesList[i].values.length > 1);
diff --git a/frontend/src/pages/Settings/config.ts b/frontend/src/pages/Settings/config.ts
index 26fb1805fa..ca18559ec5 100644
--- a/frontend/src/pages/Settings/config.ts
+++ b/frontend/src/pages/Settings/config.ts
@@ -2,17 +2,21 @@ import { RouteTabProps } from 'components/RouteTab/types';
import ROUTES from 'constants/routes';
import AlertChannels from 'container/AllAlertChannels';
import GeneralSettings from 'container/GeneralSettings';
+import GeneralSettingsCloud from 'container/GeneralSettingsCloud';
import IngestionSettings from 'container/IngestionSettings/IngestionSettings';
import OrganizationSettings from 'container/OrganizationSettings';
import { TFunction } from 'i18next';
-export const commonRoutes = (t: TFunction): RouteTabProps['routes'] => [
+export const organizationSettings = (t: TFunction): RouteTabProps['routes'] => [
{
- Component: GeneralSettings,
- name: t('routes:general').toString(),
- route: ROUTES.SETTINGS,
- key: ROUTES.SETTINGS,
+ Component: OrganizationSettings,
+ name: t('routes:organization_settings').toString(),
+ route: ROUTES.ORG_SETTINGS,
+ key: ROUTES.ORG_SETTINGS,
},
+];
+
+export const alertChannels = (t: TFunction): RouteTabProps['routes'] => [
{
Component: AlertChannels,
name: t('routes:alert_channels').toString(),
@@ -30,11 +34,20 @@ export const ingestionSettings = (t: TFunction): RouteTabProps['routes'] => [
},
];
-export const organizationSettings = (t: TFunction): RouteTabProps['routes'] => [
+export const generalSettings = (t: TFunction): RouteTabProps['routes'] => [
{
- Component: OrganizationSettings,
- name: t('routes:organization_settings').toString(),
- route: ROUTES.ORG_SETTINGS,
- key: ROUTES.ORG_SETTINGS,
+ Component: GeneralSettings,
+ name: t('routes:general').toString(),
+ route: ROUTES.SETTINGS,
+ key: ROUTES.SETTINGS,
+ },
+];
+
+export const generalSettingsCloud = (t: TFunction): RouteTabProps['routes'] => [
+ {
+ Component: GeneralSettingsCloud,
+ name: t('routes:general').toString(),
+ route: ROUTES.SETTINGS,
+ key: ROUTES.SETTINGS,
},
];
diff --git a/frontend/src/pages/Settings/utils.ts b/frontend/src/pages/Settings/utils.ts
index 862ee0adb9..89a4e7f3ef 100644
--- a/frontend/src/pages/Settings/utils.ts
+++ b/frontend/src/pages/Settings/utils.ts
@@ -3,7 +3,9 @@ import { TFunction } from 'i18next';
import { isCloudUser } from 'utils/app';
import {
- commonRoutes,
+ alertChannels,
+ generalSettings,
+ generalSettingsCloud,
ingestionSettings,
organizationSettings,
} from './config';
@@ -12,15 +14,20 @@ export const getRoutes = (
isCurrentOrgSettings: boolean,
t: TFunction,
): RouteTabProps['routes'] => {
- let common = commonRoutes(t);
+ const settings = [];
if (isCurrentOrgSettings) {
- common = [...common, ...organizationSettings(t)];
+ settings.push(...organizationSettings(t));
}
if (isCloudUser()) {
- common = [...common, ...ingestionSettings(t)];
+ settings.push(...ingestionSettings(t));
+ settings.push(...alertChannels(t));
+ settings.push(...generalSettingsCloud(t));
+ } else {
+ settings.push(...alertChannels(t));
+ settings.push(...generalSettings(t));
}
- return common;
+ return settings;
};
diff --git a/go.mod b/go.mod
index eeb6e05ec9..d7d824f47d 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.21
require (
github.com/ClickHouse/clickhouse-go/v2 v2.15.0
github.com/SigNoz/govaluate v0.0.0-20220522085550-d19c08c206cb
- github.com/SigNoz/signoz-otel-collector v0.88.9
+ github.com/SigNoz/signoz-otel-collector v0.88.11
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
diff --git a/go.sum b/go.sum
index 5d28bc873e..f65f071c40 100644
--- a/go.sum
+++ b/go.sum
@@ -98,8 +98,8 @@ github.com/SigNoz/govaluate v0.0.0-20220522085550-d19c08c206cb h1:bneLSKPf9YUSFm
github.com/SigNoz/govaluate v0.0.0-20220522085550-d19c08c206cb/go.mod h1:JznGDNg9x1cujDKa22RaQOimOvvEfy3nxzDGd8XDgmA=
github.com/SigNoz/prometheus v1.9.78 h1:bB3yuDrRzi/Mv00kWayR9DZbyjTuGfendSqISyDcXiY=
github.com/SigNoz/prometheus v1.9.78/go.mod h1:MffmFu2qFILQrOHehx3D0XjYtaZMVfI+Ppeiv98x4Ww=
-github.com/SigNoz/signoz-otel-collector v0.88.9 h1:7bbJSXrSZcQsdEVVLsjsNXm/bWe9MhKu8qfXp8MlXQM=
-github.com/SigNoz/signoz-otel-collector v0.88.9/go.mod h1:7I4FWwraVSnDywsPNbo8TdHDsPxShtYkGU5usr6dTtk=
+github.com/SigNoz/signoz-otel-collector v0.88.11 h1:w9IVcXg5T+o37c0HVtBfxdKxkPYyiGX1YaOrCexpjrc=
+github.com/SigNoz/signoz-otel-collector v0.88.11/go.mod h1:2ddO2lcb/4kMONIJXwfXxegRsi7FYPSWtXTgji3qsp8=
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=
diff --git a/pkg/query-service/tests/test-deploy/docker-compose.yaml b/pkg/query-service/tests/test-deploy/docker-compose.yaml
index 7ce3107dbd..25de92e819 100644
--- a/pkg/query-service/tests/test-deploy/docker-compose.yaml
+++ b/pkg/query-service/tests/test-deploy/docker-compose.yaml
@@ -192,7 +192,7 @@ services:
<<: *db-depend
otel-collector-migrator:
- image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.9}
+ image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.11}
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.9
+ image: signoz/signoz-otel-collector:0.88.11
container_name: signoz-otel-collector
command:
[