Compare commits

..

20 Commits

Author SHA1 Message Date
Gaurav Tewari
c1e81a57a3 chore: remove ox lint 2026-05-22 20:54:16 +05:30
Gaurav Tewari
c30994f966 fix: lint 2026-05-22 20:51:38 +05:30
Gaurav Tewari
9aef69a186 fix: lint 2026-05-22 20:48:05 +05:30
Gaurav Tewari
66bc4b4398 Merge remote-tracking branch 'origin/main' into refactor/dropdown-migration
# Conflicts:
#	frontend/plugins/rules/no-antd-components.mjs
#	frontend/src/components/ResizeTable/DynamicColumnTable.tsx
#	frontend/src/pages/AlertDetails/AlertHeader/ActionButtons/ActionButtons.tsx
#	frontend/src/pages/TracesFunnelDetails/components/FunnelConfiguration/FunnelStep.tsx
2026-05-22 19:03:05 +05:30
Vinicius Lourenço
04a4d3fe32 fix(date-time-selection-v2): out of sync query params (#11399)
* fix(date-time-selection-v2): out of sync query params

* chore(get-current-search-params): explain why we have that file

* fix(pr): address comments
2026-05-22 11:58:53 +00:00
swapnil-signoz
27dc996fd8 chore(integrations): make dot-metrics dashboards canonical, remove IsDotMetricsEnabled flag (#11406)
IsDotMetricsEnabled always returns true so the _dot.json variants were
always served. Replace each non-dot dashboard JSON with the dot content,
delete the _dot.json files, and remove the dead flag-check logic from
HydrateFileUris.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 10:14:48 +00:00
Karan Balani
83b25f3e9a fix(authdomain): sso enabled toggle value from nested config (#11402)
* fix(authdomain): read ssoEnabled from nested config path in enforce SSO column

* test(authdomain): assert enforce SSO toggle reflects nested config.ssoEnabled

* test(authdomain): drop unnecessary Switch mock

---------

Co-authored-by: Karan Balani <29383381+balanikaran@users.noreply.github.com>
2026-05-22 09:24:09 +00:00
Yunus M
67e4c4611c refactor: replace Ant Design Switch with Signoz UI Switch across mult… (#11223)
* refactor: replace Ant Design Switch with Signoz UI Switch across multiple components

* fix: update snapshot of failing test

* feat: update snapshot

* refactor: update imports to use Signoz UI Switch from the new path across multiple components

* refactor: update banned components to use Signoz UI imports for Typography and Switch

* refactor: replace Ant Design Switch with Signoz UI Switch
2026-05-22 08:50:41 +00:00
Gaurav Tewari
04c58a1572 chore: save antd file 2026-05-22 01:58:11 +05:30
Gaurav Tewari
9bbdd00858 chore: sync with main 2026-05-22 01:56:59 +05:30
Gaurav Tewari
316e9c7361 chore: remove internal docs 2026-05-22 01:50:54 +05:30
Gaurav Tewari
634166860b fix: add dropdown to list 2026-05-22 01:40:15 +05:30
Gaurav Tewari
af8f2fa95a chore: self review comments 2026-05-22 01:32:54 +05:30
Gaurav Tewari
f81fd78ff6 fix: lint 2026-05-21 22:09:24 +05:30
Gaurav Tewari
b589a7b2e9 fix: failing test 2026-05-21 20:24:03 +05:30
Gaurav Tewari
716dbc7847 chore: migration from antd 2026-05-21 18:05:21 +05:30
Gaurav Tewari
3a92c7577f fix: another bug 2026-05-21 16:00:12 +05:30
Gaurav Tewari
ba043a5741 fix: side nav issue 2026-05-21 14:59:23 +05:30
Gaurav Tewari
6d2b99eb8d fix: self review changes 2026-05-21 14:11:13 +05:30
Gaurav Tewari
3765ca3d42 chore: migrate dropdown 2026-05-20 17:39:33 +05:30
107 changed files with 2532 additions and 22137 deletions

View File

@@ -14,7 +14,11 @@
*/
const BANNED_COMPONENTS = {
Typography: 'Use @signozhq/ui Typography instead of antd Typography.',
Typography:
'Use @signozhq/ui/typography Typography instead of antd Typography.',
Switch: 'Use @signozhq/ui/switch Switch instead of antd Switch.',
Dropdown:
'Use @signozhq/ui DropdownMenuSimple (or the composable DropdownMenu primitives) from @signozhq/ui/dropdown-menu instead of antd Dropdown.',
Badge: 'Use @signozhq/ui/badge instead of antd Badge.',
};

View File

@@ -1,7 +0,0 @@
.dropdown-button {
color: var(--l1-foreground);
}
.dropdown-icon {
font-size: 1.2rem;
}

View File

@@ -1,51 +0,0 @@
import { useState } from 'react';
import { Ellipsis } from '@signozhq/icons';
import { Button, Dropdown, MenuProps } from 'antd';
import './DropDown.styles.scss';
function DropDown({
element,
onDropDownItemClick,
}: {
element: JSX.Element[];
onDropDownItemClick?: MenuProps['onClick'];
}): JSX.Element {
const items: MenuProps['items'] = element.map(
(e: JSX.Element, index: number) => ({
label: e,
key: index,
}),
);
const [isDdOpen, setDdOpen] = useState<boolean>(false);
return (
<Dropdown
menu={{
items,
onMouseEnter: (): void => setDdOpen(true),
onMouseLeave: (): void => setDdOpen(false),
onClick: (item): void => onDropDownItemClick?.(item),
}}
open={isDdOpen}
>
<Button
type="link"
className={`dropdown-button`}
onClick={(e): void => {
e.preventDefault();
setDdOpen(true);
}}
>
<Ellipsis className="dropdown-icon" size={16} />
</Button>
</Dropdown>
);
}
DropDown.defaultProps = {
onDropDownItemClick: (): void => {},
};
export default DropDown;

View File

@@ -1,15 +1,7 @@
import { useState } from 'react';
import { useCopyToClipboard } from 'react-use';
import {
Button,
Col,
Dropdown,
MenuProps,
Popover,
Row,
Select,
Space,
} from 'antd';
import { Button, Col, Popover, Row, Select, Space } from 'antd';
import { DropdownMenuSimple, type MenuProps } from '@signozhq/ui/dropdown-menu';
import { Typography } from '@signozhq/ui/typography';
import axios from 'axios';
import TextToolTip from 'components/TextToolTip';
@@ -241,9 +233,9 @@ function ExplorerCard({
</Popover>
<Share2 onClick={onCopyUrlHandler} size="md" />
{viewKey && (
<Dropdown trigger={['click']} menu={moreOptionMenu}>
<Ellipsis size="md" />
</Dropdown>
<DropdownMenuSimple menu={moreOptionMenu}>
<Button type="text" size="small" icon={<Ellipsis size="md" />} />
</DropdownMenuSimple>
)}
</Space>
</OffSetCol>

View File

@@ -4,7 +4,8 @@ import { useSelector } from 'react-redux';
import { matchPath, useLocation } from 'react-router-dom';
import { useCopyToClipboard } from 'react-use';
import { Color } from '@signozhq/design-tokens';
import { Button, Switch } from 'antd';
import { Button } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import logEvent from 'api/common/logEvent';
import { QueryParams } from 'constants/query';
@@ -125,9 +126,8 @@ function ShareURLModal(): JSX.Element {
<Info size={14} color={Color.BG_AMBER_600} />
)}
<Switch
checked={enableAbsoluteTime}
value={enableAbsoluteTime}
disabled={!isValidateRelativeTime}
size="small"
onChange={(): void => {
setEnableAbsoluteTime((prev) => !prev);
}}

View File

@@ -6,7 +6,7 @@ import {
useMemo,
useState,
} from 'react';
import { Dropdown } from 'antd';
import { DropdownMenuSimple } from '@signozhq/ui/dropdown-menu';
import cx from 'classnames';
import { ENTITY_VERSION_V4, ENTITY_VERSION_V5 } from 'constants/app';
import { PANEL_TYPES } from 'constants/queryBuilder';
@@ -195,7 +195,7 @@ export const QueryV2 = forwardRef(function QueryV2(
)}
{isMultiQueryAllowed && (
<Dropdown
<DropdownMenuSimple
className="query-actions-dropdown"
menu={{
items: [
@@ -217,10 +217,10 @@ export const QueryV2 = forwardRef(function QueryV2(
: []),
],
}}
placement="bottomRight"
align="end"
>
<Ellipsis size={16} />
</Dropdown>
</DropdownMenuSimple>
)}
</div>
</div>

View File

@@ -14,7 +14,8 @@ import {
ComboboxList,
ComboboxTrigger,
} from '@signozhq/ui/combobox';
import { Skeleton, Switch, Tooltip } from 'antd';
import { Skeleton, Tooltip } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import getLocalStorageKey from 'api/browser/localstorage/get';
import setLocalStorageKey from 'api/browser/localstorage/set';
@@ -281,9 +282,8 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element {
<div className="api-quick-filters-header">
<Typography.Text>Show IP addresses</Typography.Text>
<Switch
size="small"
style={{ marginLeft: 'auto' }}
checked={showIP ?? true}
value={showIP ?? true}
onChange={(checked): void => {
logEvent('API Monitoring: Show IP addresses clicked', {
showIP: checked,

View File

@@ -4,13 +4,14 @@ import type {
TableColumnsType as ColumnsType,
TableColumnType as ColumnType,
} from 'antd';
import { Button, Dropdown, Flex, MenuProps, Switch } from 'antd';
import { Button, Flex } from 'antd';
import { DropdownMenuSimple, type MenuItem } from '@signozhq/ui/dropdown-menu';
import { Switch } from '@signozhq/ui/switch';
import logEvent from 'api/common/logEvent';
import LaunchChatSupport from 'components/LaunchChatSupport/LaunchChatSupport';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import useUrlQuery from 'hooks/useUrlQuery';
import { SlidersHorizontal } from '@signozhq/icons';
import { popupContainer } from 'utils/selectPopupContainer';
import ResizeTable from './ResizeTable';
import { DynamicColumnTableProps } from './types';
@@ -60,9 +61,7 @@ function DynamicColumnTable({
const onToggleHandler =
(index: number, column: ColumnGroupType<any> | ColumnType<any>) =>
(checked: boolean, event: React.MouseEvent<HTMLButtonElement>): void => {
event.stopPropagation();
(checked: boolean): void => {
if (shouldSendAlertsLogEvent) {
logEvent('Alert: Column toggled', {
column: column?.title,
@@ -85,19 +84,22 @@ function DynamicColumnTable({
);
};
const items: MenuProps['items'] =
const items: MenuItem[] =
dynamicColumns?.map((column, index) => ({
key: String(index),
label: (
<div className="dynamicColumnsTable-items">
<div
className="dynamicColumnsTable-items"
onClick={(e): void => e.stopPropagation()}
role="presentation"
>
<div>{column.title?.toString()}</div>
<Switch
checked={columnsData?.findIndex((c) => c.key === column.key) !== -1}
value={columnsData?.findIndex((c) => c.key === column.key) !== -1}
onChange={onToggleHandler(index, column)}
/>
</div>
),
key: index,
type: 'checkbox',
})) || [];
// Get current page from URL or default to 1
@@ -126,18 +128,14 @@ function DynamicColumnTable({
<Flex justify="flex-end" align="center" gap={8}>
{facingIssueBtn && <LaunchChatSupport {...facingIssueBtn} />}
{dynamicColumns && (
<Dropdown
getPopupContainer={popupContainer}
menu={{ items }}
trigger={['click']}
>
<DropdownMenuSimple menu={{ items }}>
<Button
className="dynamicColumnTable-button filter-btn"
size="middle"
icon={<SlidersHorizontal size={14} />}
data-testid="additional-filters-button"
/>
</Dropdown>
</DropdownMenuSimple>
)}
</Flex>

View File

@@ -1,6 +1,7 @@
import { Dispatch, SetStateAction, useCallback, useMemo } from 'react';
import { ChevronDown, Globe } from '@signozhq/icons';
import { Button, Dropdown } from 'antd';
import { DropdownMenuSimple } from '@signozhq/ui/dropdown-menu';
import { Button } from 'antd';
import { Typography } from '@signozhq/ui/typography';
import TimeItems, {
timePreferance,
@@ -27,20 +28,17 @@ function TimePreference({
const menu = useMemo(
() => ({
items: menuItems,
onClick: timeMenuItemOnChangeHandler,
items: menuItems.map((item) => ({
...item,
onClick: timeMenuItemOnChangeHandler,
})),
}),
[timeMenuItemOnChangeHandler],
);
return (
<Dropdown
menu={menu}
rootClassName="time-selection-menu"
className="time-selection-target"
trigger={['click']}
>
<Button>
<DropdownMenuSimple menu={menu} className="time-selection-menu">
<Button className="time-selection-target">
<div className="button-selected-text">
<Globe size={14} />
<Typography.Text className="selected-value">
@@ -49,7 +47,7 @@ function TimePreference({
</div>
<ChevronDown size="md" />
</Button>
</Dropdown>
</DropdownMenuSimple>
);
}

View File

@@ -1,7 +1,8 @@
import { useMemo, useState } from 'react';
import { QueryFunctionContext, useQueries, useQuery } from 'react-query';
import { Spin, Switch, Table, Tooltip } from 'antd';
import { Spin, Table, Tooltip } from 'antd';
import { Info, Loader } from '@signozhq/icons';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import { getQueryRangeV5 } from 'api/v5/queryRange/getQueryRange';
import { MetricRangePayloadV5, ScalarData } from 'api/v5/v5';
@@ -170,11 +171,7 @@ function TopErrors({
/>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<Switch
checked={showStatusCodeErrors}
onChange={setShowStatusCodeErrors}
size="small"
/>
<Switch value={showStatusCodeErrors} onChange={setShowStatusCodeErrors} />
<span style={{ color: 'white', fontSize: '14px' }}>
Status Message Exists
</span>

View File

@@ -1,4 +1,5 @@
import { Button, Flex, SelectProps, Switch } from 'antd';
import { Button, Flex, SelectProps } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import type { BaseOptionType, DefaultOptionType } from 'antd/es/select';
import { getInvolvedQueriesInTraceOperator } from 'components/QueryBuilderV2/QueryV2/TraceOperator/utils/utils';
@@ -419,8 +420,8 @@ export function RoutingPolicyBanner({
</Typography.Text>
<div className="routing-policies-info-banner-right">
<Switch
checked={notificationSettings.routingPolicies}
data-testid="routing-policies-switch"
value={notificationSettings.routingPolicies}
testId="routing-policies-switch"
onChange={(value): void => {
setNotificationSettings({
type: 'SET_ROUTING_POLICIES',

View File

@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react';
import { Switch, Tooltip } from 'antd';
import { Tooltip } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import { Info } from '@signozhq/icons';
@@ -49,7 +50,7 @@ function AdvancedOptionItem({
>
{input}
</div>
<Switch onChange={handleOnToggle} checked={showInput} />
<Switch onChange={handleOnToggle} value={showInput} />
</div>
</div>
);

View File

@@ -11,8 +11,13 @@ import {
} from '@signozhq/icons';
import { Button } from '@signozhq/ui/button';
import { Callout } from '@signozhq/ui/callout';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuTrigger,
} from '@signozhq/ui/dropdown-menu';
import { toast } from '@signozhq/ui/sonner';
import { Dropdown, Skeleton } from 'antd';
import { Skeleton } from 'antd';
import {
RenderErrorResponseDTO,
ZeustypesHostDTO,
@@ -200,10 +205,15 @@ export default function CustomDomainSettings(): JSX.Element {
!workspaceName ? 'workspace-name-hidden' : ''
}`}
>
<Dropdown
trigger={['click']}
disabled={isFetchingHosts}
dropdownRender={(): JSX.Element => (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="link" color="none" disabled={isFetchingHosts}>
<Link2 size={12} />
<span>{stripProtocol(activeHost?.url ?? '')}</span>
<ChevronDown size={12} />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<div className="workspace-url-dropdown">
<span className="workspace-url-dropdown-header">
All Workspace URLs
@@ -236,14 +246,8 @@ export default function CustomDomainSettings(): JSX.Element {
);
})}
</div>
)}
>
<Button variant="link" color="none">
<Link2 size={12} />
<span>{stripProtocol(activeHost?.url ?? '')}</span>
<ChevronDown size={12} />
</Button>
</Dropdown>
</DropdownMenuContent>
</DropdownMenu>
<span className="custom-domain-card-meta-timezone">
<Clock size={11} />
{timezone.offset}

View File

@@ -1,4 +1,5 @@
import { GetHosts200 } from 'api/generated/services/sigNoz.schemas';
import userEvent from '@testing-library/user-event';
import { rest, server } from 'mocks-server/server';
import { fireEvent, render, screen, waitFor } from 'tests/test-utils';
@@ -142,12 +143,13 @@ describe('CustomDomainSettings', () => {
});
it('shows all workspace URLs as links in the dropdown', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
render(<CustomDomainSettings />);
await screen.findByText(/custom-host\.test\.cloud/i);
// Open the URL dropdown
fireEvent.click(
await user.click(
screen.getByRole('button', { name: /custom-host\.test\.cloud/i }),
);

View File

@@ -5,7 +5,8 @@ import { useQuery } from 'react-query';
import { useSelector } from 'react-redux';
import { orange } from '@ant-design/colors';
import { Color } from '@signozhq/design-tokens';
import { Button, Collapse, Input, Select, Switch, Tag } from 'antd';
import { Button, Collapse, Input, Select, Tag } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import dashboardVariablesQuery from 'api/dashboard/variables/dashboardVariablesQuery';
import cx from 'classnames';
@@ -763,7 +764,7 @@ function VariableItem({
</Typography>
</LabelContainer>
<Switch
checked={variableMultiSelect}
value={variableMultiSelect}
onChange={(e): void => {
setVariableMultiSelect(e);
if (!e) {
@@ -780,7 +781,7 @@ function VariableItem({
</Typography>
</LabelContainer>
<Switch
checked={variableShowALLOption}
value={variableShowALLOption}
onChange={(e): void => setVariableShowALLOption(e)}
/>
</VariableItemRow>

View File

@@ -1,6 +1,7 @@
import { useState } from 'react';
import { CloudDownload } from '@signozhq/icons';
import { Button, Dropdown, MenuProps, Flex } from 'antd';
import { DropdownMenuSimple, type MenuProps } from '@signozhq/ui/dropdown-menu';
import { Button, Flex } from 'antd';
import { unparse } from 'papaparse';
import { DownloadProps } from './Download.types';
@@ -67,7 +68,7 @@ function Download({ data, isLoading, fileName }: DownloadProps): JSX.Element {
};
return (
<Dropdown menu={menu} trigger={['click']}>
<DropdownMenuSimple menu={menu}>
<Button
className="download-button"
loading={isLoading || isDownloading}
@@ -79,7 +80,7 @@ function Download({ data, isLoading, fileName }: DownloadProps): JSX.Element {
Download
</Flex>
</Button>
</Dropdown>
</DropdownMenuSimple>
);
}

View File

@@ -1,6 +1,7 @@
import { Dispatch, ReactElement, SetStateAction } from 'react';
import { useTranslation } from 'react-i18next';
import { Form, FormInstance, Input, Select, Switch } from 'antd';
import { Form, FormInstance, Input, Select } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import type { Store } from 'antd/lib/form/interface';
import ROUTES from 'constants/routes';
@@ -82,8 +83,8 @@ function FormAlertChannels({
name="send_resolved"
>
<Switch
defaultChecked={initialValue?.send_resolved}
data-testid="field-send-resolved-checkbox"
defaultValue={initialValue?.send_resolved}
testId="field-send-resolved-checkbox"
onChange={(value): void => {
setSelectedConfig((state) => ({
...state,

View File

@@ -2,7 +2,8 @@ import { useCallback, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery } from 'react-query';
import { Plus } from '@signozhq/icons';
import { Button, Flex, Form, Select, Switch, Tooltip } from 'antd';
import { Button, Flex, Form, Select, Tooltip } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import getAll from 'api/channels/getAll';
import logEvent from 'api/common/logEvent';
import { ALERTS_DATA_SOURCE_MAP } from 'constants/alerts';
@@ -198,10 +199,10 @@ function BasicInfo({
placement="right"
>
<Switch
checked={shouldBroadCastToAllChannels}
value={shouldBroadCastToAllChannels}
onChange={handleBroadcastToAllChannels}
disabled={noChannels || !!isLoading}
data-testid="alert-broadcast-to-all-channels"
testId="alert-broadcast-to-all-channels"
/>
</Tooltip>
</FormItemMedium>

View File

@@ -1,8 +1,4 @@
import {
Col,
Dropdown as DropDownComponent,
Input as InputComponent,
} from 'antd';
import { Col, Input as InputComponent } from 'antd';
import { Typography as TypographyComponent } from '@signozhq/ui/typography';
import styled from 'styled-components';
@@ -34,16 +30,6 @@ export const ButtonContainer = styled.div`
}
`;
export const Dropdown = styled(DropDownComponent)`
&&& {
display: flex;
justify-content: center;
align-items: center;
max-width: 150px;
min-width: 150px;
}
`;
export const TextContainer = styled.div`
&&& {
min-width: 100px;

View File

@@ -1,6 +1,7 @@
// eslint-disable-next-line no-restricted-imports
import { Provider } from 'react-redux';
import { fireEvent, render, screen } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { PANEL_TYPES } from 'constants/queryBuilder';
import ROUTES from 'constants/routes';
import { AppProvider } from 'providers/App/App';
@@ -176,6 +177,7 @@ jest.mock('providers/Dashboard/store/useDashboardStore', () => ({
describe('WidgetGraphComponent', () => {
it('should show correct menu items when hovering over more options while loading', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
const { getByTestId, findByRole, getByText, container } = render(
<MockQueryClientProvider>
<ErrorModalProvider>
@@ -208,7 +210,7 @@ describe('WidgetGraphComponent', () => {
expect(skeleton).toBeInTheDocument();
const moreOptionsButton = getByTestId('widget-header-options');
fireEvent.mouseEnter(moreOptionsButton);
await user.click(moreOptionsButton);
const menu = await findByRole('menu');
expect(menu).toBeInTheDocument();

View File

@@ -54,6 +54,17 @@
visibility: visible;
}
// currently the width of the dropdown menu is set to 100% of the parent container,
// which is not desired. This is a workaround to unset that width and allow the dropdown menu to size based on its content.
// This is necessary because the dropdown menu can contain items with varying widths, and setting it to 100% can cause layout issues and make the menu look unbalanced.
// we should idealy fix this in the dropdown menu component itself, but for now this is a quick fix to ensure the dropdown menu looks correct in the widget header.
[data-radix-popper-content-wrapper]
[data-slot='dropdown-menu-content'].widget-header-dropdown
[data-slot='dropdown-menu-item'] {
width: unset !important;
}
.widget-api-actions {
padding-right: 0.25rem;
}

View File

@@ -467,6 +467,7 @@ describe('WidgetHeader', () => {
describe('Create Alerts Menu Item', () => {
it('renders Create Alerts menu item with external link icon when included in headerMenuList', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
render(
<WidgetHeader
title={TEST_WIDGET_TITLE}
@@ -483,7 +484,7 @@ describe('WidgetHeader', () => {
const moreOptionsIcon = await screen.findByTestId(WIDGET_HEADER_OPTIONS_ID);
expect(moreOptionsIcon).toBeInTheDocument();
await userEvent.hover(moreOptionsIcon);
await user.click(moreOptionsIcon);
await screen.findByText(CREATE_ALERTS_TEXT);
@@ -494,6 +495,7 @@ describe('WidgetHeader', () => {
});
it('Create Alerts menu item is enabled and clickable', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
const mockCreateAlertsHandler = jest.fn();
const useCreateAlerts = jest.requireMock(
'hooks/queryBuilder/useCreateAlerts',
@@ -517,12 +519,12 @@ describe('WidgetHeader', () => {
expect(useCreateAlerts).toHaveBeenCalledWith(mockWidget, 'dashboardView');
const moreOptionsIcon = await screen.findByTestId(WIDGET_HEADER_OPTIONS_ID);
await userEvent.hover(moreOptionsIcon);
await user.click(moreOptionsIcon);
const createAlertsMenuItem = await screen.findByText(CREATE_ALERTS_TEXT);
// Verify the menu item is clickable by actually clicking it
await userEvent.click(createAlertsMenuItem);
await user.click(createAlertsMenuItem);
expect(mockCreateAlertsHandler).toHaveBeenCalledTimes(1);
});
});

View File

@@ -15,7 +15,8 @@ import {
X,
} from '@signozhq/icons';
import { Color } from '@signozhq/design-tokens';
import { Button, Dropdown, Input, MenuProps, Tooltip } from 'antd';
import { Button, Input, Tooltip } from 'antd';
import { DropdownMenuSimple } from '@signozhq/ui/dropdown-menu';
import { Typography } from '@signozhq/ui/typography';
import ErrorContent from 'components/ErrorModal/components/ErrorContent';
import ErrorPopover from 'components/ErrorPopover/ErrorPopover';
@@ -128,7 +129,7 @@ function WidgetHeader({
],
);
const onMenuItemSelectHandler: MenuProps['onClick'] = useCallback(
const onMenuItemSelectHandler = useCallback(
({ key }: { key: string }): void => {
if (isTWidgetOptions(key)) {
const functionToCall = keyMethodMapping[key];
@@ -188,18 +189,8 @@ function WidgetHeader({
{
key: MenuItemKeys.CreateAlerts,
icon: <Bell size="md" />,
label: (
<span
style={{
display: 'flex',
alignItems: 'baseline',
justifyContent: 'space-between',
}}
>
{MENUITEM_KEYS_VS_LABELS[MenuItemKeys.CreateAlerts]}
<SquareArrowOutUpRight size={10} />
</span>
),
label: MENUITEM_KEYS_VS_LABELS[MenuItemKeys.CreateAlerts],
rightIcon: <SquareArrowOutUpRight size="lg" />,
isVisible: headerMenuList?.includes(MenuItemKeys.CreateAlerts) || false,
disabled: false,
},
@@ -221,8 +212,10 @@ function WidgetHeader({
const menu = useMemo(
() => ({
items: updatedMenuList,
onClick: onMenuItemSelectHandler,
items: updatedMenuList.map((item) => ({
...item,
onClick: onMenuItemSelectHandler,
})),
}),
[updatedMenuList, onMenuItemSelectHandler],
);
@@ -321,7 +314,12 @@ function WidgetHeader({
/>
)}
{menu && Array.isArray(menu.items) && menu.items.length > 0 && (
<Dropdown menu={menu} trigger={['hover']} placement="bottomRight">
<DropdownMenuSimple
menu={menu}
side="bottom"
align="end"
className="widget-header-dropdown"
>
<Button
data-testid="widget-header-options"
className={`widget-header-more-options ${
@@ -329,7 +327,7 @@ function WidgetHeader({
}`}
icon={<EllipsisVertical size="md" />}
/>
</Dropdown>
</DropdownMenuSimple>
)}
</div>
</>

View File

@@ -6,6 +6,7 @@ export interface MenuItem {
key: MenuItemKeys;
icon: ReactNode;
label: ReactNode;
rightIcon?: ReactNode;
isVisible: boolean;
disabled: boolean;
danger?: boolean;

View File

@@ -1,9 +1,9 @@
import type { MenuItemType } from 'antd/es/menu/hooks/useItems';
import type { MenuItem as DropdownMenuItem } from '@signozhq/ui/dropdown-menu';
import { MenuItemKeys } from './contants';
import { MenuItem } from './types';
export const generateMenuList = (actions: MenuItem[]): MenuItemType[] =>
export const generateMenuList = (actions: MenuItem[]): DropdownMenuItem[] =>
actions
.filter((action: MenuItem) => action.isVisible)
.map(({ key, icon: Icon, label, disabled, ...rest }) => ({

View File

@@ -15,13 +15,13 @@ import {
Modal,
Row,
Select,
Switch,
Table,
TablePaginationConfig,
TableProps as AntDTableProps,
Tag,
Tooltip,
} from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import type { NotificationInstance } from 'antd/es/notification/interface';
import type { CollapseProps } from 'antd/lib';
@@ -1180,8 +1180,7 @@ function MultiIngestionSettings(): JSX.Element {
<div className="limit-enable-disable-toggle">
<Form.Item name="enableDailyLimit">
<Switch
size="small"
checked={activeSignal?.config?.day?.enabled}
value={activeSignal?.config?.day?.enabled}
onChange={(value): void => {
setActiveSignal((prev) =>
prev
@@ -1270,8 +1269,7 @@ function MultiIngestionSettings(): JSX.Element {
<div className="limit-enable-disable-toggle">
<Form.Item name="enableSecondLimit">
<Switch
size="small"
checked={activeSignal?.config?.second?.enabled}
value={activeSignal?.config?.second?.enabled}
onChange={(value): void => {
setActiveSignal((prev) =>
prev

View File

@@ -3,7 +3,8 @@ import { useTranslation } from 'react-i18next';
import { UseQueryResult } from 'react-query';
import { Button, Flex, Input } from 'antd';
import { Typography } from '@signozhq/ui/typography';
import { Plus } from '@signozhq/icons';
import { Ellipsis, Plus } from '@signozhq/icons';
import { DropdownMenuSimple } from '@signozhq/ui/dropdown-menu';
import type { ColumnsType } from 'antd/es/table/interface';
import logEvent from 'api/common/logEvent';
import { convertToApiError } from 'api/ErrorResponseHandlerForGeneratedAPIs';
@@ -15,7 +16,6 @@ import type {
} from 'api/generated/services/sigNoz.schemas';
import type { ErrorType } from 'api/generatedAPIInstance';
import { AxiosError } from 'axios';
import DropDown from 'components/DropDown/DropDown';
import {
DynamicColumnsKey,
TableDataSource,
@@ -323,55 +323,67 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
dataIndex: 'id',
key: 'action',
width: 10,
render: (id: RuletypesRuleDTO['id'], record): JSX.Element => (
<div data-testid="alert-actions">
<DropDown
onDropDownItemClick={(item): void =>
alertActionLogEvent(item.key, record)
render: (id: RuletypesRuleDTO['id'], record): JSX.Element => {
const actionItems = [
<ToggleAlertState
key="1"
disabled={record.disabled ?? false}
setData={setData}
id={id ?? ''}
/>,
<ColumnButton
key="2"
onClick={(e: React.MouseEvent): void =>
onEditHandler(record, { newTab: isModifierKeyPressed(e) })
}
element={[
<ToggleAlertState
key="1"
disabled={record.disabled ?? false}
setData={setData}
id={id ?? ''}
/>,
<ColumnButton
key="2"
onClick={(e: React.MouseEvent): void =>
onEditHandler(record, { newTab: isModifierKeyPressed(e) })
}
type="link"
loading={editLoader}
>
Edit
</ColumnButton>,
<ColumnButton
key="3-new-tab"
onClick={(): void => onEditHandler(record, { newTab: true })}
type="link"
loading={editLoader}
>
Edit in New Tab
</ColumnButton>,
<ColumnButton
key="3-clone"
onClick={onCloneHandler(record)}
type="link"
loading={cloneLoader}
>
Clone
</ColumnButton>,
<DeleteAlert
key="4"
notifications={notificationsApi}
setData={setData}
id={id ?? ''}
/>,
];
return (
<div data-testid="alert-actions">
<DropdownMenuSimple
menu={{
items: actionItems.map((element, index) => ({
key: String(index),
label: element,
onClick: ({ key }): void => alertActionLogEvent(key, record),
})),
}}
>
<Button
type="link"
loading={editLoader}
>
Edit
</ColumnButton>,
<ColumnButton
key="3"
onClick={(): void => onEditHandler(record, { newTab: true })}
type="link"
loading={editLoader}
>
Edit in New Tab
</ColumnButton>,
<ColumnButton
key="3"
onClick={onCloneHandler(record)}
type="link"
loading={cloneLoader}
>
Clone
</ColumnButton>,
<DeleteAlert
key="4"
notifications={notificationsApi}
setData={setData}
id={id ?? ''}
/>,
]}
/>
</div>
),
style={{ color: 'var(--l1-foreground)' }}
icon={<Ellipsis size={16} />}
/>
</DropdownMenuSimple>
</div>
);
},
});
}

View File

@@ -12,20 +12,19 @@ import { useTranslation } from 'react-i18next';
import { generatePath } from 'react-router-dom';
import { useCopyToClipboard } from 'react-use';
import { Color } from '@signozhq/design-tokens';
import { DropdownMenuSimple, type MenuItem } from '@signozhq/ui/dropdown-menu';
import {
Button,
Dropdown,
Flex,
Input,
MenuProps,
Modal,
Popover,
Skeleton,
Switch,
Table,
Tag,
Tooltip,
} from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import type { TableProps } from 'antd/lib';
import getLocalStorageKey from 'api/browser/localstorage/get';
@@ -553,7 +552,7 @@ function DashboardsList(): JSX.Element {
];
const getCreateDashboardItems = useMemo(() => {
const menuItems: MenuProps['items'] = [
const menuItems: MenuItem[] = [
{
label: (
<div
@@ -711,11 +710,11 @@ function DashboardsList(): JSX.Element {
{createNewDashboard && (
<section className="actions">
<Dropdown
overlayClassName="new-dashboard-menu"
<DropdownMenuSimple
className="new-dashboard-menu"
menu={{ items: getCreateDashboardItems }}
placement="bottomRight"
trigger={['click']}
side="bottom"
align="end"
>
<Button
type="text"
@@ -727,7 +726,7 @@ function DashboardsList(): JSX.Element {
>
New Dashboard
</Button>
</Dropdown>
</DropdownMenuSimple>
<Button
type="text"
className="learn-more"
@@ -756,11 +755,11 @@ function DashboardsList(): JSX.Element {
onChange={handleSearch}
/>
{createNewDashboard && (
<Dropdown
overlayClassName="new-dashboard-menu"
<DropdownMenuSimple
className="new-dashboard-menu"
menu={{ items: getCreateDashboardItems }}
placement="bottomRight"
trigger={['click']}
side="bottom"
align="end"
>
<Button
type="primary"
@@ -773,7 +772,7 @@ function DashboardsList(): JSX.Element {
>
New dashboard
</Button>
</Dropdown>
</DropdownMenuSimple>
)}
</div>
@@ -965,8 +964,7 @@ function DashboardsList(): JSX.Element {
<div className="connection-line" />
<div className="right">
<Switch
size="small"
checked
value
disabled
onChange={(check): void =>
setVisibleColumns((prev) => ({
@@ -985,9 +983,8 @@ function DashboardsList(): JSX.Element {
<div className="connection-line" />
<div className="right">
<Switch
size="small"
disabled
checked
value
onChange={(check): void =>
setVisibleColumns((prev) => ({
...prev,
@@ -1005,8 +1002,7 @@ function DashboardsList(): JSX.Element {
<div className="connection-line" />
<div className="right">
<Switch
size="small"
checked={visibleColumns.updatedAt}
value={visibleColumns.updatedAt}
onChange={(check): void =>
setVisibleColumns((prev) => ({
...prev,
@@ -1024,8 +1020,7 @@ function DashboardsList(): JSX.Element {
<div className="connection-line" />
<div className="right">
<Switch
size="small"
checked={visibleColumns.updatedBy}
value={visibleColumns.updatedBy}
onChange={(check): void =>
setVisibleColumns((prev) => ({
...prev,

View File

@@ -1,6 +1,6 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useLocation } from 'react-router-dom';
import { Switch } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import LogsFormatOptionsMenu from 'components/LogsFormatOptionsMenu/LogsFormatOptionsMenu';
import { MAX_LOGS_LIST_SIZE } from 'constants/liveTail';
@@ -228,9 +228,8 @@ function LiveLogsContainer({
<div className="live-logs-frequency-chart-view-controller">
<Typography>Frequency chart</Typography>
<Switch
size="small"
checked={showLiveLogsFrequencyChart}
defaultChecked
value={showLiveLogsFrequencyChart}
defaultValue
onChange={handleToggleFrequencyChart}
/>
</div>

View File

@@ -2,7 +2,13 @@ import { useCallback } from 'react';
import { useCopyToClipboard } from 'react-use';
import { orange } from '@ant-design/colors';
import { Settings } from '@signozhq/icons';
import { Dropdown, MenuProps } from 'antd';
import {
type BaseMenuItem,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@signozhq/ui/dropdown-menu';
import {
negateOperator,
OPERATORS,
@@ -135,41 +141,38 @@ function BodyTitleRenderer({
viewName,
]);
const onClickHandler: MenuProps['onClick'] = (props): void => {
const onClickHandler = (key: string): void => {
const mapper = {
[DROPDOWN_KEY.FILTER_IN]: filterHandler(true),
[DROPDOWN_KEY.FILTER_OUT]: filterHandler(false),
[DROPDOWN_KEY.GROUP_BY]: groupByHandler,
};
const handler = mapper[props.key];
const handler = mapper[key];
if (handler) {
handler();
}
};
const menu: MenuProps = {
items: [
{
key: DROPDOWN_KEY.FILTER_IN,
label: `Filter for ${value}`,
},
{
key: DROPDOWN_KEY.FILTER_OUT,
label: `Filter out ${value}`,
},
...(isGroupBySupported
? [
{
key: DROPDOWN_KEY.GROUP_BY,
label: `Group by ${nodeKey}`,
},
]
: []),
],
onClick: onClickHandler,
};
const menuItems: BaseMenuItem[] = [
{
key: DROPDOWN_KEY.FILTER_IN,
label: `Filter for ${value}`,
},
{
key: DROPDOWN_KEY.FILTER_OUT,
label: `Filter out ${value}`,
},
...(isGroupBySupported
? [
{
key: DROPDOWN_KEY.GROUP_BY,
label: `Group by ${nodeKey}`,
},
]
: []),
];
const handleNodeClick = useCallback(
(e: React.MouseEvent): void => {
@@ -218,15 +221,23 @@ function BodyTitleRenderer({
}}
onMouseDown={(e): void => e.preventDefault()}
>
<Dropdown
menu={menu}
trigger={['click']}
dropdownRender={(originNode): React.ReactNode => (
<div data-log-detail-ignore="true">{originNode}</div>
)}
>
<Settings style={{ marginRight: 8 }} className="hover-reveal" />
</Dropdown>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Settings style={{ marginRight: 8 }} className="hover-reveal" />
</DropdownMenuTrigger>
<DropdownMenuContent>
<div data-log-detail-ignore="true">
{menuItems.map((item) => (
<DropdownMenuItem
key={item.key}
onSelect={(): void => onClickHandler(item.key as string)}
>
{item.label}
</DropdownMenuItem>
))}
</div>
</DropdownMenuContent>
</DropdownMenu>
</span>
)}
{title.toString()}{' '}

View File

@@ -1,7 +1,7 @@
import { useMemo, useState } from 'react';
import MEditor, { EditorProps, Monaco } from '@monaco-editor/react';
import { Color } from '@signozhq/design-tokens';
import { Switch } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import { useIsDarkMode } from 'hooks/useDarkMode';
@@ -81,7 +81,7 @@ function JSONView({ logData }: JSONViewProps): JSX.Element {
<div className="log-switch">
<div className="wrap-word-switch">
<Typography.Text>Wrap text</Typography.Text>
<Switch checked={isWrapWord} onChange={handleWrapWord} size="small" />
<Switch value={isWrapWord} onChange={handleWrapWord} />
</div>
</div>
</div>

View File

@@ -2,7 +2,8 @@ import { ReactNode, useState } from 'react';
import MEditor, { EditorProps, Monaco } from '@monaco-editor/react';
import { Color } from '@signozhq/design-tokens';
import { Button } from '@signozhq/ui/button';
import { Collapse, Divider, Input, Switch, Tag } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Collapse, Divider, Input, Tag } from 'antd';
import { Typography } from '@signozhq/ui/typography';
import { AddToQueryHOCProps } from 'components/Logs/AddToQueryHOC';
import { ChangeViewFunctionType } from 'container/ExplorerOptions/types';
@@ -136,7 +137,7 @@ function Overview({
<div className="log-switch">
<div className="wrap-word-switch">
<Typography.Text>Wrap text</Typography.Text>
<Switch checked={isWrapWord} onChange={handleWrapWord} size="small" />
<Switch value={isWrapWord} onChange={handleWrapWord} />
</div>
</div>
</div>

View File

@@ -1,4 +1,4 @@
import { Switch } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import DownloadOptionsMenu from 'components/DownloadOptionsMenu/DownloadOptionsMenu';
import LogsFormatOptionsMenu from 'components/LogsFormatOptionsMenu/LogsFormatOptionsMenu';
@@ -69,9 +69,8 @@ function LogsActionsContainer({
<div className="frequency-chart-view-controller">
<Typography>Frequency chart</Typography>
<Switch
size="small"
checked={showFrequencyChart}
defaultChecked
value={showFrequencyChart}
defaultValue
onChange={handleToggleFrequencyChart}
/>
</div>

View File

@@ -2,9 +2,8 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
import { useHistory } from 'react-router-dom';
import { Check, ChevronDown, Plus } from '@signozhq/icons';
import { Button } from '@signozhq/ui/button';
import { DropdownMenuSimple, type MenuItem } from '@signozhq/ui/dropdown-menu';
import { Input } from '@signozhq/ui/input';
import type { MenuProps } from 'antd';
import { Dropdown } from 'antd';
import { useListUsers } from 'api/generated/services/users';
import EditMemberDrawer from 'components/EditMemberDrawer/EditMemberDrawer';
import InviteMembersModal from 'components/InviteMembersModal/InviteMembersModal';
@@ -95,7 +94,7 @@ function MembersSettings(): JSX.Element {
).length;
const totalCount = allMembers.length;
const filterMenuItems: MenuProps['items'] = [
const filterMenuItems: MenuItem[] = [
{
key: FilterMode.All,
label: (
@@ -171,10 +170,9 @@ function MembersSettings(): JSX.Element {
</div>
<div className="members-settings__controls">
<Dropdown
<DropdownMenuSimple
menu={{ items: filterMenuItems }}
trigger={['click']}
overlayClassName="members-filter-dropdown"
className="members-filter-dropdown"
>
<Button
variant="solid"
@@ -184,7 +182,7 @@ function MembersSettings(): JSX.Element {
<span>{filterLabel}</span>
<ChevronDown size={12} className="members-filter-trigger__chevron" />
</Button>
</Dropdown>
</DropdownMenuSimple>
<div className="members-settings__search">
<Input

View File

@@ -1,4 +1,5 @@
import type { TypesUserDTO } from 'api/generated/services/sigNoz.schemas';
import userEvent from '@testing-library/user-event';
import { rest, server } from 'mocks-server/server';
import { fireEvent, render, screen } from 'tests/test-utils';
@@ -76,14 +77,15 @@ describe('MembersSettings (integration)', () => {
});
it('filters to pending invites via the filter dropdown', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
render(<MembersSettings />);
await screen.findByText('Alice Smith');
fireEvent.click(screen.getByRole('button', { name: /all members/i }));
await user.click(screen.getByRole('button', { name: /all members/i }));
const pendingOption = await screen.findByText(/pending invites/i);
fireEvent.click(pendingOption);
await user.click(pendingOption);
await screen.findByText('charlie@signoz.io');
expect(screen.queryByText('Alice Smith')).not.toBeInTheDocument();

View File

@@ -5,11 +5,11 @@ import { useParams } from 'react-router-dom';
import { Search } from '@signozhq/icons';
import {
InputRef,
Switch,
TableColumnsType as ColumnsType,
TableColumnType as ColumnType,
Tooltip,
} from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import { ResizeTable } from 'components/ResizeTable';
import TextToolTip from 'components/TextToolTip';
@@ -212,11 +212,7 @@ function TopOperationsTable({
/>
</div>
<div className="top-operation__entry-point">
<Switch
checked={isEntryPoint}
onChange={onEntryPointToggle}
size="small"
/>
<Switch value={isEntryPoint} onChange={onEntryPointToggle} />
<span className="top-operation__entry-point-label">Entrypoint Spans</span>
<TextToolTip
text={entryPointSpanInfo.text}

View File

@@ -2,7 +2,8 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
import { useQueryClient } from 'react-query';
import { useSearchParams } from 'react-router-dom-v5-compat';
import * as Sentry from '@sentry/react';
import { Switch, Tooltip } from 'antd';
import { Tooltip } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import logEvent from 'api/common/logEvent';
import { QueryBuilderV2 } from 'components/QueryBuilderV2/QueryBuilderV2';
import WarningPopover from 'components/WarningPopover/WarningPopover';
@@ -358,10 +359,9 @@ function Explorer(): JSX.Element {
title={oneChartPerQueryDisabledTooltip}
>
<Switch
checked={showOneChartPerQuery}
value={showOneChartPerQuery}
onChange={handleToggleShowOneChartPerQuery}
disabled={disableOneChartPerQuery || splitedQueries.length <= 1}
size="small"
/>
</Tooltip>
</div>

View File

@@ -2,7 +2,8 @@ import { useEffect, useMemo, useRef, useState } from 'react';
// eslint-disable-next-line no-restricted-imports
import { useSelector } from 'react-redux';
import { Color } from '@signozhq/design-tokens';
import { Button, Skeleton, Switch } from 'antd';
import { Button, Skeleton } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import logEvent from 'api/common/logEvent';
import Uplot from 'components/Uplot';
@@ -206,7 +207,7 @@ function GraphView({
</Button.Group>
<div className="view-toggle-button">
<Switch
checked={viewType === 'graph'}
value={viewType === 'graph'}
onChange={(checked): void => {
const newViewType = checked ? 'graph' : 'table';
setViewType(newViewType);

View File

@@ -1,7 +1,8 @@
import { useMemo } from 'react';
import { generatePath } from 'react-router-dom';
import { Color } from '@signozhq/design-tokens';
import { Dropdown, Skeleton } from 'antd';
import { DropdownMenuSimple } from '@signozhq/ui/dropdown-menu';
import { Skeleton } from 'antd';
import { Typography } from '@signozhq/ui/typography';
import {
useGetMetricAlerts,
@@ -126,12 +127,11 @@ function DashboardsAndAlertsPopover({
return (
<div className="dashboards-and-alerts-popover-container">
{dashboardsPopoverContent && (
<Dropdown
<DropdownMenuSimple
menu={{
items: dashboardsPopoverContent,
}}
placement="bottomLeft"
trigger={['click']}
align="start"
>
<div
className="dashboards-and-alerts-popover dashboards-popover"
@@ -142,15 +142,14 @@ function DashboardsAndAlertsPopover({
{pluralize(dashboards.length, 'dashboard')}
</Typography.Text>
</div>
</Dropdown>
</DropdownMenuSimple>
)}
{alertsPopoverContent && (
<Dropdown
<DropdownMenuSimple
menu={{
items: alertsPopoverContent,
}}
placement="bottomLeft"
trigger={['click']}
align="start"
>
<div
className="dashboards-and-alerts-popover alerts-popover"
@@ -161,7 +160,7 @@ function DashboardsAndAlertsPopover({
{pluralize(alerts.length, 'alert rule')}
</Typography.Text>
</div>
</Dropdown>
</DropdownMenuSimple>
)}
</div>
);

View File

@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { Color } from '@signozhq/design-tokens';
import { Switch } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import logEvent from 'api/common/logEvent';
import { Delete } from '@signozhq/icons';
import { useTimezone } from 'providers/Timezone';
@@ -49,10 +49,10 @@ function TimezoneAdaptation(): JSX.Element {
<div className="timezone-adaption__header">
<h2 className="timezone-adaption__title">Adapt to my timezone</h2>
<Switch
checked={isAdaptationEnabled}
value={isAdaptationEnabled}
onChange={handleSwitchChange}
style={getSwitchStyles()}
data-testid="timezone-adaptation-switch"
testId="timezone-adaptation-switch"
/>
</div>

View File

@@ -1,6 +1,7 @@
import { useEffect, useState } from 'react';
import { useMutation } from 'react-query';
import { Radio, RadioChangeEvent, Switch, Tag } from 'antd';
import { Radio, RadioChangeEvent, Tag } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import setLocalStorageApi from 'api/browser/localstorage/set';
import logEvent from 'api/common/logEvent';
import updateUserPreference from 'api/v1/user/preferences/name/update';
@@ -218,10 +219,10 @@ function MySettings(): JSX.Element {
<div className="user-preference-section-content-item-title-action">
Keep the primary sidebar always open{' '}
<Switch
checked={sideNavPinned}
value={sideNavPinned}
onChange={handleSideNavPinnedChange}
loading={isUpdatingUserPreference}
data-testid="side-nav-pinned-switch"
disabled={isUpdatingUserPreference}
testId="side-nav-pinned-switch"
/>
</div>

View File

@@ -7,7 +7,12 @@ import {
DropResult,
} from 'react-beautiful-dnd';
import { Color } from '@signozhq/design-tokens';
import { Button, Divider, Dropdown, Input, MenuProps, Tooltip } from 'antd';
import { Button, Divider, Input, Tooltip } from 'antd';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuTrigger,
} from '@signozhq/ui/dropdown-menu';
import { Typography } from '@signozhq/ui/typography';
import { FieldDataType } from 'api/v5/v5';
import { SOMETHING_WENT_WRONG } from 'constants/api';
@@ -159,34 +164,12 @@ function ExplorerColumnsRenderer({
debouncedSetQuerySearchText(e.target.value);
};
const items: MenuProps['items'] = [
{
key: 'search',
label: (
<Input
type="text"
placeholder="Search"
className="explorer-columns-search"
value={searchText}
onChange={handleSearchChange}
prefix={<Search size={16} style={{ padding: '6px' }} />}
/>
),
},
{
key: 'columns',
label: (
<ExplorerAttributeColumns
isLoading={isLoading}
data={data}
searchText={searchText}
isAttributeKeySelected={isAttributeKeySelected}
handleCheckboxChange={handleCheckboxChange}
dataSource={initialDataSource}
/>
),
},
];
const handleOpenChange = (nextOpen: boolean): void => {
setOpen(nextOpen);
if (nextOpen) {
setSearchText('');
}
};
const removeSelectedLogField = (name: string): void => {
if (
@@ -238,13 +221,6 @@ function ExplorerColumnsRenderer({
}
};
const toggleDropdown = (): void => {
setOpen(!open);
if (!open) {
setSearchText('');
}
};
const isDarkMode = useIsDarkMode();
return (
@@ -327,25 +303,38 @@ function ExplorerColumnsRenderer({
</Droppable>
</DragDropContext>
<div>
<Dropdown
menu={{ items }}
arrow
placement="top"
open={open}
overlayClassName="explorer-columns-dropdown"
>
<Button
className="action-btn"
data-testid="add-columns-button"
icon={
<CirclePlus
size={16}
color={isDarkMode ? Color.BG_INK_400 : Color.BG_VANILLA_100}
/>
}
onClick={toggleDropdown}
/>
</Dropdown>
<DropdownMenu open={open} onOpenChange={handleOpenChange}>
<DropdownMenuTrigger asChild>
<Button
className="action-btn"
data-testid="add-columns-button"
icon={
<CirclePlus
size={16}
color={isDarkMode ? Color.BG_INK_400 : Color.BG_VANILLA_100}
/>
}
/>
</DropdownMenuTrigger>
<DropdownMenuContent side="top" className="explorer-columns-dropdown">
<Input
type="text"
placeholder="Search"
className="explorer-columns-search"
value={searchText}
onChange={handleSearchChange}
prefix={<Search size={16} style={{ padding: '6px' }} />}
/>
<ExplorerAttributeColumns
isLoading={isLoading}
data={data}
searchText={searchText}
isAttributeKeySelected={isAttributeKeySelected}
handleCheckboxChange={handleCheckboxChange}
dataSource={initialDataSource}
/>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
)}

View File

@@ -146,6 +146,7 @@ describe('ExplorerColumnsRenderer', () => {
});
it('opens and closes the dropdown', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
render(
<Wrapper>
<ExplorerColumnsRenderer
@@ -158,12 +159,12 @@ describe('ExplorerColumnsRenderer', () => {
);
const addButton = screen.getByTestId('add-columns-button');
await userEvent.click(addButton);
await user.click(addButton);
expect(screen.getByPlaceholderText('Search')).toBeInTheDocument();
expect(screen.getByText('attribute1')).toBeInTheDocument();
await userEvent.click(addButton);
await user.click(addButton);
await waitFor(() => {
expect(screen.queryByRole('menu')).not.toBeInTheDocument();
});

View File

@@ -13,7 +13,7 @@ import { Plus, Trash2 } from '@signozhq/icons';
import { ContextLinkProps, Widgets } from 'types/api/dashboard/getAll';
import { getBaseUrl } from 'utils/basePath';
import VariablesDropdown from './VariablesDropdown';
import VariablesPopover from './VariablesPopover';
import './UpdateContextLinks.styles.scss';
@@ -71,7 +71,7 @@ function UpdateContextLinks({
customVariables: fieldVariables,
});
// Transform variables into the format expected by VariablesDropdown
// Transform variables into the format expected by VariablesPopover
const transformedVariables = useMemo(
() => transformContextVariables(variables),
[variables],
@@ -224,7 +224,9 @@ function UpdateContextLinks({
},
]}
>
<VariablesDropdown
{/* TODO: replace with AutoComplete with options for variables and
previously used URLs for better UX */}
<VariablesPopover
onVariableSelect={handleVariableSelect}
variables={transformedVariables}
>
@@ -252,7 +254,7 @@ function UpdateContextLinks({
/>
</div>
)}
</VariablesDropdown>
</VariablesPopover>
</Form.Item>
{/* Remove the separate variables section */}
@@ -282,7 +284,7 @@ function UpdateContextLinks({
/>
</Col>
<Col span={16}>
<VariablesDropdown
<VariablesPopover
onVariableSelect={(variableName, cursorPosition): void =>
handleParamVariableSelect(index, variableName, cursorPosition)
}
@@ -311,7 +313,7 @@ function UpdateContextLinks({
}
/>
)}
</VariablesDropdown>
</VariablesPopover>
</Col>
<Col span={2}>
<Button

View File

@@ -1,26 +0,0 @@
.variables-dropdown-container {
.url-input-trigger {
width: 100%;
.url-input-field {
width: 100%;
}
}
// Override Ant Design dropdown styles
.ant-dropdown-menu {
max-height: 300px;
overflow-y: auto;
padding: 8px 0;
}
}
.variable-row {
display: flex;
justify-content: space-between;
.variable-source {
color: #666;
font-size: 12px;
}
}

View File

@@ -1,93 +0,0 @@
import { ReactNode, useEffect, useMemo, useRef, useState } from 'react';
import { Dropdown } from 'antd';
import { Typography } from '@signozhq/ui/typography';
import './VariablesDropdown.styles.scss';
interface VariablesDropdownProps {
onVariableSelect: (variableName: string, cursorPosition?: number) => void;
variables: VariableItem[];
children: (props: {
onVariableSelect: (variableName: string, cursorPosition?: number) => void;
isOpen: boolean;
setIsOpen: (open: boolean) => void;
cursorPosition: number | null;
setCursorPosition: (position: number | null) => void;
}) => ReactNode;
}
interface VariableItem {
name: string;
source: string;
}
function VariablesDropdown({
onVariableSelect,
variables,
children,
}: VariablesDropdownProps): JSX.Element {
const [isOpen, setIsOpen] = useState(false);
const [cursorPosition, setCursorPosition] = useState<number | null>(null);
const wrapperRef = useRef<HTMLDivElement>(null);
// Click outside handler
useEffect(() => {
function handleClickOutside(event: MouseEvent): void {
if (
wrapperRef.current &&
!wrapperRef.current.contains(event.target as Node)
) {
setIsOpen(false);
}
}
if (isOpen) {
document.addEventListener('mousedown', handleClickOutside);
}
return (): void => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [isOpen]);
const dropdownItems = useMemo(
() =>
variables.map((v) => ({
key: v.name,
label: (
<div className="variable-row">
<Typography.Text className="variable-name">{`{{${v.name}}}`}</Typography.Text>
<Typography.Text className="variable-source">{v.source}</Typography.Text>
</div>
),
})),
[variables],
);
return (
<div className="variables-dropdown-container" ref={wrapperRef}>
<Dropdown
menu={{
items: dropdownItems,
onClick: ({ key }): void => {
const variableName = key as string;
onVariableSelect(`{{${variableName}}}`, cursorPosition || undefined);
setIsOpen(false);
},
}}
open={isOpen}
placement="bottomLeft"
trigger={['click']}
getPopupContainer={(): HTMLElement => wrapperRef.current || document.body}
>
{children({
onVariableSelect,
isOpen,
setIsOpen,
cursorPosition,
setCursorPosition,
})}
</Dropdown>
</div>
);
}
export default VariablesDropdown;

View File

@@ -0,0 +1,74 @@
.variables-popover-container {
.url-input-trigger {
width: 100%;
.url-input-field {
width: 100%;
}
}
.variables-popover-anchor-wrap {
width: 100%;
}
}
.variables-popover-content {
// antd Modal uses z-index ~1000; popover must sit above it.
z-index: 1100;
padding: 4px 0;
max-height: 300px;
overflow-y: auto;
overflow-x: hidden;
min-width: var(--radix-popover-trigger-width);
}
.variables-popover-empty {
padding: 8px 12px;
color: var(--l3-foreground, #999);
font-size: 12px;
font-style: italic;
}
.variables-popover-item {
all: unset;
display: block;
box-sizing: border-box;
width: 100%;
padding: 8px 12px;
cursor: pointer;
color: var(--l1-foreground);
font-size: 13px;
line-height: 1.4;
overflow: hidden;
&:hover,
&:focus {
background-color: var(--l1-background-hover);
}
}
.variable-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
min-width: 0;
.variable-name,
.variable-source {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.variable-name {
flex: 1 1 auto;
}
.variable-source {
color: #666;
font-size: 12px;
flex: 0 1 auto;
}
}

View File

@@ -0,0 +1,111 @@
// Uses Popover (not DropdownMenu like the rest of the antd-dropdown migration):
// DropdownMenuTrigger preventDefaults pointerdown, breaking input focus and
// dismissing on every keystroke. PopoverAnchor is a passive positioning element.
import { ReactNode, useRef, useState } from 'react';
import { Popover, PopoverAnchor, PopoverContent } from '@signozhq/ui/popover';
import { Typography } from '@signozhq/ui/typography';
import './VariablesPopover.styles.scss';
interface VariablesPopoverProps {
onVariableSelect: (variableName: string, cursorPosition?: number) => void;
variables: VariableItem[];
children: (props: {
onVariableSelect: (variableName: string, cursorPosition?: number) => void;
isOpen: boolean;
setIsOpen: (open: boolean) => void;
cursorPosition: number | null;
setCursorPosition: (position: number | null) => void;
}) => ReactNode;
}
interface VariableItem {
name: string;
source: string;
}
function VariablesPopover({
onVariableSelect,
variables,
children,
}: VariablesPopoverProps): JSX.Element {
const [isOpen, setIsOpen] = useState(false);
const [cursorPosition, setCursorPosition] = useState<number | null>(null);
const anchorRef = useRef<HTMLDivElement>(null);
const handleOpenChange = (open: boolean): void => {
// Accept "close" events from the popover (outside-click, Esc) but ignore
// opens — opening is driven by the input's onFocus in the consumer.
if (!open) {
setIsOpen(false);
}
};
return (
<div className="variables-popover-container">
<Popover open={isOpen} onOpenChange={handleOpenChange} modal={false}>
<PopoverAnchor asChild>
<div className="variables-popover-anchor-wrap" ref={anchorRef}>
{children({
onVariableSelect,
isOpen,
setIsOpen,
cursorPosition,
setCursorPosition,
})}
</div>
</PopoverAnchor>
<PopoverContent
align="start"
sideOffset={4}
className="variables-popover-content"
onOpenAutoFocus={(e): void => e.preventDefault()}
onCloseAutoFocus={(e): void => e.preventDefault()}
onInteractOutside={(e): void => {
// Keep the popover open while interacting with the anchor (the input),
// otherwise typing/clicking the input would close it immediately.
const target = e.target as Node | null;
if (target && anchorRef.current?.contains(target)) {
e.preventDefault();
}
}}
onFocusOutside={(e): void => {
const target = e.target as Node | null;
if (target && anchorRef.current?.contains(target)) {
e.preventDefault();
}
}}
>
{variables.length === 0 ? (
<div className="variables-popover-empty">No variables available</div>
) : (
variables.map((v) => (
<button
key={v.name}
type="button"
className="variables-popover-item"
onMouseDown={(e): void => {
// Prevent the input from losing focus when clicking an item.
e.preventDefault();
}}
onClick={(): void => {
onVariableSelect(`{{${v.name}}}`, cursorPosition || undefined);
setIsOpen(false);
}}
>
<div className="variable-row">
<Typography.Text className="variable-name">{`{{${v.name}}}`}</Typography.Text>
<Typography.Text className="variable-source">
{v.source}
</Typography.Text>
</div>
</button>
))
)}
</PopoverContent>
</Popover>
</div>
);
}
export default VariablesPopover;

View File

@@ -204,7 +204,7 @@ const processContextLinks = (
};
/**
* Transforms context variables into the format expected by VariablesDropdown
* Transforms context variables into the format expected by VariablesPopover
* @param variables - Array of context variables from useContextVariables
* @returns Array of transformed variables with proper source descriptions
*/

View File

@@ -1,5 +1,5 @@
import { Dispatch, SetStateAction } from 'react';
import { Switch } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import {
FillMode,
@@ -73,7 +73,7 @@ export default function ChartAppearanceSection({
Display individual data points on the chart
</Typography.Text>
</div>
<Switch size="small" checked={showPoints} onChange={setShowPoints} />
<Switch value={showPoints} onChange={setShowPoints} />
</section>
)}
{allowSpanGaps && (

View File

@@ -1,5 +1,6 @@
import { Dispatch, SetStateAction } from 'react';
import { InputNumber, Switch } from 'antd';
import { InputNumber } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import SettingsSection from '../../components/SettingsSection/SettingsSection';
@@ -61,8 +62,7 @@ export default function HistogramBucketsSection({
</span>
</Typography.Text>
<Switch
checked={combineHistogram}
size="small"
value={combineHistogram}
onChange={(checked): void => setCombineHistogram(checked)}
/>
</section>

View File

@@ -1,5 +1,6 @@
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
import { Select, Switch } from 'antd';
import { Select } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import TimePreference from 'components/TimePreferenceDropDown';
import { PANEL_TYPES } from 'constants/queryBuilder';
@@ -104,8 +105,7 @@ export default function VisualizationSettingsSection({
<section className="stack-chart control-container">
<Typography.Text className="section-heading">Stack series</Typography.Text>
<Switch
checked={stackedBarChart}
size="small"
value={stackedBarChart}
onChange={(checked): void => setStackedBarChart(checked)}
/>
</section>
@@ -120,8 +120,7 @@ export default function VisualizationSettingsSection({
</Typography.Text>
</div>
<Switch
checked={isFillSpans}
size="small"
value={isFillSpans}
onChange={(checked): void => setIsFillSpans(checked)}
/>
</section>

View File

@@ -1,6 +1,7 @@
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
import { ChevronDown } from '@signozhq/icons';
import { Button, ColorPicker, Dropdown, MenuProps, Space } from 'antd';
import { DropdownMenuSimple, type MenuItem } from '@signozhq/ui/dropdown-menu';
import { Button, ColorPicker, Space } from 'antd';
import type { Color } from 'antd/es/color-picker';
import useDebounce from 'hooks/useDebounce';
@@ -26,7 +27,7 @@ function ColorSelector({
setColorFromPicker(hex);
};
const items: MenuProps['items'] = [
const items: MenuItem[] = [
{
key: 'Red',
label: <CustomColor color="Red" />,
@@ -62,7 +63,7 @@ function ColorSelector({
];
return (
<Dropdown menu={{ items }} trigger={['click']}>
<DropdownMenuSimple menu={{ items }}>
<Button
onClick={(e): void => e.preventDefault()}
className="color-selector-button"
@@ -72,7 +73,7 @@ function ColorSelector({
<ChevronDown size="md" />
</Space>
</Button>
</Dropdown>
</DropdownMenuSimple>
);
}

View File

@@ -341,10 +341,10 @@ describe('Stacking bar in new panel', () => {
const section = container.querySelector('.stack-chart');
expect(section).toBeInTheDocument();
// Verify switch is present and enabled (ant-switch-checked)
const switchBtn = section?.querySelector('.ant-switch');
// Verify switch is present and enabled
const switchBtn = section?.querySelector('[role="switch"]');
expect(switchBtn).toBeInTheDocument();
expect(switchBtn).toHaveClass('ant-switch-checked');
expect(switchBtn).toHaveAttribute('data-state', 'checked');
// Check that stack series is present and checked
checkStackSeriesState(container, true);

View File

@@ -58,6 +58,26 @@ describe('AuthDomain', () => {
});
});
it('reflects ssoEnabled state from nested config in each row toggle', async () => {
server.use(
rest.get(AUTH_DOMAINS_LIST_ENDPOINT, (_, res, ctx) =>
res(ctx.status(200), ctx.json(mockDomainsListResponse)),
),
);
render(<AuthDomain />);
// mockDomainsListResponse rows:
// [0] signoz.io → config.ssoEnabled: true
// [1] example.com → config.ssoEnabled: false
// [2] corp.io → config.ssoEnabled: true
const switches = await screen.findAllByRole('switch');
expect(switches).toHaveLength(3);
expect(switches[0]).toBeChecked();
expect(switches[1]).not.toBeChecked();
expect(switches[2]).toBeChecked();
});
it('renders empty state when no domains exist', async () => {
server.use(
rest.get(AUTH_DOMAINS_LIST_ENDPOINT, (_, res, ctx) =>

View File

@@ -121,14 +121,14 @@ function AuthDomain(): JSX.Element {
},
{
title: 'Enforce SSO',
dataIndex: 'ssoEnabled',
dataIndex: ['config', 'ssoEnabled'],
key: 'ssoEnabled',
width: 80,
render: (
value: boolean,
record: AuthtypesGettableAuthDomainDTO,
): JSX.Element => (
<SSOEnforcementToggle isDefaultChecked={value} record={record} />
<SSOEnforcementToggle isDefaultChecked={!!value} record={record} />
),
},
{

View File

@@ -1,6 +1,7 @@
import { useEffect, useState } from 'react';
import { Info } from '@signozhq/icons';
import { Flex, Form, Input, Space, Switch, Tooltip } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Flex, Form, Input, Space, Tooltip } from 'antd';
import { ProcessorData } from 'types/api/pipeline/def';
import { PREDEFINED_MAPPING } from '../config';
@@ -58,11 +59,7 @@ function JsonFlattening({
initialValue={isAdd ? true : selectedProcessorData?.enable_paths}
>
<Space>
<Switch
size="small"
checked={enablePaths}
onChange={handleEnablePathsChange}
/>
<Switch value={enablePaths} onChange={handleEnablePathsChange} />
Enable Paths
</Space>
</Form.Item>
@@ -79,11 +76,7 @@ function JsonFlattening({
<Form.Item className="json-flattening-form__item">
<Space>
<Switch
size="small"
checked={enableMapping}
onChange={handleEnableMappingChange}
/>
<Switch value={enableMapping} onChange={handleEnableMappingChange} />
<Flex gap="8px" align="center">
Enable Mapping
<Tooltip title="The order of filled keys will determine the priority of keys i.e. earlier keys have higher precedence">

View File

@@ -1,5 +1,6 @@
import { useTranslation } from 'react-i18next';
import { Form, Input, Select, Space, Switch } from 'antd';
import { Form, Input, Select, Space } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { ModalFooterTitle } from 'container/PipelinePage/styles';
import { ProcessorData } from 'types/api/pipeline/def';
@@ -92,8 +93,7 @@ function ProcessorFieldInput({
>
<Space>
<Switch
size="small"
checked={form.getFieldValue('enable_flattening')}
value={form.getFieldValue('enable_flattening')}
onChange={(checked: boolean): void => {
form.setFieldValue('enable_flattening', checked);
}}

View File

@@ -1,5 +1,5 @@
import { GripVertical } from '@signozhq/icons';
import { Switch } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { holdIconStyle } from '../config';
import { LastActionColumn } from '../styles';
@@ -7,7 +7,7 @@ import { LastActionColumn } from '../styles';
function DragAction({ isEnabled, onChange }: DragActionProps): JSX.Element {
return (
<LastActionColumn>
<Switch defaultChecked={isEnabled} onChange={onChange} />
<Switch defaultValue={isEnabled} onChange={onChange} />
<GripVertical size="lg" style={holdIconStyle} />
</LastActionColumn>
);

View File

@@ -191,7 +191,7 @@ describe('PipelinePage container test', () => {
await fireEvent.click(expandIcon[0]);
const switchToggle = document.querySelector(
'.ant-table-expanded-row .ant-switch',
'.ant-table-expanded-row [role="switch"]',
);
expect(switchToggle).toBeChecked();
@@ -244,7 +244,7 @@ describe('PipelinePage container test', () => {
const addNewPipelineBtn = getByText('add_new_pipeline');
expect(addNewPipelineBtn).toBeInTheDocument();
const switchToggle = document.querySelectorAll('.ant-switch');
const switchToggle = document.querySelectorAll('[role="switch"]');
expect(switchToggle[0]).not.toBeChecked();
await fireEvent.click(switchToggle[0] as HTMLElement);

View File

@@ -21,26 +21,25 @@ exports[`PipelinePage container test should render DragAction section 1`] = `
<div
class="c0"
>
<button
aria-checked="true"
class="ant-switch css-dev-only-do-not-override-2i2tap ant-switch-checked"
role="switch"
type="button"
<div
class="_switch-wrapper_jbsv7_1"
>
<div
class="ant-switch-handle"
/>
<span
class="ant-switch-inner"
<button
aria-checked="true"
class="_switch_jbsv7_1"
data-color="robin"
data-state="checked"
id=":r0:"
role="switch"
type="button"
value="on"
>
<span
class="ant-switch-inner-checked"
class="_switch__thumb_jbsv7_59"
data-state="checked"
/>
<span
class="ant-switch-inner-unchecked"
/>
</span>
</button>
</button>
</div>
<svg
style="font-size: 1rem; cursor: move;"
/>

View File

@@ -1,9 +1,8 @@
import { useCallback, useEffect, useMemo } from 'react';
import { Check, ChevronDown, Plus } from '@signozhq/icons';
import { Button } from '@signozhq/ui/button';
import { DropdownMenuSimple, type MenuItem } from '@signozhq/ui/dropdown-menu';
import { Input } from '@signozhq/ui/input';
import type { MenuProps } from 'antd';
import { Dropdown } from 'antd';
import { useListServiceAccounts } from 'api/generated/services/serviceaccount';
import AuthZTooltip from 'components/AuthZTooltip/AuthZTooltip';
import CreateServiceAccountModal from 'components/CreateServiceAccountModal/CreateServiceAccountModal';
@@ -134,7 +133,7 @@ function ServiceAccountsSettings(): JSX.Element {
const totalCount = allAccounts.length;
const filterMenuItems: MenuProps['items'] = [
const filterMenuItems: MenuItem[] = [
{
key: FilterMode.All,
label: (
@@ -231,10 +230,9 @@ function ServiceAccountsSettings(): JSX.Element {
) : (
<div className="sa-settings__list-section">
<div className="sa-settings__controls">
<Dropdown
<DropdownMenuSimple
menu={{ items: filterMenuItems }}
trigger={['click']}
overlayClassName="sa-settings-filter-dropdown"
className="sa-settings-filter-dropdown"
>
<Button
variant="solid"
@@ -247,7 +245,7 @@ function ServiceAccountsSettings(): JSX.Element {
className="sa-settings-filter-trigger__chevron"
/>
</Button>
</Dropdown>
</DropdownMenuSimple>
<div className="sa-settings__search">
<Input

View File

@@ -1,4 +1,5 @@
import type { ReactNode } from 'react';
import userEvent from '@testing-library/user-event';
import { listRolesSuccessResponse } from 'mocks-server/__mockdata__/roles';
import { rest, server } from 'mocks-server/server';
import { NuqsTestingAdapter } from 'nuqs/adapters/testing';
@@ -129,6 +130,7 @@ describe('ServiceAccountsSettings (integration)', () => {
});
it('filter dropdown to "Active" hides DISABLED accounts', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
render(
<NuqsTestingAdapter>
<ServiceAccountsSettings />
@@ -137,10 +139,10 @@ describe('ServiceAccountsSettings (integration)', () => {
await screen.findByText('CI Bot');
fireEvent.click(screen.getByRole('button', { name: /All accounts/i }));
await user.click(screen.getByRole('button', { name: /All accounts/i }));
const activeOption = await screen.findByText(/Active ⎯/i);
fireEvent.click(activeOption);
await user.click(activeOption);
await screen.findByText('CI Bot');
expect(screen.queryByText('Legacy Bot')).not.toBeInTheDocument();

View File

@@ -662,7 +662,7 @@
}
}
&:not(.pinned):hover,
&:not(.pinned).is-hovered,
&.dropdown-open {
flex: 0 0 240px;
max-width: 240px;

View File

@@ -1,5 +1,6 @@
import {
MouseEvent,
ReactNode,
useCallback,
useEffect,
useMemo,
@@ -25,7 +26,14 @@ import {
verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { Button, Dropdown, MenuProps, Modal, Tooltip } from 'antd';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@signozhq/ui/dropdown-menu';
import { Button, MenuProps, Modal, Tooltip } from 'antd';
import logEvent from 'api/common/logEvent';
import { Logout } from 'api/utils';
import updateUserPreference from 'api/v1/user/preferences/name/update';
@@ -162,7 +170,9 @@ function SideNav({ isPinned }: { isPinned: boolean }): JSX.Element {
const [hasScroll, setHasScroll] = useState(false);
const navTopSectionRef = useRef<HTMLDivElement>(null);
const sidenavRef = useRef<HTMLDivElement>(null);
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const isDropdownOpenRef = useRef(false);
const [isHovered, setIsHovered] = useState(false);
const [pinnedMenuItems, setPinnedMenuItems] = useState<SidebarItem[]>([]);
@@ -175,9 +185,27 @@ function SideNav({ isPinned }: { isPinned: boolean }): JSX.Element {
}, []);
const handleMouseLeave = useCallback(() => {
// When the dropdown is open its content renders in a portal outside
// the sidenav, which causes the browser to fire mouseleave on the
// sidenav. Keep the sidenav expanded in that case.
if (isDropdownOpenRef.current) {
return;
}
setIsHovered(false);
}, []);
const handleDropdownOpenChange = useCallback((open: boolean): void => {
isDropdownOpenRef.current = open;
setIsDropdownOpen(open);
if (!open) {
// Re-sync hover state on close: the cursor may have moved to the
// portal content (outside .sideNav), so mouseleave never fired.
requestAnimationFrame(() => {
setIsHovered(sidenavRef.current?.matches(':hover') ?? false);
});
}
}, []);
const checkScroll = useCallback((): void => {
if (navTopSectionRef.current) {
const { scrollHeight, clientHeight, scrollTop } = navTopSectionRef.current;
@@ -959,9 +987,11 @@ function SideNav({ isPinned }: { isPinned: boolean }): JSX.Element {
return (
<div className={cx('sidenav-container', isPinned && 'pinned')}>
<div
ref={sidenavRef}
className={cx(
'sideNav',
isPinned && 'pinned',
isHovered && 'is-hovered',
isDropdownOpen && 'dropdown-open',
)}
onMouseEnter={handleMouseEnter}
@@ -1182,46 +1212,95 @@ function SideNav({ isPinned }: { isPinned: boolean }): JSX.Element {
{isAIAssistantEnabled && renderNavItems([aiAssistantMenuItem], false)}
<div className="nav-dropdown-item">
<Dropdown
menu={{
items: helpSupportDropdownMenuItems,
onClick: handleHelpSupportMenuItemClick,
}}
placement="topLeft"
overlayClassName="nav-dropdown-overlay help-support-dropdown"
trigger={['click']}
onOpenChange={(open): void => setIsDropdownOpen(open)}
>
<div className="nav-item">
<div className="nav-item-data" data-testid="help-support-nav-item">
<div className="nav-item-icon">{helpSupportMenuItem.icon}</div>
<DropdownMenu onOpenChange={handleDropdownOpenChange}>
<DropdownMenuTrigger asChild>
<div className="nav-item">
<div className="nav-item-data" data-testid="help-support-nav-item">
<div className="nav-item-icon">{helpSupportMenuItem.icon}</div>
<div className="nav-item-label">{helpSupportMenuItem.label}</div>
<div className="nav-item-label">{helpSupportMenuItem.label}</div>
</div>
</div>
</div>
</Dropdown>
</DropdownMenuTrigger>
<DropdownMenuContent
side="top"
align="start"
className="nav-dropdown-overlay help-support-dropdown"
>
{helpSupportDropdownMenuItems.map((item, idx) => {
if ('type' in item) {
// eslint-disable-next-line react/no-array-index-key
return <DropdownMenuSeparator key={`help-sep-${idx}`} />;
}
return (
<DropdownMenuItem
key={String(item.key)}
leftIcon={item.icon}
onClick={(e): void =>
handleHelpSupportMenuItemClick({
...item,
key: String(item.key),
domEvent: e.nativeEvent,
} as unknown as SidebarItem)
}
>
{item.label}
</DropdownMenuItem>
);
})}
</DropdownMenuContent>
</DropdownMenu>
</div>
<div className="nav-dropdown-item">
<Dropdown
menu={{
items: userSettingsDropdownMenuItems,
onClick: handleSettingsMenuItemClick,
}}
placement="topLeft"
overlayClassName="nav-dropdown-overlay settings-dropdown"
trigger={['click']}
onOpenChange={(open): void => setIsDropdownOpen(open)}
>
<div className={cx('nav-item', isSettingsPage && 'active')}>
<div className="nav-item-active-marker" />
<div className="nav-item-data" data-testid="settings-nav-item">
<div className="nav-item-icon">{userSettingsMenuItem.icon}</div>
<DropdownMenu onOpenChange={handleDropdownOpenChange}>
<DropdownMenuTrigger asChild>
<div className={cx('nav-item', isSettingsPage && 'active')}>
<div className="nav-item-active-marker" />
<div className="nav-item-data" data-testid="settings-nav-item">
<div className="nav-item-icon">{userSettingsMenuItem.icon}</div>
<div className="nav-item-label">{userSettingsMenuItem.label}</div>
<div className="nav-item-label">{userSettingsMenuItem.label}</div>
</div>
</div>
</div>
</Dropdown>
</DropdownMenuTrigger>
<DropdownMenuContent
side="top"
align="start"
className="nav-dropdown-overlay settings-dropdown"
>
{(userSettingsDropdownMenuItems ?? []).map((item, idx) => {
if (!item) {
return null;
}
if ('type' in item && item.type === 'divider') {
// eslint-disable-next-line react/no-array-index-key
return <DropdownMenuSeparator key={`settings-sep-${idx}`} />;
}
const settingsItem = item as {
key?: string | number;
label?: ReactNode;
icon?: ReactNode;
disabled?: boolean;
};
return (
<DropdownMenuItem
key={String(settingsItem.key)}
leftIcon={settingsItem.icon}
disabled={settingsItem.disabled}
onClick={(e): void =>
handleSettingsMenuItemClick({
key: String(settingsItem.key),
domEvent: e.nativeEvent,
} as unknown as SidebarItem)
}
>
{settingsItem.label}
</DropdownMenuItem>
);
})}
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
</div>

View File

@@ -0,0 +1,258 @@
import {
act,
fireEvent,
render,
screen,
waitFor,
} from '@testing-library/react';
import DateTimeSelection from '../index';
import {
__resetSearchParamsGetter,
__setSearchParamsGetterForTest,
} from '../utils/getUnstableCurrentSearchParams';
import { queryClient, TestWrapper } from './testUtils';
const mockSafeNavigate = jest.fn();
jest.mock('hooks/useSafeNavigate', () => ({
useSafeNavigate: (): { safeNavigate: jest.Mock } => ({
safeNavigate: mockSafeNavigate,
}),
}));
jest.mock('container/NewExplorerCTA', () => ({
__esModule: true,
default: (): null => null,
}));
jest.mock('components/CustomTimePicker/CustomTimePicker', () => ({
__esModule: true,
default: ({
onSelect,
}: {
onSelect: (value: string) => void;
}): JSX.Element => (
<div data-testid="custom-time-picker">
<button
type="button"
data-testid="select-15m"
onClick={(): void => onSelect('15m')}
>
15m
</button>
<button
type="button"
data-testid="select-1h"
onClick={(): void => onSelect('1h')}
>
1h
</button>
<button
type="button"
data-testid="select-6h"
onClick={(): void => onSelect('6h')}
>
6h
</button>
<button
type="button"
data-testid="select-custom"
onClick={(): void => onSelect('custom')}
>
Custom
</button>
</div>
),
}));
describe('DateTimeSelectionV2 - Edge Cases', () => {
let currentSearchParams: URLSearchParams;
beforeEach(() => {
jest.clearAllMocks();
mockSafeNavigate.mockClear();
queryClient.clear();
});
afterEach(() => {
__resetSearchParamsGetter();
});
describe('Fresh Params at Navigation Time (Core Fix)', () => {
it('should read params at navigation time, not render time', async () => {
currentSearchParams = new URLSearchParams('relativeTime=30m');
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper
initialSearchParams="relativeTime=30m"
onUrlUpdate={(event): void => {
currentSearchParams = event.searchParams;
}}
>
<DateTimeSelection showAutoRefresh />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
currentSearchParams = new URLSearchParams(
'relativeTime=30m&externalParam=addedLater',
);
mockSafeNavigate.mockClear();
act(() => {
fireEvent.click(screen.getByTestId('select-1h'));
});
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[
mockSafeNavigate.mock.calls.length - 1
][0] as string;
expect(navigatedUrl).toContain('relativeTime=1h');
expect(navigatedUrl).toContain('externalParam=addedLater');
});
it('should preserve multiple externally added params', async () => {
currentSearchParams = new URLSearchParams('relativeTime=30m');
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper initialSearchParams="relativeTime=30m">
<DateTimeSelection showAutoRefresh />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
currentSearchParams = new URLSearchParams(
'relativeTime=30m&yAxisUnit=bytes&groupBy=host&view=table',
);
mockSafeNavigate.mockClear();
act(() => {
fireEvent.click(screen.getByTestId('select-6h'));
});
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[
mockSafeNavigate.mock.calls.length - 1
][0] as string;
expect(navigatedUrl).toContain('relativeTime=6h');
expect(navigatedUrl).toContain('yAxisUnit=bytes');
expect(navigatedUrl).toContain('groupBy=host');
expect(navigatedUrl).toContain('view=table');
});
});
describe('Empty and Special Values', () => {
it('should handle empty URL params gracefully', async () => {
currentSearchParams = new URLSearchParams('');
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper initialSearchParams="">
<DateTimeSelection showAutoRefresh />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
mockSafeNavigate.mockClear();
act(() => {
fireEvent.click(screen.getByTestId('select-15m'));
});
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[
mockSafeNavigate.mock.calls.length - 1
][0] as string;
expect(navigatedUrl).toContain('relativeTime=15m');
});
it('should handle special characters in preserved params', async () => {
currentSearchParams = new URLSearchParams(
'relativeTime=30m&filter=name%3D%22test%22',
);
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper initialSearchParams="relativeTime=30m&filter=name%3D%22test%22">
<DateTimeSelection showAutoRefresh />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
mockSafeNavigate.mockClear();
act(() => {
fireEvent.click(screen.getByTestId('select-1h'));
});
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[
mockSafeNavigate.mock.calls.length - 1
][0] as string;
expect(navigatedUrl).toContain('relativeTime=1h');
expect(navigatedUrl).toContain('filter=');
});
it('should not navigate when selecting custom (opens picker instead)', async () => {
currentSearchParams = new URLSearchParams('relativeTime=30m');
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper initialSearchParams="relativeTime=30m">
<DateTimeSelection showAutoRefresh />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
mockSafeNavigate.mockClear();
act(() => {
fireEvent.click(screen.getByTestId('select-custom'));
});
await new Promise((resolve) => setTimeout(resolve, 100));
const customNavigationCalls = mockSafeNavigate.mock.calls.filter((call) => {
const url = call[0] as string;
return url.includes('startTime=') || url.includes('endTime=');
});
expect(customNavigationCalls).toHaveLength(0);
});
});
});

View File

@@ -0,0 +1,180 @@
import {
act,
fireEvent,
render,
screen,
waitFor,
} from '@testing-library/react';
import DateTimeSelection from '../index';
import {
__resetSearchParamsGetter,
__setSearchParamsGetterForTest,
} from '../utils/getUnstableCurrentSearchParams';
import { queryClient, TestWrapper } from './testUtils';
const mockSafeNavigate = jest.fn();
jest.mock('hooks/useSafeNavigate', () => ({
useSafeNavigate: (): { safeNavigate: jest.Mock } => ({
safeNavigate: mockSafeNavigate,
}),
}));
jest.mock('container/NewExplorerCTA', () => ({
__esModule: true,
default: (): null => null,
}));
let mockOnCustomDateHandler: ((range: [unknown, unknown]) => void) | null =
null;
let mockOnValidCustomDateChange: ((data: { timeStr: string }) => void) | null =
null;
jest.mock('components/CustomTimePicker/CustomTimePicker', () => ({
__esModule: true,
default: ({
onSelect,
onCustomDateHandler,
onValidCustomDateChange,
}: {
onSelect: (value: string) => void;
onCustomDateHandler?: (range: [unknown, unknown]) => void;
onValidCustomDateChange?: (data: { timeStr: string }) => void;
}): JSX.Element => {
mockOnCustomDateHandler = onCustomDateHandler || null;
mockOnValidCustomDateChange = onValidCustomDateChange || null;
return (
<div data-testid="custom-time-picker">
<button
type="button"
data-testid="select-1h"
onClick={(): void => onSelect('1h')}
>
1h
</button>
</div>
);
},
}));
describe('DateTimeSelectionV2 - Modal Mode', () => {
let currentSearchParams: URLSearchParams;
beforeEach(() => {
jest.clearAllMocks();
mockSafeNavigate.mockClear();
queryClient.clear();
mockOnCustomDateHandler = null;
mockOnValidCustomDateChange = null;
});
afterEach(() => {
__resetSearchParamsGetter();
});
it('should call onTimeChange instead of navigating for relative time', async () => {
currentSearchParams = new URLSearchParams('relativeTime=30m');
__setSearchParamsGetterForTest(() => currentSearchParams);
const mockOnTimeChange = jest.fn();
render(
<TestWrapper initialSearchParams="relativeTime=30m">
<DateTimeSelection
showAutoRefresh
isModalTimeSelection
onTimeChange={mockOnTimeChange}
/>
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
mockSafeNavigate.mockClear();
act(() => {
fireEvent.click(screen.getByTestId('select-1h'));
});
await waitFor(() => {
expect(mockOnTimeChange).toHaveBeenCalledWith('1h');
});
expect(mockSafeNavigate).not.toHaveBeenCalled();
});
it('should call onTimeChange with custom and timestamps for custom date', async () => {
currentSearchParams = new URLSearchParams('relativeTime=30m');
__setSearchParamsGetterForTest(() => currentSearchParams);
const mockOnTimeChange = jest.fn();
render(
<TestWrapper initialSearchParams="relativeTime=30m">
<DateTimeSelection
showAutoRefresh
isModalTimeSelection
onTimeChange={mockOnTimeChange}
/>
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
const startMoment = { toDate: (): Date => new Date(1700000000000) };
const endMoment = { toDate: (): Date => new Date(1700003600000) };
mockSafeNavigate.mockClear();
act(() => {
mockOnCustomDateHandler?.([startMoment, endMoment]);
});
await waitFor(() => {
expect(mockOnTimeChange).toHaveBeenCalledWith(
'custom',
[1700000000000, 1700003600000],
);
});
expect(mockSafeNavigate).not.toHaveBeenCalled();
});
it('should call onTimeChange for valid custom date string in modal', async () => {
currentSearchParams = new URLSearchParams('relativeTime=30m');
__setSearchParamsGetterForTest(() => currentSearchParams);
const mockOnTimeChange = jest.fn();
render(
<TestWrapper initialSearchParams="relativeTime=30m">
<DateTimeSelection
showAutoRefresh
isModalTimeSelection
onTimeChange={mockOnTimeChange}
/>
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
mockSafeNavigate.mockClear();
act(() => {
mockOnValidCustomDateChange?.({ timeStr: '4h' });
});
await waitFor(() => {
expect(mockOnTimeChange).toHaveBeenCalledWith('4h');
});
expect(mockSafeNavigate).not.toHaveBeenCalled();
});
});

View File

@@ -0,0 +1,207 @@
// eslint-disable-next-line no-restricted-imports
import { Provider } from 'react-redux';
import { MemoryRouter, Route } from 'react-router-dom';
import { NuqsTestingAdapter } from 'nuqs/adapters/testing';
import { QueryClient, QueryClientProvider } from 'react-query';
import {
act,
fireEvent,
render,
screen,
waitFor,
} from '@testing-library/react';
import { parseAsString, useQueryState } from 'nuqs';
import { AppContext } from 'providers/App/App';
import TimezoneProvider from 'providers/Timezone';
import { QueryBuilderProvider } from 'providers/QueryBuilder';
import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import store from 'store';
import { getAppContextMock } from 'tests/test-utils';
import { CompatRouter } from 'react-router-dom-v5-compat';
import DateTimeSelection from '../index';
import {
__resetSearchParamsGetter,
__setSearchParamsGetterForTest,
} from '../utils/getUnstableCurrentSearchParams';
const queryClient = new QueryClient({
defaultOptions: {
queries: { refetchOnWindowFocus: false, retry: false },
mutations: { retry: false },
},
});
const mockStore = configureStore([thunk]);
const mockSafeNavigate = jest.fn();
jest.mock('hooks/useSafeNavigate', () => ({
useSafeNavigate: (): { safeNavigate: jest.Mock } => ({
safeNavigate: mockSafeNavigate,
}),
}));
jest.mock('components/CustomTimePicker/CustomTimePicker', () => ({
__esModule: true,
default: ({
onSelect,
}: {
onSelect: (value: string) => void;
}): JSX.Element => (
<div data-testid="custom-time-picker">
<button
type="button"
data-testid="select-1h"
onClick={(): void => onSelect('1h')}
>
1h
</button>
</div>
),
}));
jest.mock('container/NewExplorerCTA', () => ({
__esModule: true,
default: (): null => null,
}));
function NuqsParamSetter({ paramValue }: { paramValue: string }): JSX.Element {
const [, setYAxisUnit] = useQueryState(
'yAxisUnit',
parseAsString.withDefault(''),
);
return (
<button
type="button"
data-testid="set-nuqs-param"
onClick={(): void => {
setYAxisUnit(paramValue);
}}
>
Set yAxisUnit
</button>
);
}
interface WrapperProps {
children: React.ReactNode;
initialSearchParams?: string;
initialPath?: string;
onUrlUpdate?: (event: { searchParams: URLSearchParams }) => void;
}
function TestWrapper({
children,
initialSearchParams = '',
initialPath = '/services',
onUrlUpdate,
}: WrapperProps): JSX.Element {
const initialEntry = initialSearchParams
? `${initialPath}?${initialSearchParams}`
: initialPath;
const mockedStore = mockStore({
...store.getState(),
app: {
...store.getState().app,
role: 'ADMIN',
user: {
userId: 'test-user-id',
email: 'test@signoz.io',
name: 'TestUser',
profilePictureURL: '',
accessJwt: '',
refreshJwt: '',
},
isLoggedIn: true,
},
});
return (
<MemoryRouter initialEntries={[initialEntry]}>
<CompatRouter>
<NuqsTestingAdapter
searchParams={initialSearchParams}
onUrlUpdate={onUrlUpdate}
>
<QueryClientProvider client={queryClient}>
<Provider store={mockedStore}>
<AppContext.Provider value={getAppContextMock('ADMIN')}>
<TimezoneProvider>
<QueryBuilderProvider>
<Route path="*">{children}</Route>
</QueryBuilderProvider>
</TimezoneProvider>
</AppContext.Provider>
</Provider>
</QueryClientProvider>
</NuqsTestingAdapter>
</CompatRouter>
</MemoryRouter>
);
}
describe('REGRESSION: DateTimeSelectionV2 preserves nuqs query params on time change', () => {
let currentSearchParams: URLSearchParams;
beforeEach(() => {
jest.clearAllMocks();
mockSafeNavigate.mockClear();
queryClient.clear();
// Initialize with test's initial search params
currentSearchParams = new URLSearchParams('relativeTime=30m');
__setSearchParamsGetterForTest(() => currentSearchParams);
});
afterEach(() => {
__resetSearchParamsGetter();
});
it('should preserve yAxisUnit param set via nuqs when changing time selection', async () => {
render(
<TestWrapper
initialSearchParams="relativeTime=30m"
onUrlUpdate={(event): void => {
// Sync nuqs URL updates to our mock getter
// This simulates how window.location.search would be updated in real browser
currentSearchParams = event.searchParams;
}}
>
<NuqsParamSetter paramValue="bytes" />
<DateTimeSelection showAutoRefresh />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
act(() => {
fireEvent.click(screen.getByTestId('set-nuqs-param'));
});
await waitFor(() => {
expect(currentSearchParams.get('yAxisUnit')).toBe('bytes');
});
mockSafeNavigate.mockClear();
act(() => {
fireEvent.click(screen.getByTestId('select-1h'));
});
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[
mockSafeNavigate.mock.calls.length - 1
][0] as string;
expect(navigatedUrl).toContain('relativeTime=1h');
expect(navigatedUrl).toContain('yAxisUnit=bytes');
});
});

View File

@@ -0,0 +1,133 @@
import { render, screen, waitFor } from '@testing-library/react';
import ROUTES from 'constants/routes';
import DateTimeSelection from '../index';
import {
__resetSearchParamsGetter,
__setSearchParamsGetterForTest,
} from '../utils/getUnstableCurrentSearchParams';
import { queryClient, TestWrapper } from './testUtils';
const mockSafeNavigate = jest.fn();
jest.mock('hooks/useSafeNavigate', () => ({
useSafeNavigate: (): { safeNavigate: jest.Mock } => ({
safeNavigate: mockSafeNavigate,
}),
}));
jest.mock('container/NewExplorerCTA', () => ({
__esModule: true,
default: (): null => null,
}));
jest.mock('components/CustomTimePicker/CustomTimePicker', () => ({
__esModule: true,
default: (): JSX.Element => <div data-testid="custom-time-picker" />,
}));
describe('DateTimeSelectionV2 - Route-Specific Behavior', () => {
let currentSearchParams: URLSearchParams;
beforeEach(() => {
jest.clearAllMocks();
mockSafeNavigate.mockClear();
queryClient.clear();
});
afterEach(() => {
__resetSearchParamsGetter();
});
describe('Alert Pages', () => {
it('should set default time for alert overview when no time params', async () => {
currentSearchParams = new URLSearchParams('otherParam=value');
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper
initialSearchParams="otherParam=value"
initialPath={ROUTES.ALERT_OVERVIEW}
>
<DateTimeSelection showAutoRefresh defaultRelativeTime="6h" />
</TestWrapper>,
);
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[0][0] as string;
expect(navigatedUrl).toContain('relativeTime=6h');
expect(navigatedUrl).toContain('otherParam=value');
});
it('should set default time for alert history when no time params', async () => {
currentSearchParams = new URLSearchParams('filter=active');
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper
initialSearchParams="filter=active"
initialPath={ROUTES.ALERT_HISTORY}
>
<DateTimeSelection showAutoRefresh defaultRelativeTime="6h" />
</TestWrapper>,
);
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[0][0] as string;
expect(navigatedUrl).toContain('relativeTime=6h');
});
it('should NOT override existing time params on alert pages', async () => {
currentSearchParams = new URLSearchParams('relativeTime=1h&filter=active');
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper
initialSearchParams="relativeTime=1h&filter=active"
initialPath={ROUTES.ALERT_OVERVIEW}
>
<DateTimeSelection showAutoRefresh defaultRelativeTime="6h" />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
const calls = mockSafeNavigate.mock.calls;
if (calls.length > 0) {
const lastUrl = calls[calls.length - 1][0] as string;
expect(lastUrl).toContain('relativeTime=1h');
}
});
});
describe('disableUrlSync Behavior', () => {
it('should not sync URL on mount when disableUrlSync is true', async () => {
currentSearchParams = new URLSearchParams('');
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper initialSearchParams="" initialPath="/services">
<DateTimeSelection showAutoRefresh disableUrlSync />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
const syncCalls = mockSafeNavigate.mock.calls.filter((call) => {
const url = call[0] as string;
return url.includes('relativeTime=') && !url.includes('services?');
});
expect(syncCalls).toHaveLength(0);
});
});
});

View File

@@ -0,0 +1,353 @@
import {
act,
fireEvent,
render,
screen,
waitFor,
} from '@testing-library/react';
import DateTimeSelection from '../index';
import {
__resetSearchParamsGetter,
__setSearchParamsGetterForTest,
} from '../utils/getUnstableCurrentSearchParams';
import { queryClient, TestWrapper, createMockMoment } from './testUtils';
const mockSafeNavigate = jest.fn();
jest.mock('hooks/useSafeNavigate', () => ({
useSafeNavigate: (): { safeNavigate: jest.Mock } => ({
safeNavigate: mockSafeNavigate,
}),
}));
jest.mock('container/NewExplorerCTA', () => ({
__esModule: true,
default: (): null => null,
}));
let mockOnCustomDateHandler: ((range: [unknown, unknown]) => void) | null =
null;
let mockOnValidCustomDateChange: ((data: { timeStr: string }) => void) | null =
null;
jest.mock('components/CustomTimePicker/CustomTimePicker', () => ({
__esModule: true,
default: ({
onSelect,
onCustomDateHandler,
onValidCustomDateChange,
}: {
onSelect: (value: string) => void;
onCustomDateHandler?: (range: [unknown, unknown]) => void;
onValidCustomDateChange?: (data: { timeStr: string }) => void;
}): JSX.Element => {
mockOnCustomDateHandler = onCustomDateHandler || null;
mockOnValidCustomDateChange = onValidCustomDateChange || null;
return (
<div data-testid="custom-time-picker">
<button
type="button"
data-testid="select-15m"
onClick={(): void => onSelect('15m')}
>
15m
</button>
<button
type="button"
data-testid="select-1h"
onClick={(): void => onSelect('1h')}
>
1h
</button>
<button
type="button"
data-testid="select-6h"
onClick={(): void => onSelect('6h')}
>
6h
</button>
</div>
);
},
}));
describe('DateTimeSelectionV2 - Time Selection', () => {
let currentSearchParams: URLSearchParams;
beforeEach(() => {
jest.clearAllMocks();
mockSafeNavigate.mockClear();
queryClient.clear();
mockOnCustomDateHandler = null;
mockOnValidCustomDateChange = null;
});
afterEach(() => {
__resetSearchParamsGetter();
});
describe('Relative Time', () => {
it('should update relativeTime and remove startTime/endTime', async () => {
currentSearchParams = new URLSearchParams(
'startTime=1000&endTime=2000&otherParam=keep',
);
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper initialSearchParams="startTime=1000&endTime=2000&otherParam=keep">
<DateTimeSelection showAutoRefresh />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
mockSafeNavigate.mockClear();
act(() => {
fireEvent.click(screen.getByTestId('select-15m'));
});
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[
mockSafeNavigate.mock.calls.length - 1
][0] as string;
expect(navigatedUrl).toContain('relativeTime=15m');
expect(navigatedUrl).not.toContain('startTime=');
expect(navigatedUrl).not.toContain('endTime=');
expect(navigatedUrl).toContain('otherParam=keep');
});
it('should remove activeLogId param on time change', async () => {
currentSearchParams = new URLSearchParams(
'relativeTime=30m&activeLogId=log123',
);
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper initialSearchParams="relativeTime=30m&activeLogId=log123">
<DateTimeSelection showAutoRefresh />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
mockSafeNavigate.mockClear();
act(() => {
fireEvent.click(screen.getByTestId('select-1h'));
});
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[
mockSafeNavigate.mock.calls.length - 1
][0] as string;
expect(navigatedUrl).toContain('relativeTime=1h');
expect(navigatedUrl).not.toContain('activeLogId');
});
it('should update compositeQuery with new ID when present', async () => {
const compositeQuery = encodeURIComponent(
JSON.stringify({ id: 'old-id', builder: { queryData: [] } }),
);
currentSearchParams = new URLSearchParams(
`relativeTime=30m&compositeQuery=${compositeQuery}`,
);
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper
initialSearchParams={`relativeTime=30m&compositeQuery=${compositeQuery}`}
>
<DateTimeSelection showAutoRefresh />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
mockSafeNavigate.mockClear();
act(() => {
fireEvent.click(screen.getByTestId('select-6h'));
});
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[
mockSafeNavigate.mock.calls.length - 1
][0] as string;
expect(navigatedUrl).toContain('compositeQuery=');
expect(navigatedUrl).not.toContain('old-id');
});
it('should preserve all non-time URL params', async () => {
currentSearchParams = new URLSearchParams(
'relativeTime=30m&param1=a&param2=b&param3=c',
);
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper initialSearchParams="relativeTime=30m&param1=a&param2=b&param3=c">
<DateTimeSelection showAutoRefresh />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
mockSafeNavigate.mockClear();
act(() => {
fireEvent.click(screen.getByTestId('select-1h'));
});
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[
mockSafeNavigate.mock.calls.length - 1
][0] as string;
expect(navigatedUrl).toContain('relativeTime=1h');
expect(navigatedUrl).toContain('param1=a');
expect(navigatedUrl).toContain('param2=b');
expect(navigatedUrl).toContain('param3=c');
});
});
describe('Custom Date Range', () => {
it('should set startTime/endTime and remove relativeTime', async () => {
currentSearchParams = new URLSearchParams('relativeTime=30m&keepThis=yes');
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper initialSearchParams="relativeTime=30m&keepThis=yes">
<DateTimeSelection showAutoRefresh />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
const startMoment = createMockMoment(1700000000000);
const endMoment = createMockMoment(1700003600000);
mockSafeNavigate.mockClear();
act(() => {
mockOnCustomDateHandler?.([startMoment, endMoment]);
});
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[
mockSafeNavigate.mock.calls.length - 1
][0] as string;
expect(navigatedUrl).toContain('startTime=1700000000000');
expect(navigatedUrl).toContain('endTime=1700003600000');
expect(navigatedUrl).not.toContain('relativeTime=');
expect(navigatedUrl).toContain('keepThis=yes');
});
it('should update compositeQuery when present for custom date', async () => {
const compositeQuery = encodeURIComponent(
JSON.stringify({ id: 'old-id', builder: { queryData: [] } }),
);
currentSearchParams = new URLSearchParams(
`relativeTime=30m&compositeQuery=${compositeQuery}`,
);
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper
initialSearchParams={`relativeTime=30m&compositeQuery=${compositeQuery}`}
>
<DateTimeSelection showAutoRefresh />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
const startMoment = createMockMoment(1700000000000);
const endMoment = createMockMoment(1700003600000);
mockSafeNavigate.mockClear();
act(() => {
mockOnCustomDateHandler?.([startMoment, endMoment]);
});
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[
mockSafeNavigate.mock.calls.length - 1
][0] as string;
expect(navigatedUrl).toContain('compositeQuery=');
expect(navigatedUrl).not.toContain('old-id');
});
});
describe('Valid Custom Date String', () => {
it('should handle shorthand date format and preserve params', async () => {
currentSearchParams = new URLSearchParams('relativeTime=30m&filter=active');
__setSearchParamsGetterForTest(() => currentSearchParams);
render(
<TestWrapper initialSearchParams="relativeTime=30m&filter=active">
<DateTimeSelection showAutoRefresh />
</TestWrapper>,
);
await waitFor(() => {
expect(screen.getByTestId('custom-time-picker')).toBeInTheDocument();
});
mockSafeNavigate.mockClear();
act(() => {
mockOnValidCustomDateChange?.({ timeStr: '2h' });
});
await waitFor(() => {
expect(mockSafeNavigate).toHaveBeenCalled();
});
const navigatedUrl = mockSafeNavigate.mock.calls[
mockSafeNavigate.mock.calls.length - 1
][0] as string;
expect(navigatedUrl).toContain('relativeTime=2h');
expect(navigatedUrl).toContain('filter=active');
expect(navigatedUrl).not.toContain('startTime=');
expect(navigatedUrl).not.toContain('endTime=');
});
});
});

View File

@@ -0,0 +1,95 @@
// eslint-disable-next-line no-restricted-imports
import { Provider } from 'react-redux';
import { MemoryRouter, Route } from 'react-router-dom';
import { NuqsTestingAdapter } from 'nuqs/adapters/testing';
import { QueryClient, QueryClientProvider } from 'react-query';
import { AppContext } from 'providers/App/App';
import TimezoneProvider from 'providers/Timezone';
import { QueryBuilderProvider } from 'providers/QueryBuilder';
import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import store from 'store';
import { getAppContextMock } from 'tests/test-utils';
import { CompatRouter } from 'react-router-dom-v5-compat';
export const queryClient = new QueryClient({
defaultOptions: {
queries: { refetchOnWindowFocus: false, retry: false },
mutations: { retry: false },
},
});
export const mockStore = configureStore([thunk]);
interface WrapperProps {
children: React.ReactNode;
initialSearchParams?: string;
initialPath?: string;
onUrlUpdate?: (event: { searchParams: URLSearchParams }) => void;
}
export function TestWrapper({
children,
initialSearchParams = '',
initialPath = '/services',
onUrlUpdate,
}: WrapperProps): JSX.Element {
const initialEntry = initialSearchParams
? `${initialPath}?${initialSearchParams}`
: initialPath;
const mockedStore = mockStore({
...store.getState(),
app: {
...store.getState().app,
role: 'ADMIN',
user: {
userId: 'test-user-id',
email: 'test@signoz.io',
name: 'TestUser',
profilePictureURL: '',
accessJwt: '',
refreshJwt: '',
},
isLoggedIn: true,
},
});
return (
<MemoryRouter initialEntries={[initialEntry]}>
<CompatRouter>
<NuqsTestingAdapter
searchParams={initialSearchParams}
onUrlUpdate={onUrlUpdate}
>
<QueryClientProvider client={queryClient}>
<Provider store={mockedStore}>
<AppContext.Provider value={getAppContextMock('ADMIN')}>
<TimezoneProvider>
<QueryBuilderProvider>
<Route path="*">{children}</Route>
</QueryBuilderProvider>
</TimezoneProvider>
</AppContext.Provider>
</Provider>
</QueryClientProvider>
</NuqsTestingAdapter>
</CompatRouter>
</MemoryRouter>
);
}
export function createMockMoment(timestamp: number): {
toDate: () => Date;
toISOString: () => string;
format: () => string;
toString: () => string;
} {
const date = new Date(timestamp);
return {
toDate: (): Date => date,
toISOString: (): string => date.toISOString(),
format: (): string => date.toISOString(),
toString: (): string => date.toString(),
};
}

View File

@@ -2,7 +2,7 @@ import { useCallback, useEffect, useState } from 'react';
// eslint-disable-next-line no-restricted-imports
import { connect, useDispatch, useSelector } from 'react-redux';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { useNavigationType, useSearchParams } from 'react-router-dom-v5-compat';
import { useNavigationType } from 'react-router-dom-v5-compat';
import { RefreshCw, Undo } from '@signozhq/icons';
import { Button } from 'antd';
import getLocalStorageKey from 'api/browser/localstorage/get';
@@ -20,7 +20,6 @@ import {
} from 'store/globalTime';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import useUrlQuery from 'hooks/useUrlQuery';
import { isValidShortHandDateTimeFormat } from 'lib/getMinMax';
import getTimeString from 'lib/getTimeString';
import { cloneDeep, isObject } from 'lodash-es';
@@ -54,6 +53,7 @@ import {
Time,
TimeRange,
} from './types';
import { getUnstableCurrentSearchParams } from './utils/getUnstableCurrentSearchParams';
import './DateTimeSelectionV2.styles.scss';
@@ -90,10 +90,12 @@ function DateTimeSelection({
const [hasSelectedTimeError, setHasSelectedTimeError] = useState(false);
const [isOpen, setIsOpen] = useState<boolean>(false);
const urlQuery = useUrlQuery();
const searchStartTime = urlQuery.get('startTime');
const searchEndTime = urlQuery.get('endTime');
const relativeTimeFromUrl = urlQuery.get(QueryParams.relativeTime);
const currentSearchParams = getUnstableCurrentSearchParams();
const searchStartTime = currentSearchParams.get(QueryParams.startTime);
const searchEndTime = currentSearchParams.get(QueryParams.endTime);
const relativeTimeFromUrl = currentSearchParams.get(QueryParams.relativeTime);
const hasTimeParamsInUrl =
(searchStartTime && searchEndTime) || relativeTimeFromUrl;
// Prioritize props for initial modal time, fallback to URL params
let initialModalStartTime = 0;
@@ -115,8 +117,6 @@ function DateTimeSelection({
);
const [modalEndTime, setModalEndTime] = useState<number>(initialModalEndTime);
const [searchParams] = useSearchParams();
// Effect to update modal time state when props change
useEffect(() => {
if (modalInitialStartTime !== undefined) {
@@ -323,14 +323,15 @@ function DateTimeSelection({
return;
}
urlQuery.delete('startTime');
urlQuery.delete('endTime');
const urlQuery = getUnstableCurrentSearchParams();
urlQuery.delete(QueryParams.startTime);
urlQuery.delete(QueryParams.endTime);
urlQuery.set(QueryParams.relativeTime, value);
// Remove Hidden Filters from URL query parameters on time change
urlQuery.delete(QueryParams.activeLogId);
if (searchParams.has(QueryParams.compositeQuery)) {
if (urlQuery.has(QueryParams.compositeQuery)) {
const updatedCompositeQuery = getUpdatedCompositeQuery();
urlQuery.set(QueryParams.compositeQuery, updatedCompositeQuery);
}
@@ -349,8 +350,6 @@ function DateTimeSelection({
getUpdatedCompositeQuery,
updateLocalStorageForRoutes,
updateTimeInterval,
urlQuery,
searchParams,
],
);
@@ -414,6 +413,7 @@ function DateTimeSelection({
updateLocalStorageForRoutes(JSON.stringify({ startTime, endTime }));
const urlQuery = getUnstableCurrentSearchParams();
urlQuery.set(
QueryParams.startTime,
startTime?.toDate().getTime().toString(),
@@ -421,7 +421,7 @@ function DateTimeSelection({
urlQuery.set(QueryParams.endTime, endTime?.toDate().getTime().toString());
urlQuery.delete(QueryParams.relativeTime);
if (searchParams.has(QueryParams.compositeQuery)) {
if (urlQuery.has(QueryParams.compositeQuery)) {
const updatedCompositeQuery = getUpdatedCompositeQuery();
urlQuery.set(QueryParams.compositeQuery, updatedCompositeQuery);
}
@@ -441,8 +441,9 @@ function DateTimeSelection({
updateTimeInterval(dateTimeStr);
updateLocalStorageForRoutes(dateTimeStr);
urlQuery.delete('startTime');
urlQuery.delete('endTime');
const urlQuery = getUnstableCurrentSearchParams();
urlQuery.delete(QueryParams.startTime);
urlQuery.delete(QueryParams.endTime);
urlQuery.set(QueryParams.relativeTime, dateTimeStr);
@@ -595,13 +596,12 @@ function DateTimeSelection({
// set the default relative time for alert history and overview pages if relative time is not specified
if (
(!urlQuery.has(QueryParams.startTime) ||
!urlQuery.has(QueryParams.endTime)) &&
!urlQuery.has(QueryParams.relativeTime) &&
!hasTimeParamsInUrl &&
(currentRoute === ROUTES.ALERT_OVERVIEW ||
currentRoute === ROUTES.ALERT_HISTORY)
) {
updateTimeInterval(defaultRelativeTime);
const urlQuery = getUnstableCurrentSearchParams();
urlQuery.set(QueryParams.relativeTime, defaultRelativeTime);
const generatedUrl = `${location.pathname}?${urlQuery.toString()}`;
safeNavigate(generatedUrl);
@@ -625,9 +625,10 @@ function DateTimeSelection({
updateTimeInterval(updatedTime, [preStartTime, preEndTime]);
}
const urlQuery = getUnstableCurrentSearchParams();
if (updatedTime !== 'custom') {
urlQuery.delete('startTime');
urlQuery.delete('endTime');
urlQuery.delete(QueryParams.startTime);
urlQuery.delete(QueryParams.endTime);
urlQuery.set(QueryParams.relativeTime, updatedTime);
} else {
const startTime = preStartTime.toString();

View File

@@ -0,0 +1,34 @@
/**
* This was introduced to fix a sync bug between Nuqs and react-router-dom
*
* We are using the wrong adapter for nuqs because the correct one only supports v6/v7,
* and we are at version v5. This causes the nuqs/react-router-dom to be out of sync.
*
* We can revert this commit once we migrate react-router-dom to v6, or once we migrate
* to DateTimeSelectionV3
*/
/**
* This was created to help testing the regression introduced between nuqs/react-router-dom
*/
type SearchParamsGetter = () => URLSearchParams;
let getter: SearchParamsGetter = (): URLSearchParams =>
new URLSearchParams(window.location.search);
/**
* This function will return a fresh instance of URLSearchParams every time it's called.
*
* DO NOT USE IT FOR useEffect/useCallback dependencies, use Nuqs instead.
*/
export function getUnstableCurrentSearchParams(): URLSearchParams {
return getter();
}
// Testing helpers
export function __setSearchParamsGetterForTest(fn: SearchParamsGetter): void {
getter = fn;
}
export function __resetSearchParamsGetter(): void {
getter = (): URLSearchParams => new URLSearchParams(window.location.search);
}

View File

@@ -8,8 +8,10 @@
border-color: var(--l1-border);
margin: 0;
}
.dropdown-icon {
margin-right: 4px;
.dropdown-trigger-wrapper {
display: flex;
justify-content: center;
align-items: center;
}
}
.dropdown-menu {

View File

@@ -1,6 +1,8 @@
import { useCallback, useEffect, useState } from 'react';
import { Color } from '@signozhq/design-tokens';
import { Divider, Dropdown, MenuProps, Switch, Tooltip } from 'antd';
import { Button, Divider, Tooltip } from 'antd';
import { DropdownMenuSimple, type MenuItem } from '@signozhq/ui/dropdown-menu';
import { Switch } from '@signozhq/ui/switch';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { Copy, Ellipsis, PenLine, Trash2 } from '@signozhq/icons';
import {
@@ -11,7 +13,6 @@ import {
} from 'pages/AlertDetails/hooks';
import CopyToClipboard from 'periscope/components/CopyToClipboard';
import { useAlertRule } from 'providers/Alert';
import { CSSProperties } from 'styled-components';
import { NEW_ALERT_SCHEMA_VERSION } from 'types/api/alerts/alertTypesV2';
import { AlertDef } from 'types/api/alerts/def';
@@ -20,16 +21,6 @@ import RenameModal from './RenameModal';
import './ActionButtons.styles.scss';
const menuItemStyle: CSSProperties = {
fontSize: '14px',
letterSpacing: '0.14px',
};
const menuItemStyleV2: CSSProperties = {
fontSize: '13px',
letterSpacing: '0.13px',
};
function AlertActionButtons({
ruleId,
alertDetails,
@@ -67,9 +58,7 @@ function AlertActionButtons({
const isV2Alert = alertDetails.schemaVersion === NEW_ALERT_SCHEMA_VERSION;
const finalMenuItemStyle = isV2Alert ? menuItemStyleV2 : menuItemStyle;
const menuItems: MenuProps['items'] = [
const menuItems: MenuItem[] = [
...(!isV2Alert
? [
{
@@ -77,7 +66,6 @@ function AlertActionButtons({
label: 'Rename',
icon: <PenLine size={16} color={Color.BG_VANILLA_400} />,
onClick: handleRename,
style: finalMenuItemStyle,
},
]
: []),
@@ -86,17 +74,13 @@ function AlertActionButtons({
label: 'Duplicate',
icon: <Copy size={16} color={Color.BG_VANILLA_400} />,
onClick: handleAlertDuplicate,
style: finalMenuItemStyle,
},
{
key: 'delete-rule',
label: 'Delete',
icon: <Trash2 size={16} color={Color.BG_CHERRY_400} />,
onClick: handleAlertDelete,
style: {
...finalMenuItemStyle,
color: Color.BG_CHERRY_400,
},
danger: true,
},
];
@@ -132,27 +116,28 @@ function AlertActionButtons({
<div className="alert-action-buttons">
<Tooltip title={isAlertRuleDisabled ? 'Enable alert' : 'Disable alert'}>
{isAlertRuleDisabled !== undefined && (
<Switch
size="small"
onChange={toggleAlertRule}
checked={!isAlertRuleDisabled}
/>
<Switch onChange={toggleAlertRule} value={!isAlertRuleDisabled} />
)}
</Tooltip>
<CopyToClipboard textToCopy={window.location.href} />
<Divider type="vertical" />
<Dropdown trigger={['click']} menu={{ items: menuItems }}>
<Tooltip title="More options">
<Ellipsis
size={16}
color={isDarkMode ? Color.BG_VANILLA_400 : Color.BG_INK_400}
cursor="pointer"
className="dropdown-icon"
/>
</Tooltip>
</Dropdown>
<DropdownMenuSimple menu={{ items: menuItems }}>
<span className="dropdown-trigger-wrapper">
<Tooltip title="More options">
<Button
type="text"
icon={
<Ellipsis
size={16}
color={isDarkMode ? Color.BG_VANILLA_400 : Color.BG_INK_400}
/>
}
/>
</Tooltip>
</span>
</DropdownMenuSimple>
</div>
<RenameModal

View File

@@ -1,14 +1,7 @@
import { useMemo, useState } from 'react';
import {
Button,
Divider,
Dropdown,
Form,
MenuProps,
Space,
Switch,
Tooltip,
} from 'antd';
import { Button, Divider, Form, Space, Tooltip } from 'antd';
import { DropdownMenuSimple, type MenuItem } from '@signozhq/ui/dropdown-menu';
import { Switch } from '@signozhq/ui/switch';
import cx from 'classnames';
import { FilterSelect } from 'components/CeleryOverview/CeleryOverviewConfigOptions/CeleryOverviewConfigOptions';
import { QueryParams } from 'constants/query';
@@ -44,16 +37,22 @@ function FunnelStep({
const [isAddDetailsModalOpen, setIsAddDetailsModalOpen] =
useState<boolean>(false);
const latencyPointerItems: MenuProps['items'] = LatencyPointers.map(
(option) => ({
key: option.value,
label: option.key,
style:
option.value === stepData.latency_pointer
? { backgroundColor: 'var(--bg-slate-100)' }
: {},
}),
);
const latencyPointerItems: MenuItem[] = [
{
type: 'radio-group',
value: stepData.latency_pointer,
onChange: (value): void =>
onStepChange(index, {
latency_pointer: value as FunnelStepData['latency_pointer'],
}),
children: LatencyPointers.map((option) => ({
type: 'radio',
key: option.value,
label: option.key,
value: option.value,
})),
},
];
const updatedCurrentQuery = useMemo(
() => ({
@@ -201,8 +200,7 @@ function FunnelStep({
<div className="error">
<Switch
className="error__switch"
size="small"
checked={stepData.has_errors}
value={stepData.has_errors}
disabled={!hasEditPermission}
onChange={(): void =>
onStepChange(index, { has_errors: !stepData.has_errors })
@@ -212,17 +210,18 @@ function FunnelStep({
</div>
<div className="latency-pointer">
<div className="latency-pointer__label">Latency pointer</div>
<Dropdown
menu={{
items: latencyPointerItems,
onClick: ({ key }): void =>
onStepChange(index, {
latency_pointer: key as FunnelStepData['latency_pointer'],
}),
}}
trigger={['click']}
disabled={!hasEditPermission}
>
{hasEditPermission ? (
<DropdownMenuSimple menu={{ items: latencyPointerItems }}>
<Space>
{
LatencyPointers.find(
(option) => option.value === stepData.latency_pointer,
)?.key
}
<ChevronDown size={14} color="var(--bg-vanilla-400)" />
</Space>
</DropdownMenuSimple>
) : (
<Space>
{
LatencyPointers.find(
@@ -231,7 +230,7 @@ function FunnelStep({
}
<ChevronDown size={14} color="var(--bg-vanilla-400)" />
</Space>
</Dropdown>
)}
</div>
</div>
</Form>

View File

@@ -1,7 +1,7 @@
import { useState } from 'react';
import MEditor, { EditorProps, Monaco } from '@monaco-editor/react';
import { Color } from '@signozhq/design-tokens';
import { Switch } from 'antd';
import { Switch } from '@signozhq/ui/switch';
import { Typography } from '@signozhq/ui/typography';
import { useIsDarkMode } from 'hooks/useDarkMode';
@@ -72,9 +72,8 @@ function JsonView({ data, height = '575px' }: JsonViewProps): JSX.Element {
<div className="json-view__wrap-toggle">
<Typography.Text>Wrap text</Typography.Text>
<Switch
checked={isWrapWord}
value={isWrapWord}
onChange={(checked): void => setIsWrapWord(checked)}
size="small"
/>
</div>
</div>

View File

@@ -149,7 +149,6 @@ func paginateWithBackfill(
groupBy []qbtypes.GroupByKey,
offset, limit int,
) []map[string]string {
metricKeySet := make(map[string]bool, len(metricGroups))
for _, g := range metricGroups {
metricKeySet[g.compositeKey] = true
@@ -164,7 +163,7 @@ func paginateWithBackfill(
sort.Strings(metadataOnlyKeys)
totalMetric := len(metricGroups)
totalAll := len(metadataMap)
totalAll := totalMetric + len(metadataOnlyKeys)
end := offset + limit
if end > totalAll {
@@ -308,57 +307,23 @@ func parseFullQueryResponse(
return result
}
// alignedMetricWindow returns step-floored time bounds and the metric tables
// to use for the given window. The floor matches what the QB v5 metric
// querier does internally (see querybuilder.AdjustedMetricTimeRange).
// Please use the samplesAdjustedStartMs with samples table and tsAdjustedStartMs with ts tables.
// Both can use the same flooredEndMs.
func alignedMetricWindow(startMs, endMs int64) (
samplesAdjustedStartMs uint64,
flooredEndMs uint64,
tsAdjustedStartMs uint64,
distributedTSTable string,
localTSTable string,
distributedSamplesTable string,
localSamplesTable string,
) {
samplesAdjustedStartMs = uint64(startMs)
flooredEndMs = uint64(endMs)
stepSecs := querybuilder.RecommendedStepIntervalForMetric(samplesAdjustedStartMs, flooredEndMs)
// note: this is the same flooring logic as in querybuilder.AdjustedMetricTimeRange
if stepSecs > 0 {
samplesAdjustedStartMs = samplesAdjustedStartMs - (samplesAdjustedStartMs % (stepSecs * 1000))
adjustStep := stepSecs
if adjustStep > 60 {
adjustStep = 60
}
flooredEndMs = flooredEndMs - (flooredEndMs % (adjustStep * 1000))
}
tsAdjustedStartMs, _, distributedTSTable, localTSTable = telemetrymetrics.WhichTSTableToUse(
samplesAdjustedStartMs, flooredEndMs, nil,
)
distributedSamplesTable = telemetrymetrics.WhichSamplesTableToUse(
samplesAdjustedStartMs, flooredEndMs,
metrictypes.UnspecifiedType, metrictypes.TimeAggregationUnspecified, nil,
)
localSamplesTable = strings.TrimPrefix(distributedSamplesTable, "distributed_")
return
}
// buildSamplesTblFingerprintSubQuery returns a SelectBuilder that selects distinct fingerprints
// from the samples table for the given metric names and time range.
// Bounds must already be step-floored by the caller via alignedMetricWindow.
func (m *module) buildSamplesTblFingerprintSubQuery(metricNames []string, samplesTable string, flooredStart, flooredEnd uint64) *sqlbuilder.SelectBuilder {
// from the samples table for the given metric names andtime range.
func (m *module) buildSamplesTblFingerprintSubQuery(metricNames []string, startMs, endMs int64) *sqlbuilder.SelectBuilder {
samplesTableName := telemetrymetrics.WhichSamplesTableToUse(
uint64(startMs), uint64(endMs),
metrictypes.UnspecifiedType,
metrictypes.TimeAggregationUnspecified,
nil,
)
localSamplesTable := strings.TrimPrefix(samplesTableName, "distributed_")
fpSB := sqlbuilder.NewSelectBuilder()
fpSB.Select("DISTINCT fingerprint")
fpSB.From(fmt.Sprintf("%s.%s", telemetrymetrics.DBName, samplesTable))
fpSB.From(fmt.Sprintf("%s.%s", telemetrymetrics.DBName, localSamplesTable))
fpSB.Where(
fpSB.In("metric_name", sqlbuilder.List(metricNames)),
fpSB.GE("unix_milli", flooredStart),
fpSB.L("unix_milli", flooredEnd),
fpSB.GE("unix_milli", startMs),
fpSB.L("unix_milli", endMs),
)
return fpSB
}
@@ -489,12 +454,12 @@ func (m *module) getMetadata(
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "groupBy must not be empty")
}
// Step-floor the window and pick the right tables — matches the bounds the
// QB v5 metric querier uses, so metadataMap covers the same universe the
// ranking sees (see alignedMetricWindow doc).
samplesStartMs, flooredEndMs, tsAdjustedStartMs, distributedTableName, _, _, localSamplesTable := alignedMetricWindow(startMs, endMs)
// Pick the optimal timeseries table based on time range; also get adjusted start.
adjustedStart, adjustedEnd, distributedTableName, _ := telemetrymetrics.WhichTSTableToUse(
uint64(startMs), uint64(endMs), nil,
)
fpSB := m.buildSamplesTblFingerprintSubQuery(metricNames, localSamplesTable, samplesStartMs, flooredEndMs)
fpSB := m.buildSamplesTblFingerprintSubQuery(metricNames, startMs, endMs)
// Flatten groupBy keys to string names for SQL expressions and result scanning.
groupByCols := make([]string, len(groupBy))
@@ -529,8 +494,8 @@ func (m *module) getMetadata(
innerSB.From(fmt.Sprintf("%s.%s", telemetrymetrics.DBName, distributedTableName))
innerSB.Where(
innerSB.In("metric_name", sqlbuilder.List(metricNames)),
innerSB.GE("unix_milli", tsAdjustedStartMs),
innerSB.LE("unix_milli", flooredEndMs),
innerSB.GE("unix_milli", adjustedStart),
innerSB.L("unix_milli", adjustedEnd),
fmt.Sprintf("fingerprint IN (%s)", innerSB.Var(fpSB)),
)

View File

@@ -34,8 +34,9 @@ func (m *module) getPerGroupHostStatusCounts(
pageGroupsFilterExpr := buildPageGroupsFilterExpr(pageGroups)
filterExpr := mergeFilterExpressions(reqFilterExpr, pageGroupsFilterExpr)
// Step-floor bounds + resolve tables in one shot to match QB v5 querier.
samplesStartMs, flooredEndMs, tsAdjustedStartMs, distributedTimeSeriesTableName, _, _, localSamplesTable := alignedMetricWindow(req.Start, req.End)
adjustedStart, adjustedEnd, distributedTimeSeriesTableName, _ := telemetrymetrics.WhichTSTableToUse(
uint64(req.Start), uint64(req.End), nil,
)
hostNameExpr := fmt.Sprintf("JSONExtractString(labels, '%s')", inframonitoringtypes.HostNameAttrKey)
@@ -54,15 +55,15 @@ func (m *module) getPerGroupHostStatusCounts(
)
// Build a fingerprint subquery to restrict to fingerprints with actual sample
// data in the floored time range.
fpSB := m.buildSamplesTblFingerprintSubQuery(metricNames, localSamplesTable, samplesStartMs, flooredEndMs)
// data in the original time range (not the wider timeseries table window).
fpSB := m.buildSamplesTblFingerprintSubQuery(metricNames, req.Start, req.End)
sb.Select(selectCols...)
sb.From(fmt.Sprintf("%s.%s", telemetrymetrics.DBName, distributedTimeSeriesTableName))
sb.Where(
sb.In("metric_name", sqlbuilder.List(metricNames)),
sb.GE("unix_milli", tsAdjustedStartMs),
sb.LE("unix_milli", flooredEndMs),
sb.GE("unix_milli", adjustedStart),
sb.L("unix_milli", adjustedEnd),
fmt.Sprintf("fingerprint IN (%s)", sb.Var(fpSB)),
)

View File

@@ -9,6 +9,7 @@ import (
"github.com/SigNoz/signoz/pkg/querybuilder"
"github.com/SigNoz/signoz/pkg/telemetrymetrics"
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
"github.com/SigNoz/signoz/pkg/types/metrictypes"
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/huandu/go-sqlbuilder"
@@ -189,9 +190,15 @@ func (m *module) getPerGroupNodeConditionCounts(
pageGroupsFilterExpr := buildPageGroupsFilterExpr(pageGroups)
mergedFilterExpr := mergeFilterExpressions(userFilterExpr, pageGroupsFilterExpr)
// Step-floor bounds + resolve tables in one shot to match QB v5 querier.
samplesStartMs, flooredEndMs, tsAdjustedStartMs, _, localTimeSeriesTable, distributedSamplesTable, _ := alignedMetricWindow(start, end)
valueCol := telemetrymetrics.ValueColumnForSamplesTable(distributedSamplesTable)
// Resolve tables. Same convention as pods.
adjustedStart, adjustedEnd, _, localTimeSeriesTable := telemetrymetrics.WhichTSTableToUse(
uint64(start), uint64(end), nil,
)
samplesTable := telemetrymetrics.WhichSamplesTableToUse(
uint64(start), uint64(end),
metrictypes.UnspecifiedType, metrictypes.TimeAggregationUnspecified, nil,
)
valueCol := telemetrymetrics.ValueColumnForSamplesTable(samplesTable)
// ----- timeSeriesFPs -----
timeSeriesFPs := sqlbuilder.NewSelectBuilder()
@@ -208,8 +215,8 @@ func (m *module) getPerGroupNodeConditionCounts(
timeSeriesFPs.From(fmt.Sprintf("%s.%s", telemetrymetrics.DBName, localTimeSeriesTable))
timeSeriesFPs.Where(
timeSeriesFPs.E("metric_name", nodeConditionMetricName),
timeSeriesFPs.GE("unix_milli", tsAdjustedStartMs),
timeSeriesFPs.LE("unix_milli", flooredEndMs),
timeSeriesFPs.GE("unix_milli", adjustedStart),
timeSeriesFPs.L("unix_milli", adjustedEnd),
)
if mergedFilterExpr != "" {
filterClause, err := m.buildFilterClause(ctx, &qbtypes.Filter{Expression: mergedFilterExpr}, start, end)
@@ -242,12 +249,12 @@ func (m *module) getPerGroupNodeConditionCounts(
latestConditionPerNode.Select(latestConditionPerNodeSelectCols...)
latestConditionPerNode.From(fmt.Sprintf(
"%s.%s AS samples INNER JOIN time_series_fps AS tsfp ON samples.fingerprint = tsfp.fingerprint",
telemetrymetrics.DBName, distributedSamplesTable,
telemetrymetrics.DBName, samplesTable,
))
latestConditionPerNode.Where(
latestConditionPerNode.E("samples.metric_name", nodeConditionMetricName),
latestConditionPerNode.GE("samples.unix_milli", samplesStartMs),
latestConditionPerNode.L("samples.unix_milli", flooredEndMs),
latestConditionPerNode.GE("samples.unix_milli", start),
latestConditionPerNode.L("samples.unix_milli", end),
"tsfp.node_name != ''",
)
latestConditionPerNode.GroupBy(latestConditionPerNodeGroupBy...)

View File

@@ -10,6 +10,7 @@ import (
"github.com/SigNoz/signoz/pkg/querybuilder"
"github.com/SigNoz/signoz/pkg/telemetrymetrics"
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
"github.com/SigNoz/signoz/pkg/types/metrictypes"
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/huandu/go-sqlbuilder"
@@ -208,9 +209,15 @@ func (m *module) getPerGroupPodPhaseCounts(
pageGroupsFilterExpr := buildPageGroupsFilterExpr(pageGroups)
mergedFilterExpr := mergeFilterExpressions(userFilterExpr, pageGroupsFilterExpr)
// Step-floor bounds + resolve tables in one shot to match QB v5 querier.
samplesStartMs, flooredEndMs, tsAdjustedStart, _, localTimeSeriesTable, distributedSamplesTable, _ := alignedMetricWindow(start, end)
valueCol := telemetrymetrics.ValueColumnForSamplesTable(distributedSamplesTable)
// Resolve tables. Same convention as hosts (distributed names from helpers).
adjustedStart, adjustedEnd, _, localTimeSeriesTable := telemetrymetrics.WhichTSTableToUse(
uint64(start), uint64(end), nil,
)
samplesTable := telemetrymetrics.WhichSamplesTableToUse(
uint64(start), uint64(end),
metrictypes.UnspecifiedType, metrictypes.TimeAggregationUnspecified, nil,
)
valueCol := telemetrymetrics.ValueColumnForSamplesTable(samplesTable)
// ----- timeSeriesFPs -----
timeSeriesFPs := sqlbuilder.NewSelectBuilder()
@@ -227,8 +234,8 @@ func (m *module) getPerGroupPodPhaseCounts(
timeSeriesFPs.From(fmt.Sprintf("%s.%s", telemetrymetrics.DBName, localTimeSeriesTable))
timeSeriesFPs.Where(
timeSeriesFPs.E("metric_name", podPhaseMetricName),
timeSeriesFPs.GE("unix_milli", tsAdjustedStart),
timeSeriesFPs.LE("unix_milli", flooredEndMs),
timeSeriesFPs.GE("unix_milli", adjustedStart),
timeSeriesFPs.L("unix_milli", adjustedEnd),
)
if mergedFilterExpr != "" {
filterClause, err := m.buildFilterClause(ctx, &qbtypes.Filter{Expression: mergedFilterExpr}, start, end)
@@ -260,12 +267,12 @@ func (m *module) getPerGroupPodPhaseCounts(
latestPhasePerPod.Select(latestPhasePerPodSelectCols...)
latestPhasePerPod.From(fmt.Sprintf(
"%s.%s AS samples INNER JOIN time_series_fps AS tsfp ON samples.fingerprint = tsfp.fingerprint",
telemetrymetrics.DBName, distributedSamplesTable,
telemetrymetrics.DBName, samplesTable,
))
latestPhasePerPod.Where(
latestPhasePerPod.E("samples.metric_name", podPhaseMetricName),
latestPhasePerPod.GE("samples.unix_milli", samplesStartMs),
latestPhasePerPod.L("samples.unix_milli", flooredEndMs),
latestPhasePerPod.GE("samples.unix_milli", start),
latestPhasePerPod.L("samples.unix_milli", end),
"tsfp.pod_uid != ''",
)
latestPhasePerPod.GroupBy(latestPhasePerPodGroupBy...)

View File

@@ -7,8 +7,6 @@ import (
"strings"
"unicode"
"github.com/SigNoz/signoz/pkg/query-service/constants"
"encoding/base64"
"encoding/json"
"fmt"
@@ -178,27 +176,6 @@ func HydrateFileUris(spec interface{}, fs embed.FS, basedir string) (interface{}
if specMap, ok := spec.(map[string]interface{}); ok {
result := map[string]interface{}{}
for k, v := range specMap {
// Check if this is a dashboards slice and if dot metrics are enabled
if k == "dashboards" && constants.IsDotMetricsEnabled {
if dashboards, ok := v.([]interface{}); ok {
for i, dashboard := range dashboards {
if dashboardUri, ok := dashboard.(string); ok {
if strings.HasPrefix(dashboardUri, "file://") {
dashboards[i] = strings.Replace(dashboardUri, ".json", "_dot.json", 1)
}
} else if dashBoardMap, ok := dashboard.(map[string]interface{}); ok {
if dashboardUri, ok := dashBoardMap["definition"].(string); ok {
if strings.HasPrefix(dashboardUri, "file://") {
dashboardUri = strings.Replace(dashboardUri, ".json", "_dot.json", 1)
}
dashBoardMap["definition"] = dashboardUri
}
dashboards[i] = dashBoardMap
}
}
v = dashboards
}
}
hydrated, err := HydrateFileUris(v, fs, basedir)
if err != nil {
return nil, err

View File

@@ -367,9 +367,9 @@
"id": "31d3f13b-27d5-4291-9fb3-d5d5708a72f3",
"modificationUUID": "e4a9edf1-acd0-48b7-8a35-1b4bb668408d",
"multiSelect": false,
"name": "mysql_instance_endpoint",
"name": "mysql.instance.endpoint",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'mysql_instance_endpoint') as mysql_instance_endpoint\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'mysql_uptime'\nGROUP BY mysql_instance_endpoint",
"queryValue": "SELECT JSONExtractString(labels, 'mysql.instance.endpoint') as `mysql.instance.endpoint`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'mysql.uptime'\nGROUP BY `mysql.instance.endpoint`",
"selectedValue": "",
"showALLOption": false,
"sort": "ASC",
@@ -393,7 +393,7 @@
{
"aggregations": [
{
"metricName": "mysql_buffer_pool_usage",
"metricName": "mysql.buffer_pool.pages",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": null,
@@ -404,7 +404,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -529,7 +529,7 @@
{
"aggregations": [
{
"metricName": "mysql_buffer_pool_pages",
"metricName": "mysql.buffer_pool.pages",
"reduceTo": "avg",
"spaceAggregation": "sum",
"temporality": null,
@@ -540,7 +540,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -658,7 +658,7 @@
{
"aggregations": [
{
"metricName": "mysql_buffer_pool_data_pages",
"metricName": "mysql.buffer_pool.data_pages",
"reduceTo": "avg",
"spaceAggregation": "sum",
"temporality": null,
@@ -669,7 +669,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -788,7 +788,7 @@
{
"aggregations": [
{
"metricName": "mysql_buffer_pool_page_flushes",
"metricName": "mysql.buffer_pool.page_flushes",
"reduceTo": "avg",
"spaceAggregation": "sum",
"temporality": null,
@@ -799,7 +799,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [],
@@ -915,7 +915,7 @@
{
"aggregations": [
{
"metricName": "mysql_table_io_wait_count",
"metricName": "mysql.table.io.wait.count",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -926,7 +926,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -1045,7 +1045,7 @@
{
"aggregations": [
{
"metricName": "mysql_table_io_wait_count",
"metricName": "mysql.table.io.wait.count",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -1056,7 +1056,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -1175,7 +1175,7 @@
{
"aggregations": [
{
"metricName": "mysql_table_io_wait_count",
"metricName": "mysql.table.io.wait.count",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -1186,7 +1186,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -1305,7 +1305,7 @@
{
"aggregations": [
{
"metricName": "mysql_handlers",
"metricName": "mysql.handlers",
"reduceTo": "avg",
"spaceAggregation": "sum",
"temporality": null,
@@ -1316,7 +1316,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -1329,7 +1329,7 @@
}
],
"having": {
"expression": "sum(mysql_handlers) \u003e 0"
"expression": "sum(mysql.handlers) \u003e 0"
},
"legend": "{{kind}}",
"limit": null,
@@ -1434,7 +1434,7 @@
{
"aggregations": [
{
"metricName": "mysql_locks",
"metricName": "mysql.locks",
"reduceTo": "avg",
"spaceAggregation": "sum",
"temporality": null,
@@ -1445,7 +1445,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -1563,7 +1563,7 @@
{
"aggregations": [
{
"metricName": "mysql_log_operations",
"metricName": "mysql.log_operations",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -1574,7 +1574,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -1693,7 +1693,7 @@
{
"aggregations": [
{
"metricName": "mysql_connection_count",
"metricName": "mysql.connection.count",
"reduceTo": "avg",
"spaceAggregation": "sum",
"temporality": null,
@@ -1704,7 +1704,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [],
@@ -1720,7 +1720,7 @@
{
"aggregations": [
{
"metricName": "mysql_connection_errors",
"metricName": "mysql.connection.errors",
"reduceTo": "avg",
"spaceAggregation": "sum",
"temporality": null,
@@ -1731,7 +1731,7 @@
"disabled": false,
"expression": "B",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -1745,7 +1745,7 @@
}
],
"having": {
"expression": "sum(mysql_connection_errors) \u003e 0"
"expression": "sum(mysql.connection.errors) \u003e 0"
},
"legend": "Error count: {{error}}",
"limit": null,
@@ -1850,7 +1850,7 @@
{
"aggregations": [
{
"metricName": "mysql_opened_resources",
"metricName": "mysql.opened_resources",
"reduceTo": "avg",
"spaceAggregation": "sum",
"temporality": null,
@@ -1861,7 +1861,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -1874,7 +1874,7 @@
}
],
"having": {
"expression": "sum(mysql_opened_resources) \u003e 0"
"expression": "sum(mysql.opened_resources) \u003e 0"
},
"legend": "{{kind}}",
"limit": null,
@@ -1979,7 +1979,7 @@
{
"aggregations": [
{
"metricName": "mysql_operations",
"metricName": "mysql.operations",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -1990,7 +1990,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -2109,7 +2109,7 @@
{
"aggregations": [
{
"metricName": "mysql_row_locks",
"metricName": "mysql.row_locks",
"reduceTo": "avg",
"spaceAggregation": "sum",
"temporality": null,
@@ -2120,7 +2120,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -2238,7 +2238,7 @@
{
"aggregations": [
{
"metricName": "mysql_threads",
"metricName": "mysql.threads",
"reduceTo": "avg",
"spaceAggregation": "sum",
"temporality": null,
@@ -2249,7 +2249,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -2367,7 +2367,7 @@
{
"aggregations": [
{
"metricName": "mysql_row_operations",
"metricName": "mysql.row_operations",
"reduceTo": "avg",
"spaceAggregation": "sum",
"temporality": null,
@@ -2378,7 +2378,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [
@@ -2497,7 +2497,7 @@
{
"aggregations": [
{
"metricName": "mysql_prepared_statements",
"metricName": "mysql.prepared_statements",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -2508,7 +2508,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "mysql_instance_endpoint = $mysql_instance_endpoint"
"expression": "mysql.instance.endpoint = $mysql.instance.endpoint"
},
"functions": [],
"groupBy": [

View File

@@ -287,7 +287,7 @@
"multiSelect": true,
"name": "table_name",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'postgresql_table_name') AS table_name\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'postgresql_operations' AND JSONExtractString(labels, 'postgresql_database_name') IN {{.db_name}}\nGROUP BY table_name",
"queryValue": "SELECT JSONExtractString(labels, 'postgresql.table.name') AS table_name\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'postgresql.operations' AND JSONExtractString(labels, 'postgresql.database.name') IN {{.db_name}}\nGROUP BY table_name",
"selectedValue": [
"public.pgbench_accounts",
"public.pgbench_branches",
@@ -309,7 +309,7 @@
"multiSelect": true,
"name": "db_name",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'postgresql_database_name') AS db_name\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'postgresql_operations'\nGROUP BY db_name",
"queryValue": "SELECT JSONExtractString(labels, 'postgresql.database.name') AS db_name\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'postgresql.operations'\nGROUP BY db_name",
"selectedValue": [
"pgtestdb"
],
@@ -335,7 +335,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
@@ -346,22 +346,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(operation = 'ins' AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'ins' AND postgresql.database.name IN $db_name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_database_name}}",
"legend": "{{postgresql.database.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -410,7 +410,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
@@ -421,22 +421,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(operation = 'upd' AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'upd' AND postgresql.database.name IN $db_name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_database_name}}",
"legend": "{{postgresql.database.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -485,7 +485,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
@@ -496,22 +496,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(operation = 'del' AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'del' AND postgresql.database.name IN $db_name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_database_name}}",
"legend": "{{postgresql.database.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -560,7 +560,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
@@ -571,22 +571,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(operation = 'hot_upd' AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'hot_upd' AND postgresql.database.name IN $db_name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_database_name}}",
"legend": "{{postgresql.database.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -635,7 +635,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": null,
@@ -646,15 +646,15 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(operation = 'ins' AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'ins' AND postgresql.database.name IN $db_name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
@@ -670,7 +670,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": null,
@@ -681,15 +681,15 @@
"disabled": false,
"expression": "B",
"filter": {
"expression": "(operation = 'upd' AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'upd' AND postgresql.database.name IN $db_name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
@@ -705,7 +705,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": null,
@@ -716,15 +716,15 @@
"disabled": false,
"expression": "C",
"filter": {
"expression": "(operation = 'del' AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'del' AND postgresql.database.name IN $db_name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
@@ -780,7 +780,7 @@
{
"aggregations": [
{
"metricName": "postgresql_database_locks",
"metricName": "postgresql.database.locks",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -852,7 +852,7 @@
{
"aggregations": [
{
"metricName": "postgresql_deadlocks",
"metricName": "postgresql.deadlocks",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -863,22 +863,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "postgresql_database_name IN $db_name"
"expression": "postgresql.database.name IN $db_name"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_database_name}}",
"legend": "{{postgresql.database.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -927,7 +927,7 @@
{
"aggregations": [
{
"metricName": "postgresql_backends",
"metricName": "postgresql.backends",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
@@ -938,22 +938,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "postgresql_database_name IN $db_name"
"expression": "postgresql.database.name IN $db_name"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_database_name}}",
"legend": "{{postgresql.database.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -1002,7 +1002,7 @@
{
"aggregations": [
{
"metricName": "postgresql_rows",
"metricName": "postgresql.rows",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -1013,7 +1013,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(state = 'dead' AND postgresql_database_name IN $db_name AND postgresql_table_name IN $table_name)"
"expression": "(state = 'dead' AND postgresql.database.name IN $db_name AND postgresql.table.name IN $table_name)"
},
"groupBy": [],
"having": {
@@ -1068,7 +1068,7 @@
{
"aggregations": [
{
"metricName": "postgresql_index_scans",
"metricName": "postgresql.index.scans",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -1079,22 +1079,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(postgresql_database_name IN $db_name AND postgresql_table_name IN $table_name)"
"expression": "(postgresql.database.name IN $db_name AND postgresql.table.name IN $table_name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_index_name--string--tag--false",
"id": "postgresql.index.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_index_name",
"key": "postgresql.index.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_index_name}}",
"legend": "{{postgresql.index.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -1143,7 +1143,7 @@
{
"aggregations": [
{
"metricName": "postgresql_rows",
"metricName": "postgresql.rows",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": null,
@@ -1154,16 +1154,16 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(state = 'dead' AND postgresql_database_name IN $db_name AND postgresql_table_name IN $table_name)"
"expression": "(state = 'dead' AND postgresql.database.name IN $db_name AND postgresql.table.name IN $table_name)"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "postgresql_table_name--string--tag--false",
"id": "postgresql.table.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_table_name",
"key": "postgresql.table.name",
"type": "tag"
}
],
@@ -1179,7 +1179,7 @@
{
"aggregations": [
{
"metricName": "postgresql_rows",
"metricName": "postgresql.rows",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": null,
@@ -1190,16 +1190,16 @@
"disabled": false,
"expression": "B",
"filter": {
"expression": "(state = 'live' AND postgresql_database_name IN $db_name AND postgresql_table_name IN $table_name)"
"expression": "(state = 'live' AND postgresql.database.name IN $db_name AND postgresql.table.name IN $table_name)"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "postgresql_table_name--string--tag--false",
"id": "postgresql.table.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_table_name",
"key": "postgresql.table.name",
"type": "tag"
}
],
@@ -1215,7 +1215,7 @@
{
"aggregations": [
{
"metricName": "postgresql_index_scans",
"metricName": "postgresql.index.scans",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -1226,16 +1226,16 @@
"disabled": false,
"expression": "C",
"filter": {
"expression": "(postgresql_database_name IN $db_name AND postgresql_table_name IN $table_name)"
"expression": "(postgresql.database.name IN $db_name AND postgresql.table.name IN $table_name)"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "postgresql_table_name--string--tag--false",
"id": "postgresql.table.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_table_name",
"key": "postgresql.table.name",
"type": "tag"
}
],
@@ -1251,7 +1251,7 @@
{
"aggregations": [
{
"metricName": "postgresql_table_size",
"metricName": "postgresql.table.size",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": null,
@@ -1262,16 +1262,16 @@
"disabled": true,
"expression": "D",
"filter": {
"expression": "(postgresql_database_name IN $db_name AND postgresql_table_name IN $table_name)"
"expression": "(postgresql.database.name IN $db_name AND postgresql.table.name IN $table_name)"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "postgresql_table_name--string--tag--false",
"id": "postgresql.table.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_table_name",
"key": "postgresql.table.name",
"type": "tag"
}
],

View File

@@ -80,9 +80,9 @@
"id": "a2c21714-a814-4d31-9b56-7367c3208801",
"modificationUUID": "448e675a-4531-45b1-b434-a9ee809470d6",
"multiSelect": true,
"name": "host_name",
"name": "host.name",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'host_name') AS host_name\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'mongodb_memory_usage'\nGROUP BY host_name",
"queryValue": "SELECT JSONExtractString(labels, 'host.name') AS `host.name`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'mongodb_memory_usage'\nGROUP BY `host.name`",
"selectedValue": [
"Srikanths-MacBook-Pro.local"
],
@@ -108,7 +108,7 @@
{
"aggregations": [
{
"metricName": "mongodb_operation_count",
"metricName": "mongodb.operation.count",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -119,7 +119,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [
{
@@ -183,7 +183,7 @@
{
"aggregations": [
{
"metricName": "mongodb_operation_time",
"metricName": "mongodb.operation.time",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -194,7 +194,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [
{
@@ -258,7 +258,7 @@
{
"aggregations": [
{
"metricName": "mongodb_cache_operations",
"metricName": "mongodb.cache.operations",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -269,7 +269,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [
{
@@ -333,7 +333,7 @@
{
"aggregations": [
{
"metricName": "mongodb_operation_latency_time",
"metricName": "mongodb.operation.latency.time",
"reduceTo": "sum",
"spaceAggregation": "max",
"temporality": null,
@@ -344,7 +344,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(operation = 'read' AND host_name IN $host_name)"
"expression": "(operation = 'read' AND host.name IN $host.name)"
},
"groupBy": [],
"having": {
@@ -399,7 +399,7 @@
{
"aggregations": [
{
"metricName": "mongodb_operation_latency_time",
"metricName": "mongodb.operation.latency.time",
"reduceTo": "sum",
"spaceAggregation": "max",
"temporality": null,
@@ -410,7 +410,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(host_name IN $host_name AND operation = 'write')"
"expression": "(host.name IN $host.name AND operation = 'write')"
},
"groupBy": [],
"having": {
@@ -465,7 +465,7 @@
{
"aggregations": [
{
"metricName": "mongodb_operation_latency_time",
"metricName": "mongodb.operation.latency.time",
"reduceTo": "sum",
"spaceAggregation": "max",
"temporality": null,
@@ -476,7 +476,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(host_name IN $host_name AND operation = 'command')"
"expression": "(host.name IN $host.name AND operation = 'command')"
},
"groupBy": [],
"having": {
@@ -531,7 +531,7 @@
{
"aggregations": [
{
"metricName": "mongodb_network_io_receive",
"metricName": "mongodb.network.io.receive",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
@@ -542,22 +542,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host_name--string--tag--false",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host_name",
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Bytes received :: {{host_name}}",
"legend": "Bytes received :: {{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -566,7 +566,7 @@
{
"aggregations": [
{
"metricName": "mongodb_network_io_transmit",
"metricName": "mongodb.network.io.transmit",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
@@ -577,22 +577,22 @@
"disabled": false,
"expression": "B",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host_name--string--tag--false",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host_name",
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Bytes transmitted :: {{host_name}}",
"legend": "Bytes transmitted :: {{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "B",

View File

@@ -1,631 +0,0 @@
{
"description": "This dashboard provides a high-level overview of your MongoDB. It includes read/write performance, most-used replicas, collection metrics etc...",
"id": "mongo-overview",
"layout": [
{
"h": 3,
"i": "0c3d2b15-89be-4d62-a821-b26d93332ed3",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 3
},
{
"h": 3,
"i": "14504a3c-4a05-4d22-bab3-e22e94f51380",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 6
},
{
"h": 3,
"i": "dcfb3829-c3f2-44bb-907d-8dc8a6dc4aab",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 3
},
{
"h": 3,
"i": "bfc9e80b-02bf-4122-b3da-3dd943d35012",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 0
},
{
"h": 3,
"i": "4c07a7d2-893a-46c2-bcdb-a19b6efeac3a",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 0
},
{
"h": 3,
"i": "a5a64eec-1034-4aa6-8cb1-05673c4426c6",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 6
},
{
"h": 3,
"i": "503af589-ef4d-4fe3-8934-c8f7eb480d9a",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 9
}
],
"name": "",
"tags": [
"mongo",
"database"
],
"title": "Mongo overview",
"variables": {
"a2c21714-a814-4d31-9b56-7367c3208801": {
"allSelected": true,
"customValue": "",
"description": "List of hosts sending mongo metrics",
"id": "a2c21714-a814-4d31-9b56-7367c3208801",
"modificationUUID": "448e675a-4531-45b1-b434-a9ee809470d6",
"multiSelect": true,
"name": "host.name",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'host.name') AS `host.name`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'mongodb_memory_usage'\nGROUP BY `host.name`",
"selectedValue": [
"Srikanths-MacBook-Pro.local"
],
"showALLOption": true,
"sort": "ASC",
"textboxValue": "",
"type": "QUERY"
}
},
"version": "v5",
"widgets": [
{
"description": "Total number of operations",
"fillSpans": false,
"id": "4c07a7d2-893a-46c2-bcdb-a19b6efeac3a",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "mongodb.operation.count",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
"timeAggregation": "rate"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "operation--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "operation",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{operation}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "7da5d899-8b06-4139-9a89-47baf9551ff8",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Operations count",
"yAxisUnit": "none"
},
{
"description": "The total time spent performing operations.",
"fillSpans": false,
"id": "bfc9e80b-02bf-4122-b3da-3dd943d35012",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "mongodb.operation.time",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
"timeAggregation": "rate"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "operation--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "operation",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{operation}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "2ca35957-894a-46ae-a2a6-95d7e400d8e1",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Total operations time",
"yAxisUnit": "ms"
},
{
"description": "The number of cache operations",
"fillSpans": false,
"id": "dcfb3829-c3f2-44bb-907d-8dc8a6dc4aab",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "mongodb.cache.operations",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
"timeAggregation": "rate"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "type--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "type",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{type}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "bb439198-dcf5-4767-b0d0-ab5785159b8d",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Cache operations",
"yAxisUnit": "none"
},
{
"description": "",
"fillSpans": false,
"id": "14504a3c-4a05-4d22-bab3-e22e94f51380",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "mongodb.operation.latency.time",
"reduceTo": "sum",
"spaceAggregation": "max",
"temporality": null,
"timeAggregation": "max"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(operation = 'read' AND host.name IN $host.name)"
},
"groupBy": [],
"having": {
"expression": ""
},
"legend": "Latency",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "4a9cafe8-778b-476c-b825-c04e165bf285",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Read latency",
"yAxisUnit": "µs"
},
{
"description": "",
"fillSpans": false,
"id": "a5a64eec-1034-4aa6-8cb1-05673c4426c6",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "mongodb.operation.latency.time",
"reduceTo": "sum",
"spaceAggregation": "max",
"temporality": null,
"timeAggregation": "max"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(host.name IN $host.name AND operation = 'write')"
},
"groupBy": [],
"having": {
"expression": ""
},
"legend": "Latency",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "446827eb-a4f2-4ff3-966b-fb65288c983b",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Write latency",
"yAxisUnit": "µs"
},
{
"description": "",
"fillSpans": false,
"id": "503af589-ef4d-4fe3-8934-c8f7eb480d9a",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "mongodb.operation.latency.time",
"reduceTo": "sum",
"spaceAggregation": "max",
"temporality": null,
"timeAggregation": "max"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(host.name IN $host.name AND operation = 'command')"
},
"groupBy": [],
"having": {
"expression": ""
},
"legend": "Latency",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "7b7b977d-0921-4552-8cfe-d82dfde63ef4",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Command latency",
"yAxisUnit": "µs"
},
{
"description": "",
"fillSpans": false,
"id": "0c3d2b15-89be-4d62-a821-b26d93332ed3",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "mongodb.network.io.receive",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
"timeAggregation": "avg"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Bytes received :: {{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
},
{
"aggregations": [
{
"metricName": "mongodb.network.io.transmit",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
"timeAggregation": "avg"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "B",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Bytes transmitted :: {{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "B",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "41eea5bc-f9cf-45c2-92fb-ef226d6b540b",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Network IO",
"yAxisUnit": "bytes"
}
]
}

View File

@@ -117,9 +117,9 @@
"key": "4250ef7b-8f42-4a24-902a-a764d070b92d",
"modificationUUID": "4427b655-c8d2-40ce-84ed-7cb058bd3041",
"multiSelect": true,
"name": "host_name",
"name": "host.name",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'host_name') AS host_name\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'postgresql_operations'\nGROUP BY host_name",
"queryValue": "SELECT JSONExtractString(labels, 'host.name') AS `host.name`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'postgresql.operations'\nGROUP BY `host.name`",
"selectedValue": [
"Srikanths-MacBook-Pro.local"
],
@@ -135,9 +135,9 @@
"id": "8ecaee70-640f-46fd-83d9-a4fd18bc66e6",
"modificationUUID": "a51321cd-47a2-470a-8df4-372e5bb36f2c",
"multiSelect": true,
"name": "table_name",
"name": "table.name",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'postgresql_table_name') AS table_name\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'postgresql_operations' AND JSONExtractString(labels, 'postgresql_database_name') IN {{.db_name}}\nGROUP BY table_name",
"queryValue": "SELECT JSONExtractString(labels, 'postgresql.table.name') AS `table.name`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'postgresql.operations' AND JSONExtractString(labels, 'postgresql.database.name') IN {{.db.name}}\nGROUP BY `table.name`",
"selectedValue": [
"public.activations",
"public.licenses",
@@ -160,9 +160,9 @@
"key": "c66d1581-e5e1-440d-8ff6-ebcf078ab6dd",
"modificationUUID": "564a3f43-98f8-4189-b5e4-dcb518d73852",
"multiSelect": true,
"name": "db_name",
"name": "db.name",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'postgresql_database_name') AS db_name\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'postgresql_operations'\nGROUP BY db_name",
"queryValue": "SELECT JSONExtractString(labels, 'postgresql.database.name') AS `db.name`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'postgresql.operations'\nGROUP BY `db.name`",
"selectedValue": [
"postgres"
],
@@ -188,7 +188,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
@@ -199,22 +199,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(operation = 'ins' AND host_name IN $host_name AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'ins' AND host.name IN $host.name AND postgresql.database.name IN $db.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_database_name}}",
"legend": "{{postgresql.database.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -263,7 +263,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
@@ -274,22 +274,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(operation = 'upd' AND host_name IN $host_name AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'upd' AND host.name IN $host.name AND postgresql.database.name IN $db.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_database_name}}",
"legend": "{{postgresql.database.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -338,7 +338,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
@@ -349,22 +349,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(operation = 'del' AND host_name IN $host_name AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'del' AND host.name IN $host.name AND postgresql.database.name IN $db.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_database_name}}",
"legend": "{{postgresql.database.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -413,7 +413,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
@@ -424,22 +424,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(operation = 'hot_upd' AND host_name IN $host_name AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'hot_upd' AND host.name IN $host.name AND postgresql.database.name IN $db.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_database_name}}",
"legend": "{{postgresql.database.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -488,7 +488,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": null,
@@ -499,15 +499,15 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(operation = 'ins' AND host_name IN $host_name AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'ins' AND host.name IN $host.name AND postgresql.database.name IN $db.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
@@ -523,7 +523,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": null,
@@ -534,15 +534,15 @@
"disabled": false,
"expression": "B",
"filter": {
"expression": "(operation = 'upd' AND host_name IN $host_name AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'upd' AND host.name IN $host.name AND postgresql.database.name IN $db.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
@@ -558,7 +558,7 @@
{
"aggregations": [
{
"metricName": "postgresql_operations",
"metricName": "postgresql.operations",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": null,
@@ -569,15 +569,15 @@
"disabled": false,
"expression": "C",
"filter": {
"expression": "(operation = 'del' AND host_name IN $host_name AND postgresql_database_name IN $db_name)"
"expression": "(operation = 'del' AND host.name IN $host.name AND postgresql.database.name IN $db.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
@@ -633,7 +633,7 @@
{
"aggregations": [
{
"metricName": "postgresql_database_locks",
"metricName": "postgresql.database.locks",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -644,7 +644,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [
{
@@ -708,7 +708,7 @@
{
"aggregations": [
{
"metricName": "postgresql_deadlocks",
"metricName": "postgresql.deadlocks",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -719,22 +719,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(host_name IN $host_name AND postgresql_database_name IN $db_name)"
"expression": "(host.name IN $host.name AND postgresql.database.name IN $db.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_database_name}}",
"legend": "{{postgresql.database.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -783,7 +783,7 @@
{
"aggregations": [
{
"metricName": "postgresql_backends",
"metricName": "postgresql.backends",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
@@ -794,22 +794,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(host_name IN $host_name AND postgresql_database_name IN $db_name)"
"expression": "(host.name IN $host.name AND postgresql.database.name IN $db.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_database_name--string--tag--false",
"id": "postgresql.database.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_database_name",
"key": "postgresql.database.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_database_name}}",
"legend": "{{postgresql.database.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -858,7 +858,7 @@
{
"aggregations": [
{
"metricName": "postgresql_rows",
"metricName": "postgresql.rows",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -869,7 +869,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(state = 'dead' AND host_name IN $host_name AND postgresql_database_name IN $db_name AND postgresql_table_name IN $table_name)"
"expression": "(state = 'dead' AND host.name IN $host.name AND postgresql.database.name IN $db.name AND postgresql.table.name IN $table.name)"
},
"groupBy": [],
"having": {
@@ -924,7 +924,7 @@
{
"aggregations": [
{
"metricName": "postgresql_index_scans",
"metricName": "postgresql.index.scans",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -935,22 +935,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(host_name IN $host_name AND postgresql_database_name IN $db_name AND postgresql_table_name IN $table_name)"
"expression": "(host.name IN $host.name AND postgresql.database.name IN $db.name AND postgresql.table.name IN $table.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_index_name--string--tag--false",
"id": "postgresql.index.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_index_name",
"key": "postgresql.index.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{postgresql_index_name}}",
"legend": "{{postgresql.index.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -999,7 +999,7 @@
{
"aggregations": [
{
"metricName": "postgresql_rows",
"metricName": "postgresql.rows",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": null,
@@ -1010,15 +1010,15 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "(state = 'dead' AND host_name IN $host_name AND postgresql_database_name IN $db_name AND postgresql_table_name IN $table_name)"
"expression": "(state = 'dead' AND host.name IN $host.name AND postgresql.database.name IN $db.name AND postgresql.table.name IN $table.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_table_name--string--tag--false",
"id": "postgresql.table.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_table_name",
"key": "postgresql.table.name",
"type": "tag"
}
],
@@ -1034,7 +1034,7 @@
{
"aggregations": [
{
"metricName": "postgresql_rows",
"metricName": "postgresql.rows",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": null,
@@ -1045,15 +1045,15 @@
"disabled": false,
"expression": "B",
"filter": {
"expression": "(state = 'live' AND host_name IN $host_name AND postgresql_database_name IN $db_name AND postgresql_table_name IN $table_name)"
"expression": "(state = 'live' AND host.name IN $host.name AND postgresql.database.name IN $db.name AND postgresql.table.name IN $table.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_table_name--string--tag--false",
"id": "postgresql.table.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_table_name",
"key": "postgresql.table.name",
"type": "tag"
}
],
@@ -1069,7 +1069,7 @@
{
"aggregations": [
{
"metricName": "postgresql_index_scans",
"metricName": "postgresql.index.scans",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -1080,15 +1080,15 @@
"disabled": false,
"expression": "C",
"filter": {
"expression": "(host_name IN $host_name AND postgresql_database_name IN $db_name AND postgresql_table_name IN $table_name)"
"expression": "(host.name IN $host.name AND postgresql.database.name IN $db.name AND postgresql.table.name IN $table.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_table_name--string--tag--false",
"id": "postgresql.table.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_table_name",
"key": "postgresql.table.name",
"type": "tag"
}
],
@@ -1104,7 +1104,7 @@
{
"aggregations": [
{
"metricName": "postgresql_table_size",
"metricName": "postgresql.table.size",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": null,
@@ -1115,15 +1115,15 @@
"disabled": false,
"expression": "D",
"filter": {
"expression": "(host_name IN $host_name AND postgresql_database_name IN $db_name AND postgresql_table_name IN $table_name)"
"expression": "(host.name IN $host.name AND postgresql.database.name IN $db.name AND postgresql.table.name IN $table.name)"
},
"groupBy": [
{
"dataType": "string",
"id": "postgresql_table_name--string--tag--false",
"id": "postgresql.table.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "postgresql_table_name",
"key": "postgresql.table.name",
"type": "tag"
}
],

View File

@@ -99,9 +99,9 @@
"key": "94f19b3c-ad9f-4b47-a9b2-f312c09fa965",
"modificationUUID": "4c5b0c03-9cbc-425b-8d8e-7152e5c39ba8",
"multiSelect": true,
"name": "host_name",
"name": "host.name",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'host_name') AS host_name\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'redis_cpu_time'\nGROUP BY host_name",
"queryValue": "SELECT JSONExtractString(labels, 'host.name') AS `host.name`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'redis.cpu.time'\nGROUP BY `host.name`",
"selectedValue": [
"Srikanths-MacBook-Pro.local"
],
@@ -127,7 +127,7 @@
{
"aggregations": [
{
"metricName": "redis_keyspace_hits",
"metricName": "redis.keyspace.hits",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -138,7 +138,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [],
"having": {
@@ -193,7 +193,7 @@
{
"aggregations": [
{
"metricName": "redis_clients_blocked",
"metricName": "redis.clients.blocked",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -204,7 +204,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [],
"having": {
@@ -259,7 +259,7 @@
{
"aggregations": [
{
"metricName": "redis_db_keys",
"metricName": "redis.db.keys",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -322,7 +322,7 @@
{
"aggregations": [
{
"metricName": "redis_rdb_changes_since_last_save",
"metricName": "redis.rdb.changes_since_last_save",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -333,7 +333,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [],
"having": {
@@ -388,7 +388,7 @@
{
"aggregations": [
{
"metricName": "redis_commands",
"metricName": "redis.commands",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -399,7 +399,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [],
"having": {
@@ -454,7 +454,7 @@
{
"aggregations": [
{
"metricName": "redis_memory_used",
"metricName": "redis.memory.used",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -465,22 +465,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host_name--string--tag--false",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host_name",
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Used::{{host_name}}",
"legend": "Used::{{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -489,7 +489,7 @@
{
"aggregations": [
{
"metricName": "redis_maxmemory",
"metricName": "redis.maxmemory",
"reduceTo": "sum",
"spaceAggregation": "max",
"temporality": null,
@@ -500,22 +500,22 @@
"disabled": false,
"expression": "B",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host_name--string--tag--false",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host_name",
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Max::{{host_name}}",
"legend": "Max::{{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "B",
@@ -564,7 +564,7 @@
{
"aggregations": [
{
"metricName": "redis_memory_rss",
"metricName": "redis.memory.rss",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -575,22 +575,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host_name--string--tag--false",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host_name",
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Rss::{{host_name}}",
"legend": "Rss::{{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -639,7 +639,7 @@
{
"aggregations": [
{
"metricName": "redis_memory_fragmentation_ratio",
"metricName": "redis.memory.fragmentation_ratio",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
@@ -650,22 +650,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host_name--string--tag--false",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host_name",
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Rss::{{host_name}}",
"legend": "Rss::{{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -714,7 +714,7 @@
{
"aggregations": [
{
"metricName": "redis_keys_evicted",
"metricName": "redis.keys.evicted",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
@@ -725,22 +725,22 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "host_name IN $host_name"
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host_name--string--tag--false",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host_name",
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Rss::{{host_name}}",
"legend": "Rss::{{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",

View File

@@ -1,779 +0,0 @@
{
"description": "This dashboard shows the Redis instance overview. It includes latency, hit/miss rate, connections, and memory information.\n",
"id": "redis-overview",
"layout": [
{
"h": 3,
"i": "d4c164bc-8fc2-4dbc-aadd-8d17479ca649",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 9
},
{
"h": 3,
"i": "2fbaef0d-3cdb-4ce3-aa3c-9bbbb41786d9",
"moved": false,
"static": false,
"w": 6,
"x": 3,
"y": 6
},
{
"h": 3,
"i": "f5ee1511-0d2b-4404-9ce0-e991837decc2",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 3
},
{
"h": 3,
"i": "b19c7058-b806-4ea2-974a-ca555b168991",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 3
},
{
"h": 3,
"i": "bf0deeeb-e926-4234-944c-82bacd96af47",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 0
},
{
"h": 3,
"i": "a77227c7-16f5-4353-952e-b183c715a61c",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 0
},
{
"h": 3,
"i": "9698cee2-b1f3-4c0b-8c9f-3da4f0e05f17",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 9
},
{
"h": 3,
"i": "64a5f303-d7db-44ff-9a0e-948e5c653320",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 12
},
{
"h": 3,
"i": "3e80a918-69af-4c9a-bc57-a94e1d41b05c",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 12
}
],
"name": "",
"tags": [
"redis",
"database"
],
"title": "Redis overview",
"variables": {
"94f19b3c-ad9f-4b47-a9b2-f312c09fa965": {
"allSelected": true,
"customValue": "",
"description": "List of hosts sending Redis metrics",
"id": "94f19b3c-ad9f-4b47-a9b2-f312c09fa965",
"key": "94f19b3c-ad9f-4b47-a9b2-f312c09fa965",
"modificationUUID": "4c5b0c03-9cbc-425b-8d8e-7152e5c39ba8",
"multiSelect": true,
"name": "host.name",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'host.name') AS `host.name`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'redis.cpu.time'\nGROUP BY `host.name`",
"selectedValue": [
"Srikanths-MacBook-Pro.local"
],
"showALLOption": true,
"sort": "ASC",
"textboxValue": "",
"type": "QUERY"
}
},
"version": "v5",
"widgets": [
{
"description": "Rate successful lookup of keys in the main dictionary",
"fillSpans": false,
"id": "a77227c7-16f5-4353-952e-b183c715a61c",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "redis.keyspace.hits",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
"timeAggregation": "rate"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [],
"having": {
"expression": ""
},
"legend": "Hit/s across all hosts",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "42c9c117-bfaf-49f7-b528-aad099392295",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Hits/s",
"yAxisUnit": "none"
},
{
"description": "Number of clients pending on a blocking call",
"fillSpans": false,
"id": "bf0deeeb-e926-4234-944c-82bacd96af47",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "redis.clients.blocked",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
"timeAggregation": "sum"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [],
"having": {
"expression": ""
},
"legend": "Blocked clients across all hosts",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "b77a9e11-fb98-4a95-88a8-c3ad25c14369",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Clients blocked",
"yAxisUnit": "none"
},
{
"description": "",
"fillSpans": false,
"id": "b19c7058-b806-4ea2-974a-ca555b168991",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "redis.db.keys",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
"timeAggregation": "sum"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"groupBy": [],
"having": {
"expression": ""
},
"legend": "",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "b77a9e11-fb98-4a95-88a8-c3ad25c14369",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Keyspace Keys",
"yAxisUnit": "none"
},
{
"description": "Number of changes since the last dump",
"fillSpans": false,
"id": "f5ee1511-0d2b-4404-9ce0-e991837decc2",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "redis.rdb.changes_since_last_save",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
"timeAggregation": "sum"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [],
"having": {
"expression": ""
},
"legend": "Number of unsaved changes",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "32cedddf-606d-4de1-8c1d-4b7049e6430c",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Unsaved changes",
"yAxisUnit": "none"
},
{
"description": "",
"fillSpans": false,
"id": "2fbaef0d-3cdb-4ce3-aa3c-9bbbb41786d9",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "redis.commands",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
"timeAggregation": "sum"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [],
"having": {
"expression": ""
},
"legend": "ops/s",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "c70de4dd-a68a-42df-a249-6610c296709c",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Command/s",
"yAxisUnit": "ops"
},
{
"description": "",
"fillSpans": false,
"id": "d4c164bc-8fc2-4dbc-aadd-8d17479ca649",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "redis.memory.used",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
"timeAggregation": "sum"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Used::{{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
},
{
"aggregations": [
{
"metricName": "redis.maxmemory",
"reduceTo": "sum",
"spaceAggregation": "max",
"temporality": null,
"timeAggregation": "max"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "B",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Max::{{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "B",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "2f47df76-f09e-4152-8623-971f0fe66bfe",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Memory usage",
"yAxisUnit": "bytes"
},
{
"description": "",
"fillSpans": false,
"id": "9698cee2-b1f3-4c0b-8c9f-3da4f0e05f17",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "redis.memory.rss",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
"timeAggregation": "sum"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Rss::{{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "fddd043c-1385-481c-9f4c-381f261e1dd9",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "RSS Memory",
"yAxisUnit": "bytes"
},
{
"description": "",
"fillSpans": false,
"id": "64a5f303-d7db-44ff-9a0e-948e5c653320",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "redis.memory.fragmentation_ratio",
"reduceTo": "sum",
"spaceAggregation": "avg",
"temporality": null,
"timeAggregation": "avg"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Rss::{{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "3e802b07-0249-4d79-a5c7-6580ab535ad0",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Fragmentation ratio",
"yAxisUnit": "short"
},
{
"description": "Number of evicted keys due to maxmemory limit",
"fillSpans": false,
"id": "3e80a918-69af-4c9a-bc57-a94e1d41b05c",
"isStacked": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "redis.keys.evicted",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": null,
"timeAggregation": "rate"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "host.name IN $host.name"
},
"groupBy": [
{
"dataType": "string",
"id": "host.name--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "host.name",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "Rss::{{host.name}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "15d1d9d7-eb10-464b-aa7b-33ff211996f7",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"softMax": null,
"softMin": null,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Eviction rate",
"yAxisUnit": "short"
}
]
}

View File

@@ -1,84 +0,0 @@
{"metric_name":"system.cpu.time","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:00:00+00:00","value":100,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:02:00+00:00","value":200,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:04:00+00:00","value":300,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:00:00+00:00","value":400,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:02:00+00:00","value":600,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:04:00+00:00","value":800,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.memory.usage","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":2000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":2100000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":2200000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":6000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":5900000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":5800000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"prod-linux-1","os.type":"linux"},"timestamp":"2025-01-10T10:00:00+00:00","value":1.5,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"prod-linux-1","os.type":"linux"},"timestamp":"2025-01-10T10:02:00+00:00","value":1.55,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"prod-linux-1","os.type":"linux"},"timestamp":"2025-01-10T10:04:00+00:00","value":1.6,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":51000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":52000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":49000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"prod-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":48000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.time","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:00:00+00:00","value":100,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:02:00+00:00","value":200,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:04:00+00:00","value":300,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:00:00+00:00","value":400,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:02:00+00:00","value":600,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:04:00+00:00","value":800,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.memory.usage","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":2000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":2100000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":2200000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":6000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":5900000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":5800000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"prod-windows-1","os.type":"windows"},"timestamp":"2025-01-10T10:00:00+00:00","value":1.5,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"prod-windows-1","os.type":"windows"},"timestamp":"2025-01-10T10:02:00+00:00","value":1.55,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"prod-windows-1","os.type":"windows"},"timestamp":"2025-01-10T10:04:00+00:00","value":1.6,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":51000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":52000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":49000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"prod-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":48000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.time","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:00:00+00:00","value":100,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:02:00+00:00","value":200,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:04:00+00:00","value":300,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:00:00+00:00","value":400,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:02:00+00:00","value":600,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:04:00+00:00","value":800,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.memory.usage","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":2000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":2100000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":2200000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":6000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":5900000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":5800000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"dev-linux-1","os.type":"linux"},"timestamp":"2025-01-10T10:00:00+00:00","value":1.5,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"dev-linux-1","os.type":"linux"},"timestamp":"2025-01-10T10:02:00+00:00","value":1.55,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"dev-linux-1","os.type":"linux"},"timestamp":"2025-01-10T10:04:00+00:00","value":1.6,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":51000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":52000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":49000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"dev-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":48000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.time","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:00:00+00:00","value":100,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:02:00+00:00","value":200,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:04:00+00:00","value":300,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:00:00+00:00","value":400,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:02:00+00:00","value":600,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:04:00+00:00","value":800,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.memory.usage","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":2000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":2100000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":2200000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":6000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":5900000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":5800000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"dev-windows-1","os.type":"windows"},"timestamp":"2025-01-10T10:00:00+00:00","value":1.5,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"dev-windows-1","os.type":"windows"},"timestamp":"2025-01-10T10:02:00+00:00","value":1.55,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"dev-windows-1","os.type":"windows"},"timestamp":"2025-01-10T10:04:00+00:00","value":1.6,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":51000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":52000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":49000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"dev-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":48000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}

View File

@@ -1,126 +0,0 @@
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:00:00+00:00","value":100,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:02:00+00:00","value":200,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:04:00+00:00","value":300,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:00:00+00:00","value":400,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:02:00+00:00","value":600,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:04:00+00:00","value":800,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":2000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":2100000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":2200000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":6000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":5900000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":5800000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"inactive-linux-1","os.type":"linux"},"timestamp":"2025-01-10T10:00:00+00:00","value":1.5,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"inactive-linux-1","os.type":"linux"},"timestamp":"2025-01-10T10:02:00+00:00","value":1.55,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"inactive-linux-1","os.type":"linux"},"timestamp":"2025-01-10T10:04:00+00:00","value":1.6,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":51000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":52000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":49000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":48000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:00:00+00:00","value":100,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:02:00+00:00","value":200,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:04:00+00:00","value":300,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:00:00+00:00","value":400,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:02:00+00:00","value":600,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:04:00+00:00","value":800,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":2000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":2100000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":2200000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":6000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":5900000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":5800000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"inactive-windows-1","os.type":"windows"},"timestamp":"2025-01-10T10:00:00+00:00","value":1.5,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"inactive-windows-1","os.type":"windows"},"timestamp":"2025-01-10T10:02:00+00:00","value":1.55,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"inactive-windows-1","os.type":"windows"},"timestamp":"2025-01-10T10:04:00+00:00","value":1.6,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":51000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":52000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":49000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":48000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:00:00+00:00","value":100,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:02:00+00:00","value":200,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:04:00+00:00","value":300,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:00:00+00:00","value":400,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:02:00+00:00","value":600,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:04:00+00:00","value":800,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":2000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":2100000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":2200000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":6000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":5900000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":5800000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"inactive-windows-2","os.type":"windows"},"timestamp":"2025-01-10T10:00:00+00:00","value":1.5,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"inactive-windows-2","os.type":"windows"},"timestamp":"2025-01-10T10:02:00+00:00","value":1.55,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"inactive-windows-2","os.type":"windows"},"timestamp":"2025-01-10T10:04:00+00:00","value":1.6,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":51000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":52000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":49000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"inactive-windows-2","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":48000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-linux-1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:20:00+00:00","value":100,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-linux-1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:22:00+00:00","value":200,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-linux-1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:24:00+00:00","value":300,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-linux-1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:20:00+00:00","value":400,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-linux-1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:22:00+00:00","value":600,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-linux-1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:24:00+00:00","value":800,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:20:00+00:00","value":2000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:22:00+00:00","value":2100000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:24:00+00:00","value":2200000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:20:00+00:00","value":6000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:22:00+00:00","value":5900000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:24:00+00:00","value":5800000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"active-linux-1","os.type":"linux"},"timestamp":"2025-01-10T10:20:00+00:00","value":1.5,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"active-linux-1","os.type":"linux"},"timestamp":"2025-01-10T10:22:00+00:00","value":1.55,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"active-linux-1","os.type":"linux"},"timestamp":"2025-01-10T10:24:00+00:00","value":1.6,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:20:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:22:00+00:00","value":51000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-linux-1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:24:00+00:00","value":52000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:20:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:22:00+00:00","value":49000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-linux-1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:24:00+00:00","value":48000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-linux-2","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:20:00+00:00","value":100,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-linux-2","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:22:00+00:00","value":200,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-linux-2","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:24:00+00:00","value":300,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-linux-2","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:20:00+00:00","value":400,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-linux-2","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:22:00+00:00","value":600,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-linux-2","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:24:00+00:00","value":800,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-linux-2","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:20:00+00:00","value":2000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-linux-2","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:22:00+00:00","value":2100000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-linux-2","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:24:00+00:00","value":2200000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-linux-2","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:20:00+00:00","value":6000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-linux-2","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:22:00+00:00","value":5900000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-linux-2","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:24:00+00:00","value":5800000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"active-linux-2","os.type":"linux"},"timestamp":"2025-01-10T10:20:00+00:00","value":1.5,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"active-linux-2","os.type":"linux"},"timestamp":"2025-01-10T10:22:00+00:00","value":1.55,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"active-linux-2","os.type":"linux"},"timestamp":"2025-01-10T10:24:00+00:00","value":1.6,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-linux-2","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:20:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-linux-2","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:22:00+00:00","value":51000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-linux-2","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:24:00+00:00","value":52000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-linux-2","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:20:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-linux-2","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:22:00+00:00","value":49000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-linux-2","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:24:00+00:00","value":48000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-windows-1","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:20:00+00:00","value":100,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-windows-1","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:22:00+00:00","value":200,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-windows-1","os.type":"windows","state":"user"},"timestamp":"2025-01-10T10:24:00+00:00","value":300,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-windows-1","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:20:00+00:00","value":400,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-windows-1","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:22:00+00:00","value":600,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"active-windows-1","os.type":"windows","state":"idle"},"timestamp":"2025-01-10T10:24:00+00:00","value":800,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:20:00+00:00","value":2000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:22:00+00:00","value":2100000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:24:00+00:00","value":2200000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:20:00+00:00","value":6000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:22:00+00:00","value":5900000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"active-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:24:00+00:00","value":5800000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"active-windows-1","os.type":"windows"},"timestamp":"2025-01-10T10:20:00+00:00","value":1.5,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"active-windows-1","os.type":"windows"},"timestamp":"2025-01-10T10:22:00+00:00","value":1.55,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"active-windows-1","os.type":"windows"},"timestamp":"2025-01-10T10:24:00+00:00","value":1.6,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:20:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:22:00+00:00","value":51000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-windows-1","os.type":"windows","state":"used"},"timestamp":"2025-01-10T10:24:00+00:00","value":52000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:20:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:22:00+00:00","value":49000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"active-windows-1","os.type":"windows","state":"free"},"timestamp":"2025-01-10T10:24:00+00:00","value":48000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}

View File

@@ -1,72 +0,0 @@
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:00:00+00:00","value":100,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:02:00+00:00","value":200,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h1","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:04:00+00:00","value":300,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h1","os.type":"linux","state":"system"},"timestamp":"2025-01-10T10:00:00+00:00","value":50,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h1","os.type":"linux","state":"system"},"timestamp":"2025-01-10T10:02:00+00:00","value":100,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h1","os.type":"linux","state":"system"},"timestamp":"2025-01-10T10:04:00+00:00","value":150,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:00:00+00:00","value":400,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:02:00+00:00","value":600,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h1","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:04:00+00:00","value":800,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h1","os.type":"linux","state":"wait"},"timestamp":"2025-01-10T10:00:00+00:00","value":10,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h1","os.type":"linux","state":"wait"},"timestamp":"2025-01-10T10:02:00+00:00","value":20,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h1","os.type":"linux","state":"wait"},"timestamp":"2025-01-10T10:04:00+00:00","value":30,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h2","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:00:00+00:00","value":80,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h2","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:02:00+00:00","value":160,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h2","os.type":"linux","state":"user"},"timestamp":"2025-01-10T10:04:00+00:00","value":240,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h2","os.type":"linux","state":"system"},"timestamp":"2025-01-10T10:00:00+00:00","value":40,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h2","os.type":"linux","state":"system"},"timestamp":"2025-01-10T10:02:00+00:00","value":80,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h2","os.type":"linux","state":"system"},"timestamp":"2025-01-10T10:04:00+00:00","value":120,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h2","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:00:00+00:00","value":300,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h2","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:02:00+00:00","value":500,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h2","os.type":"linux","state":"idle"},"timestamp":"2025-01-10T10:04:00+00:00","value":700,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h2","os.type":"linux","state":"wait"},"timestamp":"2025-01-10T10:00:00+00:00","value":5,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h2","os.type":"linux","state":"wait"},"timestamp":"2025-01-10T10:02:00+00:00","value":10,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.cpu.time","labels":{"host.name":"happy-h2","os.type":"linux","state":"wait"},"timestamp":"2025-01-10T10:04:00+00:00","value":15,"temporality":"Cumulative","type_":"Sum","is_monotonic":true}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":2000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":2100000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":2200000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":6000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":5900000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":5800000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"buffered"},"timestamp":"2025-01-10T10:00:00+00:00","value":500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"buffered"},"timestamp":"2025-01-10T10:02:00+00:00","value":500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"buffered"},"timestamp":"2025-01-10T10:04:00+00:00","value":500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"cached"},"timestamp":"2025-01-10T10:00:00+00:00","value":1500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"cached"},"timestamp":"2025-01-10T10:02:00+00:00","value":1500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"cached"},"timestamp":"2025-01-10T10:04:00+00:00","value":1500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":3000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":3250000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":3500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":5000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":4750000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":4500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"buffered"},"timestamp":"2025-01-10T10:00:00+00:00","value":500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"buffered"},"timestamp":"2025-01-10T10:02:00+00:00","value":500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"buffered"},"timestamp":"2025-01-10T10:04:00+00:00","value":500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"cached"},"timestamp":"2025-01-10T10:00:00+00:00","value":1500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"cached"},"timestamp":"2025-01-10T10:02:00+00:00","value":1500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.memory.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"cached"},"timestamp":"2025-01-10T10:04:00+00:00","value":1500000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"happy-h1","os.type":"linux"},"timestamp":"2025-01-10T10:00:00+00:00","value":1.5,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"happy-h1","os.type":"linux"},"timestamp":"2025-01-10T10:02:00+00:00","value":1.55,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"happy-h1","os.type":"linux"},"timestamp":"2025-01-10T10:04:00+00:00","value":1.6,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"happy-h2","os.type":"linux"},"timestamp":"2025-01-10T10:00:00+00:00","value":2.0,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"happy-h2","os.type":"linux"},"timestamp":"2025-01-10T10:02:00+00:00","value":2.05,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.cpu.load_average.15m","labels":{"host.name":"happy-h2","os.type":"linux"},"timestamp":"2025-01-10T10:04:00+00:00","value":2.1,"temporality":"Unspecified","type_":"Gauge","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":51000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":52000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":50000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":49000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":48000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"reserved"},"timestamp":"2025-01-10T10:00:00+00:00","value":5000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"reserved"},"timestamp":"2025-01-10T10:02:00+00:00","value":5000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h1","os.type":"linux","state":"reserved"},"timestamp":"2025-01-10T10:04:00+00:00","value":5000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:00:00+00:00","value":70000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:02:00+00:00","value":71000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"used"},"timestamp":"2025-01-10T10:04:00+00:00","value":72000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:00:00+00:00","value":30000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:02:00+00:00","value":29000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"free"},"timestamp":"2025-01-10T10:04:00+00:00","value":28000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"reserved"},"timestamp":"2025-01-10T10:00:00+00:00","value":5000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"reserved"},"timestamp":"2025-01-10T10:02:00+00:00","value":5000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}
{"metric_name":"system.filesystem.usage","labels":{"host.name":"happy-h2","os.type":"linux","state":"reserved"},"timestamp":"2025-01-10T10:04:00+00:00","value":5000000000,"temporality":"Unspecified","type_":"Sum","is_monotonic":false}

Some files were not shown because too many files have changed in this diff Show More