mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-31 11:31:59 +08:00
commit
6aba701cca
@ -144,7 +144,7 @@ services:
|
||||
condition: on-failure
|
||||
|
||||
query-service:
|
||||
image: signoz/query-service:0.29.0
|
||||
image: signoz/query-service:0.29.1
|
||||
command:
|
||||
[
|
||||
"-config=/root/config/prometheus.yml",
|
||||
@ -184,7 +184,7 @@ services:
|
||||
<<: *clickhouse-depend
|
||||
|
||||
frontend:
|
||||
image: signoz/frontend:0.29.0
|
||||
image: signoz/frontend:0.29.1
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
|
@ -162,7 +162,7 @@ services:
|
||||
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
|
||||
|
||||
query-service:
|
||||
image: signoz/query-service:${DOCKER_TAG:-0.29.0}
|
||||
image: signoz/query-service:${DOCKER_TAG:-0.29.1}
|
||||
container_name: signoz-query-service
|
||||
command:
|
||||
[
|
||||
@ -201,7 +201,7 @@ services:
|
||||
<<: *clickhouse-depend
|
||||
|
||||
frontend:
|
||||
image: signoz/frontend:${DOCKER_TAG:-0.29.0}
|
||||
image: signoz/frontend:${DOCKER_TAG:-0.29.1}
|
||||
container_name: signoz-frontend
|
||||
restart: on-failure
|
||||
depends_on:
|
||||
|
@ -4,6 +4,7 @@ import { createNewBuilderItemName } from 'lib/newQueryBuilder/createNewBuilderIt
|
||||
import {
|
||||
AutocompleteType,
|
||||
BaseAutocompleteData,
|
||||
DataTypes,
|
||||
LocalDataType,
|
||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
@ -46,7 +47,7 @@ export const selectValueDivider = '__';
|
||||
|
||||
export const baseAutoCompleteIdKeysOrder: (keyof Omit<
|
||||
BaseAutocompleteData,
|
||||
'id'
|
||||
'id' | 'isJSON'
|
||||
>)[] = ['key', 'dataType', 'type', 'isColumn'];
|
||||
|
||||
export const autocompleteType: Record<AutocompleteType, AutocompleteType> = {
|
||||
@ -112,10 +113,11 @@ export const initialAutocompleteData: BaseAutocompleteData = {
|
||||
{ dataType: null, key: '', isColumn: null, type: null },
|
||||
baseAutoCompleteIdKeysOrder,
|
||||
),
|
||||
dataType: '',
|
||||
dataType: DataTypes.EMPTY,
|
||||
key: '',
|
||||
isColumn: false,
|
||||
type: '',
|
||||
isJSON: false,
|
||||
};
|
||||
|
||||
export const initialFilters: TagFilter = {
|
||||
@ -273,6 +275,8 @@ export const OPERATORS = {
|
||||
'>': '>',
|
||||
'<=': '<=',
|
||||
'<': '<',
|
||||
HAS: 'HAS',
|
||||
NHAS: 'NHAS',
|
||||
};
|
||||
|
||||
export const QUERY_BUILDER_OPERATORS_BY_TYPES = {
|
||||
|
@ -4,6 +4,7 @@ import { useOrderByFilter } from 'container/QueryBuilder/filters/OrderByFilter/u
|
||||
import { selectStyle } from 'container/QueryBuilder/filters/QueryBuilderSearch/config';
|
||||
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
||||
import { memo, useMemo } from 'react';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { StringOperators } from 'types/common/queryBuilder';
|
||||
|
||||
function ExplorerOrderBy({ query, onChange }: OrderByFilterProps): JSX.Element {
|
||||
@ -33,7 +34,7 @@ function ExplorerOrderBy({ query, onChange }: OrderByFilterProps): JSX.Element {
|
||||
const keysOptions = createOptions(data?.payload?.attributeKeys || []);
|
||||
|
||||
const customOptions = createOptions([
|
||||
{ key: 'timestamp', isColumn: true, type: '', dataType: '' },
|
||||
{ key: 'timestamp', isColumn: true, type: '', dataType: DataTypes.EMPTY },
|
||||
]);
|
||||
|
||||
const baseOptions = [
|
||||
|
@ -3,7 +3,10 @@ import {
|
||||
initialQueryBuilderFormValuesMap,
|
||||
} from 'constants/queryBuilder';
|
||||
import { FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
BaseAutocompleteData,
|
||||
DataTypes,
|
||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { IBuilderQuery, Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { LogsAggregatorOperator } from 'types/common/queryBuilder';
|
||||
|
||||
@ -45,6 +48,6 @@ export const liveLogsCompositeQuery = constructCompositeQuery({
|
||||
export const idObject: BaseAutocompleteData = {
|
||||
key: 'id',
|
||||
type: '',
|
||||
dataType: 'string',
|
||||
dataType: DataTypes.String,
|
||||
isColumn: true,
|
||||
};
|
||||
|
@ -0,0 +1,11 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export const TitleWrapper = styled.span`
|
||||
.hover-reveal {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover .hover-reveal {
|
||||
visibility: visible;
|
||||
}
|
||||
`;
|
89
frontend/src/container/LogDetailedView/BodyTitleRenderer.tsx
Normal file
89
frontend/src/container/LogDetailedView/BodyTitleRenderer.tsx
Normal file
@ -0,0 +1,89 @@
|
||||
import { orange } from '@ant-design/colors';
|
||||
import { SettingOutlined } from '@ant-design/icons';
|
||||
import { Dropdown, MenuProps } from 'antd';
|
||||
import { OPERATORS } from 'constants/queryBuilder';
|
||||
import { useActiveLog } from 'hooks/logs/useActiveLog';
|
||||
|
||||
import { TitleWrapper } from './BodyTitleRenderer.styles';
|
||||
import { DROPDOWN_KEY } from './constant';
|
||||
import { BodyTitleRendererProps } from './LogDetailedView.types';
|
||||
import {
|
||||
generateFieldKeyForArray,
|
||||
getDataTypes,
|
||||
removeObjectFromString,
|
||||
} from './utils';
|
||||
|
||||
function BodyTitleRenderer({
|
||||
title,
|
||||
parentIsArray = false,
|
||||
nodeKey,
|
||||
value,
|
||||
}: BodyTitleRendererProps): JSX.Element {
|
||||
const { onAddToQuery } = useActiveLog();
|
||||
|
||||
const filterHandler = (isFilterIn: boolean) => (): void => {
|
||||
if (parentIsArray) {
|
||||
onAddToQuery(
|
||||
generateFieldKeyForArray(
|
||||
removeObjectFromString(nodeKey),
|
||||
getDataTypes(value),
|
||||
),
|
||||
`${value}`,
|
||||
isFilterIn ? OPERATORS.HAS : OPERATORS.NHAS,
|
||||
true,
|
||||
parentIsArray ? getDataTypes([value]) : getDataTypes(value),
|
||||
);
|
||||
} else {
|
||||
onAddToQuery(
|
||||
`body.${removeObjectFromString(nodeKey)}`,
|
||||
`${value}`,
|
||||
isFilterIn ? OPERATORS['='] : OPERATORS['!='],
|
||||
true,
|
||||
getDataTypes(value),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const onClickHandler: MenuProps['onClick'] = (props): void => {
|
||||
const mapper = {
|
||||
[DROPDOWN_KEY.FILTER_IN]: filterHandler(true),
|
||||
[DROPDOWN_KEY.FILTER_OUT]: filterHandler(false),
|
||||
};
|
||||
|
||||
const handler = mapper[props.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}`,
|
||||
},
|
||||
],
|
||||
onClick: onClickHandler,
|
||||
};
|
||||
|
||||
return (
|
||||
<TitleWrapper>
|
||||
<Dropdown menu={menu} trigger={['click']}>
|
||||
<SettingOutlined style={{ marginRight: 8 }} className="hover-reveal" />
|
||||
</Dropdown>
|
||||
{title.toString()}{' '}
|
||||
{!parentIsArray && (
|
||||
<span>
|
||||
: <span style={{ color: orange[6] }}>{`${value}`}</span>
|
||||
</span>
|
||||
)}
|
||||
</TitleWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
export default BodyTitleRenderer;
|
25
frontend/src/container/LogDetailedView/FieldRenderer.tsx
Normal file
25
frontend/src/container/LogDetailedView/FieldRenderer.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import { blue } from '@ant-design/colors';
|
||||
import { Tag } from 'antd';
|
||||
|
||||
import { FieldRendererProps } from './LogDetailedView.types';
|
||||
import { getFieldAttributes } from './utils';
|
||||
|
||||
function FieldRenderer({ field }: FieldRendererProps): JSX.Element {
|
||||
const { dataType, newField, logType } = getFieldAttributes(field);
|
||||
|
||||
return (
|
||||
<span>
|
||||
{dataType && newField && logType ? (
|
||||
<>
|
||||
<span style={{ color: blue[4] }}>{newField} </span>
|
||||
<Tag>Type: {logType}</Tag>
|
||||
<Tag>Data type: {dataType}</Tag>
|
||||
</>
|
||||
) : (
|
||||
<span style={{ color: blue[4] }}>{field}</span>
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
export default FieldRenderer;
|
@ -0,0 +1,20 @@
|
||||
import { MetricsType } from 'container/MetricsApplication/constant';
|
||||
|
||||
export interface BodyTitleRendererProps {
|
||||
title: string;
|
||||
nodeKey: string;
|
||||
value: unknown;
|
||||
parentIsArray?: boolean;
|
||||
}
|
||||
|
||||
export type AnyObject = { [key: string]: any };
|
||||
|
||||
export interface FieldRendererProps {
|
||||
field: string;
|
||||
}
|
||||
|
||||
export interface IFieldAttributes {
|
||||
dataType?: string;
|
||||
newField?: string;
|
||||
logType?: MetricsType;
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
import { blue, orange } from '@ant-design/colors';
|
||||
import { orange } from '@ant-design/colors';
|
||||
import { LinkOutlined } from '@ant-design/icons';
|
||||
import { Input, Space, Tooltip } from 'antd';
|
||||
import { Input, Space, Tooltip, Tree } from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table';
|
||||
import Editor from 'components/Editor';
|
||||
import AddToQueryHOC, {
|
||||
AddToQueryHOCProps,
|
||||
} from 'components/Logs/AddToQueryHOC';
|
||||
@ -21,7 +20,8 @@ import { SET_DETAILED_LOG_DATA } from 'types/actions/logs';
|
||||
import { ILog } from 'types/api/logs/log';
|
||||
|
||||
import ActionItem, { ActionItemProps } from './ActionItem';
|
||||
import { flattenObject, recursiveParseJSON } from './utils';
|
||||
import FieldRenderer from './FieldRenderer';
|
||||
import { flattenObject, jsonToDataNodes, recursiveParseJSON } from './utils';
|
||||
|
||||
// Fields which should be restricted from adding it to query
|
||||
const RESTRICTED_FIELDS = ['timestamp'];
|
||||
@ -91,7 +91,7 @@ function TableView({
|
||||
const columns: ColumnsType<DataType> = [
|
||||
{
|
||||
title: 'Action',
|
||||
width: 30,
|
||||
width: 11,
|
||||
render: (fieldData: Record<string, string>): JSX.Element | null => {
|
||||
const fieldKey = fieldData.field.split('.').slice(-1);
|
||||
if (!RESTRICTED_FIELDS.includes(fieldKey[0])) {
|
||||
@ -110,12 +110,12 @@ function TableView({
|
||||
title: 'Field',
|
||||
dataIndex: 'field',
|
||||
key: 'field',
|
||||
width: 30,
|
||||
width: 50,
|
||||
align: 'left',
|
||||
ellipsis: true,
|
||||
render: (field: string, record): JSX.Element => {
|
||||
const fieldKey = field.split('.').slice(-1);
|
||||
const renderedField = <span style={{ color: blue[4] }}>{field}</span>;
|
||||
const renderedField = <FieldRenderer field={field} />;
|
||||
|
||||
if (record.field === 'trace_id') {
|
||||
const traceId = flattenLogData[record.field];
|
||||
@ -161,23 +161,14 @@ function TableView({
|
||||
title: 'Value',
|
||||
dataIndex: 'value',
|
||||
key: 'value',
|
||||
width: 80,
|
||||
width: 70,
|
||||
ellipsis: false,
|
||||
render: (field, record): JSX.Element => {
|
||||
if (record.field === 'body') {
|
||||
const parsedBody = recursiveParseJSON(field);
|
||||
if (!isEmpty(parsedBody)) {
|
||||
return (
|
||||
<Editor
|
||||
value={JSON.stringify(parsedBody, null, 2).replace(/\\n/g, '\n')}
|
||||
readOnly
|
||||
height="70vh"
|
||||
options={{
|
||||
minimap: {
|
||||
enabled: false,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Tree defaultExpandAll showLine treeData={jsonToDataNodes(parsedBody)} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
4
frontend/src/container/LogDetailedView/constant.ts
Normal file
4
frontend/src/container/LogDetailedView/constant.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export const DROPDOWN_KEY = {
|
||||
FILTER_IN: 'filterIn',
|
||||
FILTER_OUT: 'filterOut',
|
||||
};
|
@ -1,4 +1,6 @@
|
||||
import { flattenObject, recursiveParseJSON } from './utils';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
|
||||
import { flattenObject, getDataTypes, recursiveParseJSON } from './utils';
|
||||
|
||||
describe('recursiveParseJSON', () => {
|
||||
it('should return an empty object if the input is not valid JSON', () => {
|
||||
@ -146,3 +148,40 @@ describe('flattenObject in the objects recursively', () => {
|
||||
expect(flattenObject(complexObj)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Get Data Types utils', () => {
|
||||
it('should return String for string input', () => {
|
||||
expect(getDataTypes('hello')).toBe(DataTypes.String);
|
||||
});
|
||||
|
||||
it('should return Float64 for float input', () => {
|
||||
expect(getDataTypes(3.14)).toBe(DataTypes.Float64);
|
||||
});
|
||||
|
||||
it('should return Int64 for integer input', () => {
|
||||
expect(getDataTypes(42)).toBe(DataTypes.Int64);
|
||||
});
|
||||
|
||||
// Test for arrays
|
||||
it('should return ArrayString for string array input', () => {
|
||||
expect(getDataTypes(['hello', 'world'])).toBe(DataTypes.ArrayString);
|
||||
});
|
||||
|
||||
it('should return ArrayFloat64 for float array input', () => {
|
||||
expect(getDataTypes([1.23, 4.56, 7.89])).toBe(DataTypes.ArrayFloat64);
|
||||
});
|
||||
|
||||
it('should return ArrayInt64 for integer array input', () => {
|
||||
expect(getDataTypes([1, 2, 3])).toBe(DataTypes.ArrayInt64);
|
||||
});
|
||||
|
||||
// Edge cases
|
||||
it('should return Int64 for empty array input', () => {
|
||||
expect(getDataTypes([])).toBe(DataTypes.Int64);
|
||||
});
|
||||
|
||||
it('should handle mixed array (return based on first element)', () => {
|
||||
expect(getDataTypes([1, 2.5, 3])).toBe(DataTypes.ArrayInt64);
|
||||
expect(getDataTypes([2.5, 3, 1])).toBe(DataTypes.ArrayFloat64);
|
||||
});
|
||||
});
|
||||
|
@ -1,34 +0,0 @@
|
||||
export const recursiveParseJSON = (obj: string): Record<string, unknown> => {
|
||||
try {
|
||||
const value = JSON.parse(obj);
|
||||
if (typeof value === 'string') {
|
||||
return recursiveParseJSON(value);
|
||||
}
|
||||
if (typeof value === 'object') {
|
||||
Object.entries(value).forEach(([key, val]) => {
|
||||
if (typeof val === 'string') {
|
||||
value[key] = val.trim();
|
||||
} else if (typeof val === 'object') {
|
||||
value[key] = recursiveParseJSON(JSON.stringify(val));
|
||||
}
|
||||
});
|
||||
}
|
||||
return value;
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
type AnyObject = { [key: string]: any };
|
||||
|
||||
export function flattenObject(obj: AnyObject, prefix = ''): AnyObject {
|
||||
return Object.keys(obj).reduce((acc: AnyObject, k: string): AnyObject => {
|
||||
const pre = prefix.length ? `${prefix}.` : '';
|
||||
if (typeof obj[k] === 'object' && obj[k] !== null && !Array.isArray(obj[k])) {
|
||||
Object.assign(acc, flattenObject(obj[k], pre + k));
|
||||
} else {
|
||||
acc[pre + k] = obj[k];
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
176
frontend/src/container/LogDetailedView/utils.tsx
Normal file
176
frontend/src/container/LogDetailedView/utils.tsx
Normal file
@ -0,0 +1,176 @@
|
||||
import { DataNode } from 'antd/es/tree';
|
||||
import { MetricsType } from 'container/MetricsApplication/constant';
|
||||
import { uniqueId } from 'lodash-es';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
|
||||
import BodyTitleRenderer from './BodyTitleRenderer';
|
||||
import { AnyObject, IFieldAttributes } from './LogDetailedView.types';
|
||||
|
||||
export const recursiveParseJSON = (obj: string): Record<string, unknown> => {
|
||||
try {
|
||||
const value = JSON.parse(obj);
|
||||
if (typeof value === 'string') {
|
||||
return recursiveParseJSON(value);
|
||||
}
|
||||
return value;
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
export const computeDataNode = (
|
||||
key: string,
|
||||
valueIsArray: boolean,
|
||||
value: unknown,
|
||||
nodeKey: string,
|
||||
): DataNode => ({
|
||||
key: uniqueId(),
|
||||
title: `${key} ${valueIsArray ? '[...]' : ''}`,
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
children: jsonToDataNodes(
|
||||
value as Record<string, unknown>,
|
||||
valueIsArray ? `${nodeKey}[*]` : nodeKey,
|
||||
valueIsArray,
|
||||
),
|
||||
});
|
||||
|
||||
export function jsonToDataNodes(
|
||||
json: Record<string, unknown>,
|
||||
parentKey = '',
|
||||
parentIsArray = false,
|
||||
): DataNode[] {
|
||||
return Object.entries(json).map(([key, value]) => {
|
||||
let nodeKey = parentKey || key;
|
||||
if (parentIsArray) {
|
||||
nodeKey += `.${value}`;
|
||||
} else if (parentKey) {
|
||||
nodeKey += `.${key}`;
|
||||
}
|
||||
|
||||
const valueIsArray = Array.isArray(value);
|
||||
|
||||
if (parentIsArray) {
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return computeDataNode(key, valueIsArray, value, nodeKey);
|
||||
}
|
||||
|
||||
return {
|
||||
key: uniqueId(),
|
||||
title: (
|
||||
<BodyTitleRenderer
|
||||
title={value as string}
|
||||
nodeKey={nodeKey}
|
||||
value={value}
|
||||
parentIsArray={parentIsArray}
|
||||
/>
|
||||
),
|
||||
children: jsonToDataNodes({}, nodeKey, valueIsArray),
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return computeDataNode(key, valueIsArray, value, nodeKey);
|
||||
}
|
||||
return {
|
||||
key: uniqueId(),
|
||||
title: (
|
||||
<BodyTitleRenderer
|
||||
title={key}
|
||||
nodeKey={nodeKey}
|
||||
value={value}
|
||||
parentIsArray={parentIsArray}
|
||||
/>
|
||||
),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function flattenObject(obj: AnyObject, prefix = ''): AnyObject {
|
||||
return Object.keys(obj).reduce((acc: AnyObject, k: string): AnyObject => {
|
||||
const pre = prefix.length ? `${prefix}.` : '';
|
||||
if (typeof obj[k] === 'object' && obj[k] !== null && !Array.isArray(obj[k])) {
|
||||
Object.assign(acc, flattenObject(obj[k], pre + k));
|
||||
} else {
|
||||
acc[pre + k] = obj[k];
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
const isFloat = (num: number): boolean => num % 1 !== 0;
|
||||
|
||||
export const getDataTypes = (value: unknown): DataTypes => {
|
||||
if (typeof value === 'string') {
|
||||
return DataTypes.String;
|
||||
}
|
||||
|
||||
if (typeof value === 'number') {
|
||||
return isFloat(value) ? DataTypes.Float64 : DataTypes.Int64;
|
||||
}
|
||||
|
||||
if (typeof value === 'boolean') {
|
||||
return DataTypes.bool;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
const firstElement = value[0];
|
||||
|
||||
if (typeof firstElement === 'string') {
|
||||
return DataTypes.ArrayString;
|
||||
}
|
||||
|
||||
if (typeof firstElement === 'boolean') {
|
||||
return DataTypes.ArrayBool;
|
||||
}
|
||||
|
||||
if (typeof firstElement === 'number') {
|
||||
return isFloat(firstElement) ? DataTypes.ArrayFloat64 : DataTypes.ArrayInt64;
|
||||
}
|
||||
}
|
||||
|
||||
return DataTypes.Int64;
|
||||
};
|
||||
|
||||
export const generateFieldKeyForArray = (
|
||||
fieldKey: string,
|
||||
dataType: DataTypes,
|
||||
): string => {
|
||||
let lastDotIndex = fieldKey.lastIndexOf('.');
|
||||
let resultNodeKey = fieldKey;
|
||||
if (lastDotIndex !== -1) {
|
||||
resultNodeKey = fieldKey.substring(0, lastDotIndex);
|
||||
}
|
||||
|
||||
let newResultNodeKey = resultNodeKey;
|
||||
|
||||
if (dataType === DataTypes.Float64) {
|
||||
lastDotIndex = resultNodeKey.lastIndexOf('.');
|
||||
if (lastDotIndex !== -1) {
|
||||
newResultNodeKey = resultNodeKey.substring(0, lastDotIndex);
|
||||
}
|
||||
}
|
||||
return `body.${newResultNodeKey}`;
|
||||
};
|
||||
|
||||
export const removeObjectFromString = (str: string): string =>
|
||||
str.replace(/\[object Object\]./g, '');
|
||||
|
||||
export const getFieldAttributes = (field: string): IFieldAttributes => {
|
||||
let dataType;
|
||||
let newField;
|
||||
let logType;
|
||||
|
||||
if (field.startsWith('attributes_')) {
|
||||
logType = MetricsType.Tag;
|
||||
const stringWithoutPrefix = field.slice('attributes_'.length);
|
||||
const parts = stringWithoutPrefix.split('.');
|
||||
[dataType, newField] = parts;
|
||||
} else if (field.startsWith('resources_')) {
|
||||
logType = MetricsType.Resource;
|
||||
const stringWithoutPrefix = field.slice('resources_'.length);
|
||||
const parts = stringWithoutPrefix.split('.');
|
||||
[dataType, newField] = parts;
|
||||
}
|
||||
|
||||
return { dataType, newField, logType };
|
||||
};
|
@ -1,5 +1,6 @@
|
||||
import { OPERATORS } from 'constants/queryBuilder';
|
||||
import { ILog } from 'types/api/logs/log';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
@ -12,7 +13,7 @@ export const getFiltersFromResources = (
|
||||
id: uuid(),
|
||||
key: {
|
||||
key,
|
||||
dataType: 'string',
|
||||
dataType: DataTypes.String,
|
||||
type: 'resource',
|
||||
isColumn: false,
|
||||
},
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { OPERATORS } from 'constants/queryBuilder';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
BaseAutocompleteData,
|
||||
DataTypes,
|
||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import {
|
||||
DataSource,
|
||||
@ -7,7 +10,7 @@ import {
|
||||
QueryBuilderData,
|
||||
} from 'types/common/queryBuilder';
|
||||
|
||||
import { DataType, FORMULA, MetricsType, WidgetKeys } from '../constant';
|
||||
import { FORMULA, MetricsType, WidgetKeys } from '../constant';
|
||||
import { DatabaseCallProps, DatabaseCallsRPSProps } from '../types';
|
||||
import {
|
||||
getQueryBuilderQueries,
|
||||
@ -22,13 +25,18 @@ export const databaseCallsRPS = ({
|
||||
const autocompleteData: BaseAutocompleteData[] = [
|
||||
{
|
||||
key: WidgetKeys.SignozDBLatencyCount,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
},
|
||||
];
|
||||
const groupBy: BaseAutocompleteData[] = [
|
||||
{ dataType: DataType.STRING, isColumn: false, key: 'db_system', type: 'tag' },
|
||||
{
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: 'db_system',
|
||||
type: 'tag',
|
||||
},
|
||||
];
|
||||
const filterItems: TagFilterItem[][] = [
|
||||
[
|
||||
@ -36,7 +44,7 @@ export const databaseCallsRPS = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Service_name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
@ -65,13 +73,13 @@ export const databaseCallsAvgDuration = ({
|
||||
}: DatabaseCallProps): QueryBuilderData => {
|
||||
const autocompleteDataA: BaseAutocompleteData = {
|
||||
key: WidgetKeys.SignozDbLatencySum,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
};
|
||||
const autocompleteDataB: BaseAutocompleteData = {
|
||||
key: WidgetKeys.SignozDBLatencyCount,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
};
|
||||
@ -81,12 +89,12 @@ export const databaseCallsAvgDuration = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Service_name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
op: OPERATORS.IN,
|
||||
value: [`${servicename}`],
|
||||
value: [servicename],
|
||||
},
|
||||
...tagFilterItems,
|
||||
];
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { OPERATORS } from 'constants/queryBuilder';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
BaseAutocompleteData,
|
||||
DataTypes,
|
||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import {
|
||||
DataSource,
|
||||
@ -7,7 +10,7 @@ import {
|
||||
QueryBuilderData,
|
||||
} from 'types/common/queryBuilder';
|
||||
|
||||
import { DataType, FORMULA, MetricsType, WidgetKeys } from '../constant';
|
||||
import { FORMULA, MetricsType, WidgetKeys } from '../constant';
|
||||
import {
|
||||
ExternalCallDurationByAddressProps,
|
||||
ExternalCallProps,
|
||||
@ -19,7 +22,7 @@ import {
|
||||
|
||||
const groupBy: BaseAutocompleteData[] = [
|
||||
{
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Address,
|
||||
type: MetricsType.Tag,
|
||||
@ -33,13 +36,13 @@ export const externalCallErrorPercent = ({
|
||||
}: ExternalCallDurationByAddressProps): QueryBuilderData => {
|
||||
const autocompleteDataA: BaseAutocompleteData = {
|
||||
key: WidgetKeys.SignozExternalCallLatencyCount,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
};
|
||||
const autocompleteDataB: BaseAutocompleteData = {
|
||||
key: WidgetKeys.SignozExternalCallLatencyCount,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
};
|
||||
@ -49,18 +52,18 @@ export const externalCallErrorPercent = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Service_name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
op: OPERATORS.IN,
|
||||
value: [`${servicename}`],
|
||||
value: [servicename],
|
||||
},
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.StatusCode,
|
||||
dataType: DataType.INT64,
|
||||
dataType: DataTypes.Int64,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -74,7 +77,7 @@ export const externalCallErrorPercent = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Service_name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
@ -115,13 +118,13 @@ export const externalCallDuration = ({
|
||||
tagFilterItems,
|
||||
}: ExternalCallProps): QueryBuilderData => {
|
||||
const autocompleteDataA: BaseAutocompleteData = {
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
key: WidgetKeys.SignozExternalCallLatencySum,
|
||||
type: '',
|
||||
};
|
||||
const autocompleteDataB: BaseAutocompleteData = {
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
key: WidgetKeys.SignozExternalCallLatencyCount,
|
||||
type: '',
|
||||
@ -134,13 +137,13 @@ export const externalCallDuration = ({
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Service_name,
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
op: OPERATORS.IN,
|
||||
value: [`${servicename}`],
|
||||
value: [servicename],
|
||||
},
|
||||
...tagFilterItems,
|
||||
];
|
||||
@ -174,7 +177,7 @@ export const externalCallRpsByAddress = ({
|
||||
}: ExternalCallDurationByAddressProps): QueryBuilderData => {
|
||||
const autocompleteData: BaseAutocompleteData[] = [
|
||||
{
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
key: WidgetKeys.SignozExternalCallLatencyCount,
|
||||
type: '',
|
||||
@ -185,13 +188,13 @@ export const externalCallRpsByAddress = ({
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Service_name,
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
op: OPERATORS.IN,
|
||||
value: [`${servicename}`],
|
||||
value: [servicename],
|
||||
},
|
||||
...tagFilterItems,
|
||||
],
|
||||
@ -215,13 +218,13 @@ export const externalCallDurationByAddress = ({
|
||||
tagFilterItems,
|
||||
}: ExternalCallDurationByAddressProps): QueryBuilderData => {
|
||||
const autocompleteDataA: BaseAutocompleteData = {
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
key: WidgetKeys.SignozExternalCallLatencySum,
|
||||
type: '',
|
||||
};
|
||||
const autocompleteDataB: BaseAutocompleteData = {
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
key: WidgetKeys.SignozExternalCallLatencyCount,
|
||||
type: '',
|
||||
@ -233,13 +236,13 @@ export const externalCallDurationByAddress = ({
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Service_name,
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
op: OPERATORS.IN,
|
||||
value: [`${servicename}`],
|
||||
value: [servicename],
|
||||
},
|
||||
...tagFilterItems,
|
||||
];
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { OPERATORS } from 'constants/queryBuilder';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
BaseAutocompleteData,
|
||||
DataTypes,
|
||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import {
|
||||
DataSource,
|
||||
@ -8,7 +11,6 @@ import {
|
||||
} from 'types/common/queryBuilder';
|
||||
|
||||
import {
|
||||
DataType,
|
||||
FORMULA,
|
||||
GraphTitle,
|
||||
LATENCY_AGGREGATEOPERATOR,
|
||||
@ -40,7 +42,7 @@ export const latency = ({
|
||||
key: isSpanMetricEnable
|
||||
? WidgetKeys.Signoz_latency_bucket
|
||||
: WidgetKeys.DurationNano,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: isSpanMetricEnable ? '' : MetricsType.Tag,
|
||||
};
|
||||
@ -52,7 +54,7 @@ export const latency = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: isSpanMetricEnable ? WidgetKeys.Service_name : WidgetKeys.ServiceName,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
type: isSpanMetricEnable ? MetricsType.Resource : MetricsType.Tag,
|
||||
isColumn: !isSpanMetricEnable,
|
||||
},
|
||||
@ -62,7 +64,7 @@ export const latency = ({
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: !isSpanMetricEnable,
|
||||
key: isSpanMetricEnable ? WidgetKeys.Operation : WidgetKeys.Name,
|
||||
type: MetricsType.Tag,
|
||||
@ -98,21 +100,21 @@ export const apDexTracesQueryBuilderQueries = ({
|
||||
threashold,
|
||||
}: ApDexProps): QueryBuilderData => {
|
||||
const autoCompleteDataA: BaseAutocompleteData = {
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
key: '',
|
||||
type: '',
|
||||
};
|
||||
|
||||
const autoCompleteDataB: BaseAutocompleteData = {
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
key: '',
|
||||
type: '',
|
||||
};
|
||||
|
||||
const autoCompleteDataC: BaseAutocompleteData = {
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
key: '',
|
||||
type: '',
|
||||
@ -123,7 +125,7 @@ export const apDexTracesQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.ServiceName,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: true,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -134,7 +136,7 @@ export const apDexTracesQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: true,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -149,7 +151,7 @@ export const apDexTracesQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.HasError,
|
||||
dataType: DataType.BOOL,
|
||||
dataType: DataTypes.bool,
|
||||
isColumn: true,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -160,7 +162,7 @@ export const apDexTracesQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.DurationNano,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -171,7 +173,7 @@ export const apDexTracesQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.ServiceName,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: true,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -182,7 +184,7 @@ export const apDexTracesQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: true,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -196,7 +198,7 @@ export const apDexTracesQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.DurationNano,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -207,7 +209,7 @@ export const apDexTracesQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.HasError,
|
||||
dataType: DataType.BOOL,
|
||||
dataType: DataTypes.bool,
|
||||
isColumn: true,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -218,7 +220,7 @@ export const apDexTracesQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.ServiceName,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: true,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -229,7 +231,7 @@ export const apDexTracesQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: true,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -277,21 +279,21 @@ export const apDexMetricsQueryBuilderQueries = ({
|
||||
}: ApDexMetricsQueryBuilderQueriesProps): QueryBuilderData => {
|
||||
const autoCompleteDataA: BaseAutocompleteData = {
|
||||
key: WidgetKeys.SignozLatencyCount,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
};
|
||||
|
||||
const autoCompleteDataB: BaseAutocompleteData = {
|
||||
key: WidgetKeys.Signoz_latency_bucket,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
};
|
||||
|
||||
const autoCompleteDataC: BaseAutocompleteData = {
|
||||
key: WidgetKeys.Signoz_latency_bucket,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
};
|
||||
@ -301,7 +303,7 @@ export const apDexMetricsQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Service_name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -312,7 +314,7 @@ export const apDexMetricsQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Operation,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -327,7 +329,7 @@ export const apDexMetricsQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.StatusCode,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -338,7 +340,7 @@ export const apDexMetricsQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Le,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -349,7 +351,7 @@ export const apDexMetricsQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Service_name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -360,7 +362,7 @@ export const apDexMetricsQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Operation,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -375,7 +377,7 @@ export const apDexMetricsQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Le,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -386,7 +388,7 @@ export const apDexMetricsQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.StatusCode,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -397,7 +399,7 @@ export const apDexMetricsQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Service_name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -408,7 +410,7 @@ export const apDexMetricsQueryBuilderQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Operation,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -458,7 +460,7 @@ export const operationPerSec = ({
|
||||
const autocompleteData: BaseAutocompleteData[] = [
|
||||
{
|
||||
key: WidgetKeys.SignozLatencyCount,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
},
|
||||
@ -470,7 +472,7 @@ export const operationPerSec = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Service_name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
@ -481,7 +483,7 @@ export const operationPerSec = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Operation,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -510,13 +512,13 @@ export const errorPercentage = ({
|
||||
}: OperationPerSecProps): QueryBuilderData => {
|
||||
const autocompleteDataA: BaseAutocompleteData = {
|
||||
key: WidgetKeys.SignozCallsTotal,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
};
|
||||
const autocompleteDataB: BaseAutocompleteData = {
|
||||
key: WidgetKeys.SignozCallsTotal,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
};
|
||||
@ -528,7 +530,7 @@ export const errorPercentage = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Service_name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
@ -539,7 +541,7 @@ export const errorPercentage = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Operation,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -550,7 +552,7 @@ export const errorPercentage = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.StatusCode,
|
||||
dataType: DataType.INT64,
|
||||
dataType: DataTypes.Int64,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
@ -565,7 +567,7 @@ export const errorPercentage = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Service_name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
@ -576,7 +578,7 @@ export const errorPercentage = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Operation,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { OPERATORS } from 'constants/queryBuilder';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
BaseAutocompleteData,
|
||||
DataTypes,
|
||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import {
|
||||
DataSource,
|
||||
@ -8,7 +11,6 @@ import {
|
||||
} from 'types/common/queryBuilder';
|
||||
|
||||
import {
|
||||
DataType,
|
||||
GraphTitle,
|
||||
KeyOperationTableHeader,
|
||||
MetricsType,
|
||||
@ -22,21 +24,21 @@ export const topOperationQueries = ({
|
||||
}: TopOperationQueryFactoryProps): QueryBuilderData => {
|
||||
const latencyAutoCompleteData: BaseAutocompleteData = {
|
||||
key: WidgetKeys.Signoz_latency_bucket,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
};
|
||||
|
||||
const errorRateAutoCompleteData: BaseAutocompleteData = {
|
||||
key: WidgetKeys.SignozCallsTotal,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
};
|
||||
|
||||
const numOfCallAutoCompleteData: BaseAutocompleteData = {
|
||||
key: WidgetKeys.SignozLatencyCount,
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
type: '',
|
||||
};
|
||||
@ -46,7 +48,7 @@ export const topOperationQueries = ({
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Service_name,
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
@ -59,7 +61,7 @@ export const topOperationQueries = ({
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Service_name,
|
||||
type: MetricsType.Resource,
|
||||
@ -70,7 +72,7 @@ export const topOperationQueries = ({
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.INT64,
|
||||
dataType: DataTypes.Int64,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.StatusCode,
|
||||
type: MetricsType.Tag,
|
||||
@ -84,7 +86,7 @@ export const topOperationQueries = ({
|
||||
|
||||
const groupBy: BaseAutocompleteData[] = [
|
||||
{
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Operation,
|
||||
type: MetricsType.Tag,
|
||||
|
@ -41,13 +41,6 @@ export enum KeyOperationTableHeader {
|
||||
OPERATION_PR_SECOND = 'Op/s',
|
||||
}
|
||||
|
||||
export enum DataType {
|
||||
STRING = 'string',
|
||||
FLOAT64 = 'float64',
|
||||
INT64 = 'int64',
|
||||
BOOL = 'bool',
|
||||
}
|
||||
|
||||
export enum MetricsType {
|
||||
Tag = 'tag',
|
||||
Resource = 'resource',
|
||||
|
@ -12,6 +12,7 @@ import { useEffect, useState } from 'react';
|
||||
import { SuccessResponse } from 'types/api';
|
||||
import { ILog } from 'types/api/logs/log';
|
||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { EQueryType } from 'types/common/dashboard';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
@ -43,7 +44,7 @@ export default function LogsConnectionStatus({
|
||||
aggregateOperator: 'noop',
|
||||
aggregateAttribute: {
|
||||
id: '------false',
|
||||
dataType: '',
|
||||
dataType: DataTypes.EMPTY,
|
||||
key: '',
|
||||
isColumn: false,
|
||||
type: '',
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
initialQueryBuilderFormValuesMap,
|
||||
} from 'constants/queryBuilder';
|
||||
import { transformFromStringToHaving } from 'lib/query/transformQueryBuilderData';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
// ** Types
|
||||
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
||||
|
||||
@ -19,7 +20,7 @@ const valueWithAttributeAndOperator: IBuilderQuery = {
|
||||
isColumn: false,
|
||||
key: 'bytes',
|
||||
type: 'tag',
|
||||
dataType: 'float64',
|
||||
dataType: DataTypes.Float64,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { Select, Spin, Tag, Tooltip } from 'antd';
|
||||
import { OPERATORS } from 'constants/queryBuilder';
|
||||
import { getDataTypes } from 'container/LogDetailedView/utils';
|
||||
import {
|
||||
useAutoComplete,
|
||||
WhereClauseConfig,
|
||||
@ -12,7 +14,10 @@ import {
|
||||
useEffect,
|
||||
useMemo,
|
||||
} from 'react';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
BaseAutocompleteData,
|
||||
DataTypes,
|
||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
IBuilderQuery,
|
||||
TagFilter,
|
||||
@ -80,15 +85,22 @@ function QueryBuilderSearch({
|
||||
handleSearch(value);
|
||||
};
|
||||
|
||||
const isDisabled =
|
||||
!!searchValue ||
|
||||
OPERATORS.HAS === tagOperator ||
|
||||
OPERATORS.NHAS === tagOperator;
|
||||
|
||||
return (
|
||||
<Tag closable={!searchValue && closable} onClose={onCloseHandler}>
|
||||
<Tooltip title={chipValue}>
|
||||
<TypographyText
|
||||
ellipsis
|
||||
$isInNin={isInNin}
|
||||
disabled={!!searchValue}
|
||||
disabled={isDisabled}
|
||||
$isEnabled={!!searchValue}
|
||||
onClick={(): void => tagEditHandler(value)}
|
||||
onClick={(): void => {
|
||||
if (!isDisabled) tagEditHandler(value);
|
||||
}}
|
||||
>
|
||||
{chipValue}
|
||||
</TypographyText>
|
||||
@ -119,6 +131,14 @@ function QueryBuilderSearch({
|
||||
[query.dataSource],
|
||||
);
|
||||
|
||||
const fetchValueDataType = (value: unknown, operator: string): DataTypes => {
|
||||
if (operator === OPERATORS.HAS || operator === OPERATORS.NHAS) {
|
||||
return getDataTypes([value]);
|
||||
}
|
||||
|
||||
return DataTypes.EMPTY;
|
||||
};
|
||||
|
||||
const queryTags = useMemo(() => {
|
||||
if (!query.aggregateAttribute.key && isMetricsDataSource) return [];
|
||||
return tags;
|
||||
@ -129,26 +149,35 @@ function QueryBuilderSearch({
|
||||
const initialSourceKeys = query.filters.items?.map(
|
||||
(item) => item.key as BaseAutocompleteData,
|
||||
);
|
||||
initialTagFilters.items = tags.map((tag) => {
|
||||
|
||||
initialTagFilters.items = tags.map((tag, index) => {
|
||||
const isJsonTrue = query.filters?.items[index]?.key?.isJSON;
|
||||
|
||||
const { tagKey, tagOperator, tagValue } = getTagToken(tag);
|
||||
|
||||
const filterAttribute = [...initialSourceKeys, ...sourceKeys].find(
|
||||
(key) => key.key === getRemovePrefixFromKey(tagKey),
|
||||
);
|
||||
|
||||
const computedTagValue =
|
||||
tagValue && Array.isArray(tagValue) && tagValue[tagValue.length - 1] === ''
|
||||
? tagValue?.slice(0, -1)
|
||||
: tagValue ?? '';
|
||||
|
||||
return {
|
||||
id: uuid().slice(0, 8),
|
||||
key: filterAttribute ?? {
|
||||
key: tagKey,
|
||||
dataType: '',
|
||||
dataType: fetchValueDataType(computedTagValue, tagOperator),
|
||||
type: '',
|
||||
isColumn: false,
|
||||
isJSON: isJsonTrue,
|
||||
},
|
||||
op: getOperatorValue(tagOperator),
|
||||
value:
|
||||
tagValue[tagValue.length - 1] === ''
|
||||
? tagValue?.slice(0, -1)
|
||||
: tagValue ?? '',
|
||||
value: computedTagValue,
|
||||
};
|
||||
});
|
||||
|
||||
onChange(initialTagFilters);
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
}, [sourceKeys]);
|
||||
|
@ -3,7 +3,8 @@ import { parse } from 'papaparse';
|
||||
|
||||
import { orderByValueDelimiter } from '../OrderByFilter/utils';
|
||||
|
||||
export const tagRegexp = /([a-zA-Z0-9_.:@$()\-/\\]+)\s*(!=|=|<=|<|>=|>|IN|NOT_IN|LIKE|NOT_LIKE|REGEX|NOT_REGEX|EXISTS|NOT_EXISTS|CONTAINS|NOT_CONTAINS|-->|--!>)\s*([\s\S]*)/g;
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
export const tagRegexp = /^\s*(.*?)\s*(IN|NOT_IN|LIKE|NOT_LIKE|REGEX|NOT_REGEX|=|!=|EXISTS|NOT_EXISTS|CONTAINS|NOT_CONTAINS|>=|>|<=|<|HAS|NHAS)\s*(.*)$/g;
|
||||
|
||||
export function isInNInOperator(value: string): boolean {
|
||||
return value === OPERATORS.IN || value === OPERATORS.NIN;
|
||||
@ -57,6 +58,10 @@ export function getOperatorValue(op: string): string {
|
||||
return 'nin';
|
||||
case OPERATORS.REGEX:
|
||||
return 'regex';
|
||||
case OPERATORS.HAS:
|
||||
return 'has';
|
||||
case OPERATORS.NHAS:
|
||||
return 'nhas';
|
||||
case OPERATORS.NREGEX:
|
||||
return 'nregex';
|
||||
case 'LIKE':
|
||||
@ -98,6 +103,10 @@ export function getOperatorFromValue(op: string): string {
|
||||
return 'CONTAINS';
|
||||
case 'ncontains':
|
||||
return 'NOT_CONTAINS';
|
||||
case 'has':
|
||||
return OPERATORS.HAS;
|
||||
case 'nhas':
|
||||
return OPERATORS.NHAS;
|
||||
default:
|
||||
return op;
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
import { ServiceDataProps } from 'api/metrics/getTopLevelOperations';
|
||||
import { OPERATORS } from 'constants/queryBuilder';
|
||||
import {
|
||||
DataType,
|
||||
KeyOperationTableHeader,
|
||||
MetricsType,
|
||||
WidgetKeys,
|
||||
} from 'container/MetricsApplication/constant';
|
||||
import { getQueryBuilderQuerieswithFormula } from 'container/MetricsApplication/MetricsPageQueries/MetricsPageQueriesFactory';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
BaseAutocompleteData,
|
||||
DataTypes,
|
||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import {
|
||||
DataSource,
|
||||
@ -19,21 +21,21 @@ export const serviceMetricsQuery = (
|
||||
topLevelOperation: [keyof ServiceDataProps, string[]],
|
||||
): QueryBuilderData => {
|
||||
const p99AutoCompleteData: BaseAutocompleteData = {
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
key: WidgetKeys.Signoz_latency_bucket,
|
||||
type: '',
|
||||
};
|
||||
|
||||
const errorRateAutoCompleteData: BaseAutocompleteData = {
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
key: WidgetKeys.SignozCallsTotal,
|
||||
type: '',
|
||||
};
|
||||
|
||||
const operationPrSecondAutoCompleteData: BaseAutocompleteData = {
|
||||
dataType: DataType.FLOAT64,
|
||||
dataType: DataTypes.Float64,
|
||||
isColumn: true,
|
||||
key: WidgetKeys.SignozCallsTotal,
|
||||
type: '',
|
||||
@ -50,7 +52,7 @@ export const serviceMetricsQuery = (
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Service_name,
|
||||
type: MetricsType.Resource,
|
||||
@ -61,7 +63,7 @@ export const serviceMetricsQuery = (
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Operation,
|
||||
type: MetricsType.Tag,
|
||||
@ -75,7 +77,7 @@ export const serviceMetricsQuery = (
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Service_name,
|
||||
type: MetricsType.Resource,
|
||||
@ -86,7 +88,7 @@ export const serviceMetricsQuery = (
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.INT64,
|
||||
dataType: DataTypes.Int64,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.StatusCode,
|
||||
type: MetricsType.Tag,
|
||||
@ -97,7 +99,7 @@ export const serviceMetricsQuery = (
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Operation,
|
||||
type: MetricsType.Tag,
|
||||
@ -111,7 +113,7 @@ export const serviceMetricsQuery = (
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Service_name,
|
||||
type: MetricsType.Resource,
|
||||
@ -122,7 +124,7 @@ export const serviceMetricsQuery = (
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Operation,
|
||||
type: MetricsType.Tag,
|
||||
@ -136,7 +138,7 @@ export const serviceMetricsQuery = (
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Service_name,
|
||||
type: MetricsType.Resource,
|
||||
@ -147,7 +149,7 @@ export const serviceMetricsQuery = (
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Operation,
|
||||
type: MetricsType.Tag,
|
||||
@ -185,7 +187,7 @@ export const serviceMetricsQuery = (
|
||||
|
||||
const groupBy: BaseAutocompleteData[] = [
|
||||
{
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Service_name,
|
||||
type: MetricsType.Tag,
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { MouseEventHandler } from 'react';
|
||||
import { ILog } from 'types/api/logs/log';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
|
||||
export type LogTimeRange = {
|
||||
start: number;
|
||||
@ -20,5 +21,11 @@ export type UseActiveLog = {
|
||||
activeLog: ILog | null;
|
||||
onSetActiveLog: (log: ILog) => void;
|
||||
onClearActiveLog: () => void;
|
||||
onAddToQuery: (fieldKey: string, fieldValue: string, operator: string) => void;
|
||||
onAddToQuery: (
|
||||
fieldKey: string,
|
||||
fieldValue: string,
|
||||
operator: string,
|
||||
isJSON?: boolean,
|
||||
dataType?: DataTypes,
|
||||
) => void;
|
||||
};
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { getAggregateKeys } from 'api/queryBuilder/getAttributeKeys';
|
||||
import { SOMETHING_WENT_WRONG } from 'constants/api';
|
||||
import { QueryBuilderKeys } from 'constants/queryBuilder';
|
||||
import ROUTES from 'constants/routes';
|
||||
import { getOperatorValue } from 'container/QueryBuilder/filters/QueryBuilderSearch/utils';
|
||||
@ -7,14 +8,16 @@ import { useNotifications } from 'hooks/useNotifications';
|
||||
import { getGeneratedFilterQueryString } from 'lib/getGeneratedFilterQueryString';
|
||||
import { chooseAutocompleteFromCustomValue } from 'lib/newQueryBuilder/chooseAutocompleteFromCustomValue';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useQueryClient } from 'react-query';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { SET_DETAILED_LOG_DATA } from 'types/actions/logs';
|
||||
import { ILog } from 'types/api/logs/log';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
BaseAutocompleteData,
|
||||
DataTypes,
|
||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { ILogsReducer } from 'types/reducer/logs';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
@ -33,8 +36,6 @@ export const useActiveLog = (): UseActiveLog => {
|
||||
const { currentQuery, redirectWithQueryBuilderData } = useQueryBuilder();
|
||||
const { notifications } = useNotifications();
|
||||
|
||||
const { t } = useTranslation('common');
|
||||
|
||||
const isLogsPage = useMemo(() => pathname === ROUTES.LOGS, [pathname]);
|
||||
|
||||
const [activeLog, setActiveLog] = useState<ILog | null>(null);
|
||||
@ -67,6 +68,8 @@ export const useActiveLog = (): UseActiveLog => {
|
||||
fieldKey: string,
|
||||
fieldValue: string,
|
||||
operator: string,
|
||||
isJSON?: boolean,
|
||||
dataType?: DataTypes,
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const keysAutocompleteResponse = await queryClient.fetchQuery(
|
||||
@ -87,6 +90,8 @@ export const useActiveLog = (): UseActiveLog => {
|
||||
const existAutocompleteKey = chooseAutocompleteFromCustomValue(
|
||||
keysAutocomplete,
|
||||
fieldKey,
|
||||
isJSON,
|
||||
dataType,
|
||||
);
|
||||
|
||||
const currentOperator = getOperatorValue(operator);
|
||||
@ -100,9 +105,7 @@ export const useActiveLog = (): UseActiveLog => {
|
||||
filters: {
|
||||
...item.filters,
|
||||
items: [
|
||||
...item.filters.items.filter(
|
||||
(item) => item.key?.id !== existAutocompleteKey.id,
|
||||
),
|
||||
...item.filters.items,
|
||||
{
|
||||
id: uuid(),
|
||||
key: existAutocompleteKey,
|
||||
@ -117,10 +120,10 @@ export const useActiveLog = (): UseActiveLog => {
|
||||
|
||||
redirectWithQueryBuilderData(nextQuery);
|
||||
} catch {
|
||||
notifications.error({ message: t('something_went_wrong') });
|
||||
notifications.error({ message: SOMETHING_WENT_WRONG });
|
||||
}
|
||||
},
|
||||
[currentQuery, notifications, queryClient, redirectWithQueryBuilderData, t],
|
||||
[currentQuery, notifications, queryClient, redirectWithQueryBuilderData],
|
||||
);
|
||||
|
||||
const onAddToQueryLogs = useCallback(
|
||||
|
@ -9,7 +9,10 @@ import useDebounceValue from 'hooks/useDebounce';
|
||||
import { isEqual, uniqWith } from 'lodash-es';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useDebounce } from 'react-use';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
BaseAutocompleteData,
|
||||
DataTypes,
|
||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
|
||||
@ -109,7 +112,7 @@ export const useFetchKeysAndValues = (
|
||||
dataSource: query.dataSource,
|
||||
aggregateAttribute: query.aggregateAttribute.key,
|
||||
attributeKey: filterAttributeKey?.key ?? tagKey,
|
||||
filterAttributeKeyDataType: filterAttributeKey?.dataType ?? '',
|
||||
filterAttributeKeyDataType: filterAttributeKey?.dataType ?? DataTypes.EMPTY,
|
||||
tagType: filterAttributeKey?.type ?? '',
|
||||
searchText: isInNInOperator(tagOperator)
|
||||
? tagValue[tagValue.length - 1]?.toString() ?? '' // last element of tagvalue will be always user search value
|
||||
|
@ -23,6 +23,8 @@ const operatorTypeMapper: Record<string, OperatorType> = {
|
||||
[OPERATORS.NOT_CONTAINS]: 'SINGLE_VALUE',
|
||||
[OPERATORS['=']]: 'SINGLE_VALUE',
|
||||
[OPERATORS['!=']]: 'SINGLE_VALUE',
|
||||
[OPERATORS.HAS]: 'SINGLE_VALUE',
|
||||
[OPERATORS.NHAS]: 'SINGLE_VALUE',
|
||||
};
|
||||
|
||||
export const useOperatorType = (operator: string): OperatorType =>
|
||||
|
@ -17,6 +17,8 @@ export const useOperators = (
|
||||
useMemo(() => {
|
||||
const currentKey = keys?.find((el) => el.key === getRemovePrefixFromKey(key));
|
||||
return currentKey?.dataType
|
||||
? QUERY_BUILDER_OPERATORS_BY_TYPES[currentKey.dataType]
|
||||
? QUERY_BUILDER_OPERATORS_BY_TYPES[
|
||||
currentKey.dataType as keyof typeof QUERY_BUILDER_OPERATORS_BY_TYPES
|
||||
]
|
||||
: QUERY_BUILDER_OPERATORS_BY_TYPES.universal;
|
||||
}, [keys, key]);
|
||||
|
@ -4,7 +4,7 @@ import {
|
||||
} from 'api/metrics/getResourceAttributes';
|
||||
import { OperatorConversions } from 'constants/resourceAttributes';
|
||||
import ROUTES from 'constants/routes';
|
||||
import { DataType, MetricsType } from 'container/MetricsApplication/constant';
|
||||
import { MetricsType } from 'container/MetricsApplication/constant';
|
||||
import {
|
||||
IOption,
|
||||
IResourceAttribute,
|
||||
@ -12,6 +12,7 @@ import {
|
||||
} from 'hooks/useResourceAttribute/types';
|
||||
import { decode } from 'js-base64';
|
||||
import history from 'lib/history';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { OperatorValues, Tags } from 'types/reducer/trace';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
@ -72,7 +73,7 @@ export const resourceAttributesToTagFilterItems = (
|
||||
op: e.Operator,
|
||||
value: e.StringValues,
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
dataType: DataTypes.String,
|
||||
type: MetricsType.Resource,
|
||||
isColumn: false,
|
||||
key: e.Key,
|
||||
@ -82,7 +83,12 @@ export const resourceAttributesToTagFilterItems = (
|
||||
|
||||
return queries.map((res) => ({
|
||||
id: `${res.id}`,
|
||||
key: { key: res.tagKey, isColumn: false, type: '', dataType: '' },
|
||||
key: {
|
||||
key: res.tagKey,
|
||||
isColumn: false,
|
||||
type: '',
|
||||
dataType: DataTypes.EMPTY,
|
||||
},
|
||||
op: `${res.operator}`,
|
||||
value: `${res.tagValue}`.split(','),
|
||||
}));
|
||||
|
@ -1,16 +1,26 @@
|
||||
import { initialAutocompleteData } from 'constants/queryBuilder';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
BaseAutocompleteData,
|
||||
DataTypes,
|
||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
|
||||
export const chooseAutocompleteFromCustomValue = (
|
||||
sourceList: BaseAutocompleteData[],
|
||||
value: string,
|
||||
isJSON?: boolean,
|
||||
dataType?: DataTypes,
|
||||
): BaseAutocompleteData => {
|
||||
const firstBaseAutoCompleteValue = sourceList.find(
|
||||
(sourceAutoComplete) => value === sourceAutoComplete.key,
|
||||
);
|
||||
|
||||
if (!firstBaseAutoCompleteValue) {
|
||||
return { ...initialAutocompleteData, key: value, dataType: 'string' };
|
||||
return {
|
||||
...initialAutocompleteData,
|
||||
key: value,
|
||||
dataType: dataType || DataTypes.EMPTY,
|
||||
isJSON,
|
||||
};
|
||||
}
|
||||
|
||||
return firstBaseAutoCompleteValue;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
IBuilderQuery,
|
||||
OrderByPayload,
|
||||
@ -47,7 +48,7 @@ export const getPaginationQueryData: SetupPaginationQueryData = ({
|
||||
key: {
|
||||
key: 'id',
|
||||
type: '',
|
||||
dataType: 'string',
|
||||
dataType: DataTypes.String,
|
||||
isColumn: true,
|
||||
},
|
||||
op: orderByTimestamp.order === FILTERS.ASC ? '>' : '<',
|
||||
|
@ -22,12 +22,10 @@ function NewDashboardPage({ getDashboard }: NewDashboardProps): JSX.Element {
|
||||
const { dashboardId } = useParams<Params>();
|
||||
|
||||
useEffect(() => {
|
||||
if (dashboards.length !== 1) {
|
||||
getDashboard({
|
||||
uuid: dashboardId,
|
||||
});
|
||||
}
|
||||
}, [getDashboard, dashboardId, dashboards.length]);
|
||||
getDashboard({
|
||||
uuid: dashboardId,
|
||||
});
|
||||
}, [getDashboard, dashboardId]);
|
||||
|
||||
if (
|
||||
error &&
|
||||
|
@ -1,15 +1,26 @@
|
||||
export type LocalDataType = 'number' | 'string' | 'bool';
|
||||
export enum DataTypes {
|
||||
Int64 = 'int64',
|
||||
String = 'string',
|
||||
Float64 = 'float64',
|
||||
bool = 'bool',
|
||||
ArrayFloat64 = 'array(float64)',
|
||||
ArrayInt64 = 'array(int64)',
|
||||
ArrayString = 'array(string)',
|
||||
ArrayBool = 'array(bool)',
|
||||
EMPTY = '',
|
||||
}
|
||||
|
||||
export type DataType = 'int64' | 'float64' | 'string' | 'bool' | '';
|
||||
export type LocalDataType = 'number' | 'string' | 'bool';
|
||||
|
||||
export type AutocompleteType = 'tag' | 'resource' | '';
|
||||
|
||||
export interface BaseAutocompleteData {
|
||||
id?: string;
|
||||
dataType: DataType;
|
||||
dataType: DataTypes;
|
||||
isColumn: boolean;
|
||||
key: string;
|
||||
type: AutocompleteType | string | null;
|
||||
isJSON?: boolean;
|
||||
}
|
||||
|
||||
export interface IQueryAutocompleteResponse {
|
||||
|
Loading…
x
Reference in New Issue
Block a user