diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 0031ac2632..f5f5e5610a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -36,6 +36,7 @@ jobs: run: | echo 'INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > frontend/.env echo 'SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env + echo 'CLARITY_PROJECT_ID="${{ secrets.CLARITY_PROJECT_ID }}"' >> frontend/.env - name: Install dependencies run: cd frontend && yarn install - name: Run ESLint diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index a284ca5b47..98ee1e0fc4 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -133,6 +133,7 @@ jobs: run: | echo 'INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > frontend/.env echo 'SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env + echo 'CLARITY_PROJECT_ID="${{ secrets.CLARITY_PROJECT_ID }}"' >> frontend/.env - name: Install dependencies working-directory: frontend run: yarn install diff --git a/Makefile b/Makefile index 05b6cb27e6..7d976341c1 100644 --- a/Makefile +++ b/Makefile @@ -151,4 +151,5 @@ test: go test ./pkg/query-service/app/querier/... go test ./pkg/query-service/converter/... go test ./pkg/query-service/formatter/... - go test ./pkg/query-service/tests/integration/... \ No newline at end of file + go test ./pkg/query-service/tests/integration/... + go test ./pkg/query-service/rules/... diff --git a/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml b/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml index 341d8ca57d..a9e778642e 100644 --- a/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml +++ b/deploy/docker-swarm/clickhouse-setup/docker-compose.yaml @@ -144,7 +144,7 @@ services: condition: on-failure query-service: - image: signoz/query-service:0.29.3 + image: signoz/query-service:0.30.0 command: [ "-config=/root/config/prometheus.yml", @@ -184,7 +184,7 @@ services: <<: *clickhouse-depend frontend: - image: signoz/frontend:0.29.3 + image: signoz/frontend:0.30.0 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 b7f28c7799..7c770c5acf 100644 --- a/deploy/docker/clickhouse-setup/docker-compose.yaml +++ b/deploy/docker/clickhouse-setup/docker-compose.yaml @@ -162,7 +162,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.29.3} + image: signoz/query-service:${DOCKER_TAG:-0.30.0} container_name: signoz-query-service command: [ @@ -201,7 +201,7 @@ services: <<: *clickhouse-depend frontend: - image: signoz/frontend:${DOCKER_TAG:-0.29.3} + image: signoz/frontend:${DOCKER_TAG:-0.30.0} container_name: signoz-frontend restart: on-failure depends_on: diff --git a/frontend/.prettierignore b/frontend/.prettierignore new file mode 100644 index 0000000000..69797b1008 --- /dev/null +++ b/frontend/.prettierignore @@ -0,0 +1,6 @@ +# Ignore artifacts: +build +coverage + +# Ignore all MD files: +**/*.md \ No newline at end of file diff --git a/frontend/jest.config.ts b/frontend/jest.config.ts index 00bd8505c8..b7cac3cc02 100644 --- a/frontend/jest.config.ts +++ b/frontend/jest.config.ts @@ -7,7 +7,7 @@ const config: Config.InitialOptions = { moduleFileExtensions: ['ts', 'tsx', 'js', 'json'], modulePathIgnorePatterns: ['dist'], moduleNameMapper: { - '\\.(css|less)$': '/__mocks__/cssMock.ts', + '\\.(css|less|scss)$': '/__mocks__/cssMock.ts', }, globals: { extensionsToTreatAsEsm: ['.ts'], diff --git a/frontend/package.json b/frontend/package.json index 8e013ce78a..da217e7888 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -84,9 +84,11 @@ "react-helmet-async": "1.3.0", "react-i18next": "^11.16.1", "react-intersection-observer": "9.4.1", + "react-markdown": "8.0.7", "react-query": "^3.34.19", "react-redux": "^7.2.2", "react-router-dom": "^5.2.0", + "react-syntax-highlighter": "15.5.0", "react-use": "^17.3.2", "react-virtuoso": "4.0.3", "redux": "^4.0.5", @@ -150,6 +152,7 @@ "@types/react-redux": "^7.1.11", "@types/react-resizable": "3.0.3", "@types/react-router-dom": "^5.1.6", + "@types/react-syntax-highlighter": "15.5.7", "@types/styled-components": "^5.1.4", "@types/uuid": "^8.3.1", "@types/webpack": "^5.28.0", @@ -183,6 +186,7 @@ "lint-staged": "^12.5.0", "portfinder-sync": "^0.0.2", "prettier": "2.2.1", + "raw-loader": "4.0.2", "react-hooks-testing-library": "0.6.0", "react-hot-loader": "^4.13.0", "react-resizable": "3.0.4", diff --git a/frontend/public/locales/en/pipeline.json b/frontend/public/locales/en/pipeline.json index 515ce19003..77989fdfc5 100644 --- a/frontend/public/locales/en/pipeline.json +++ b/frontend/public/locales/en/pipeline.json @@ -25,6 +25,7 @@ "delete_processor_description": "Logs are processed sequentially in processors. Deleting a processor may change content of data processed by other processors", "search_pipeline_placeholder": "Filter Pipelines", "pipeline_name_placeholder": "Name", + "pipeline_filter_placeholder": "Filter for selecting logs to be processed by this pipeline. Example: service_name = billing", "pipeline_tags_placeholder": "Tags", "pipeline_description_placeholder": "Enter description for your pipeline", "processor_name_placeholder": "Name", diff --git a/frontend/src/AppRoutes/index.tsx b/frontend/src/AppRoutes/index.tsx index 4c46928163..56ba19fdf4 100644 --- a/frontend/src/AppRoutes/index.tsx +++ b/frontend/src/AppRoutes/index.tsx @@ -1,7 +1,10 @@ import { ConfigProvider } from 'antd'; +import getLocalStorageApi from 'api/browser/localstorage/get'; +import setLocalStorageApi from 'api/browser/localstorage/set'; import NotFound from 'components/NotFound'; import Spinner from 'components/Spinner'; import { FeatureKeys } from 'constants/features'; +import { LOCALSTORAGE } from 'constants/localStorage'; import ROUTES from 'constants/routes'; import AppLayout from 'container/AppLayout'; import { useThemeConfig } from 'hooks/useDarkMode'; @@ -75,14 +78,26 @@ function App(): JSX.Element { }); useEffect(() => { - if (isLoggedInState && user && user.userId && user.email) { + const isIdentifiedUser = getLocalStorageApi(LOCALSTORAGE.IS_IDENTIFIED_USER); + + if ( + isLoggedInState && + user && + user.userId && + user.email && + !isIdentifiedUser + ) { + setLocalStorageApi(LOCALSTORAGE.IS_IDENTIFIED_USER, 'true'); + window.analytics.identify(user?.email, { email: user?.email, name: user?.name, }); + + window.clarity('identify', user.email, user.name); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [isLoggedInState]); + }, [isLoggedInState, user]); useEffect(() => { trackPageView(pathname); diff --git a/frontend/src/api/utils.ts b/frontend/src/api/utils.ts index 2d31836733..140e793e35 100644 --- a/frontend/src/api/utils.ts +++ b/frontend/src/api/utils.ts @@ -14,7 +14,11 @@ import { export const Logout = (): void => { deleteLocalStorageKey(LOCALSTORAGE.AUTH_TOKEN); deleteLocalStorageKey(LOCALSTORAGE.IS_LOGGED_IN); + deleteLocalStorageKey(LOCALSTORAGE.IS_IDENTIFIED_USER); deleteLocalStorageKey(LOCALSTORAGE.REFRESH_AUTH_TOKEN); + deleteLocalStorageKey(LOCALSTORAGE.LOGGED_IN_USER_EMAIL); + deleteLocalStorageKey(LOCALSTORAGE.LOGGED_IN_USER_NAME); + deleteLocalStorageKey(LOCALSTORAGE.CHAT_SUPPORT); store.dispatch({ type: LOGGED_IN, diff --git a/frontend/src/components/ExplorerCard/ExplorerCard.tsx b/frontend/src/components/ExplorerCard/ExplorerCard.tsx index 0944023b6c..b49cfaa2d6 100644 --- a/frontend/src/components/ExplorerCard/ExplorerCard.tsx +++ b/frontend/src/components/ExplorerCard/ExplorerCard.tsx @@ -30,6 +30,7 @@ import { useNotifications } from 'hooks/useNotifications'; import { mapCompositeQueryFromQuery } from 'lib/newQueryBuilder/queryBuilderMappers/mapCompositeQueryFromQuery'; import { useState } from 'react'; import { useCopyToClipboard } from 'react-use'; +import { popupContainer } from 'utils/selectPopupContainer'; import { ExploreHeaderToolTip, SaveButtonText } from './constants'; import MenuItemGenerator from './MenuItemGenerator'; @@ -170,6 +171,7 @@ function ExplorerCard({ {viewsData?.data.data && viewsData?.data.data.length && ( {isFormatButtonVisible && ( - + )} diff --git a/frontend/src/container/LiveLogs/constants.ts b/frontend/src/container/LiveLogs/constants.ts index f2c5ca1c97..83df3759ee 100644 --- a/frontend/src/container/LiveLogs/constants.ts +++ b/frontend/src/container/LiveLogs/constants.ts @@ -2,7 +2,7 @@ import { initialQueriesMap, initialQueryBuilderFormValuesMap, } from 'constants/queryBuilder'; -import { FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config'; +import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config'; import { BaseAutocompleteData, DataTypes, @@ -14,7 +14,7 @@ export const defaultLiveQueryDataConfig: Partial = { aggregateOperator: LogsAggregatorOperator.NOOP, disabled: true, pageSize: 10, - orderBy: [{ columnName: 'timestamp', order: FILTERS.DESC }], + orderBy: [{ columnName: 'timestamp', order: ORDERBY_FILTERS.DESC }], }; type GetDefaultCompositeQueryParams = { diff --git a/frontend/src/container/LogDetailedView/utils.tsx b/frontend/src/container/LogDetailedView/utils.tsx index c07c4c7622..02890e7dc9 100644 --- a/frontend/src/container/LogDetailedView/utils.tsx +++ b/frontend/src/container/LogDetailedView/utils.tsx @@ -198,6 +198,7 @@ export const aggregateAttributesResourcesToString = (logData: ILog): string => { traceId: logData.traceId, attributes: {}, resources: {}, + severity_text: logData.severity_text, }; Object.keys(logData).forEach((key) => { diff --git a/frontend/src/container/LogLiveTail/index.tsx b/frontend/src/container/LogLiveTail/index.tsx index 08faeda94c..070423229f 100644 --- a/frontend/src/container/LogLiveTail/index.tsx +++ b/frontend/src/container/LogLiveTail/index.tsx @@ -30,6 +30,7 @@ import { TLogsLiveTailState } from 'types/api/logs/liveTail'; import { ILog } from 'types/api/logs/log'; import { GlobalReducer } from 'types/reducer/globalTime'; import { ILogsReducer } from 'types/reducer/logs'; +import { popupContainer } from 'utils/selectPopupContainer'; import { TIME_PICKER_OPTIONS } from './config'; import { StopContainer, TimePickerCard, TimePickerSelect } from './styles'; @@ -165,6 +166,7 @@ function LogLiveTail({ getLogsAggregate }: Props): JSX.Element { const OptionsPopOverContent = useMemo( () => ( { @@ -236,6 +238,7 @@ function LogLiveTail({ getLogsAggregate }: Props): JSX.Element { )} (false); const { user } = useSelector((state) => state.app); - const isChatSupportEnabled: boolean | undefined = useFeatureFlag( - FeatureKeys.CHAT_SUPPORT, - )?.active; const [precheckResult, setPrecheckResult] = useState({ sso: false, @@ -165,21 +158,12 @@ function Login({ password, }); if (response.statusCode === 200) { - const user = await afterLogin( + await afterLogin( response.payload.userId, response.payload.accessJwt, response.payload.refreshJwt, ); - if (user) { - setLocalStorageApi(LOCALSTORAGE.LOGGED_IN_USER_NAME, user.payload?.name); - setLocalStorageApi(LOCALSTORAGE.LOGGED_IN_USER_EMAIL, user.payload?.email); - setLocalStorageApi( - LOCALSTORAGE.CHAT_SUPPORT, - (isChatSupportEnabled || '').toString(), - ); - } - history.push(ROUTES.APPLICATION); } else { notifications.error({ diff --git a/frontend/src/container/LogsContextList/ShowButton.tsx b/frontend/src/container/LogsContextList/ShowButton.tsx index 26fbadaf30..7240800af7 100644 --- a/frontend/src/container/LogsContextList/ShowButton.tsx +++ b/frontend/src/container/LogsContextList/ShowButton.tsx @@ -1,5 +1,5 @@ import { Button, Typography } from 'antd'; -import { FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config'; +import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config'; import { ShowButtonWrapper } from './styles'; @@ -19,7 +19,7 @@ function ShowButton({ return ( - Showing 10 lines {order === FILTERS.ASC ? 'after' : 'before'} match + Showing 10 lines {order === ORDERBY_FILTERS.ASC ? 'after' : 'before'} match