Skip to content
This repository has been archived by the owner on Aug 9, 2022. It is now read-only.

Allow filtering by traceGroup and service #28

Merged
merged 28 commits into from
Mar 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b72722b
Move service map to dashboard
joshuali925 Mar 18, 2021
7113b02
Add back filters
joshuali925 Mar 18, 2021
382696a
Remove services table search bar
joshuali925 Mar 19, 2021
b7203c4
Add service map filter
joshuali925 Mar 19, 2021
a30102a
Fix percentile
joshuali925 Mar 19, 2021
31c894b
Make unrelated services transparent
joshuali925 Mar 19, 2021
1bbefbd
Update jest tests
joshuali925 Mar 19, 2021
a3e5a27
Fix trace count in dashboard
joshuali925 Mar 22, 2021
4c304cd
Fix ticks
joshuali925 Mar 22, 2021
fa06dc1
Fix parent span query
joshuali925 Mar 22, 2021
6a07145
Fix trace group filters for service map
joshuali925 Mar 22, 2021
a2eb48c
Revert plot query filters
joshuali925 Mar 22, 2021
ab90980
Use trace count in histogram
joshuali925 Mar 23, 2021
1208402
Use trace count in error rate histogram
joshuali925 Mar 23, 2021
0d3e638
Rename plots
joshuali925 Mar 23, 2021
9da0162
services view respecting filters
joshuali925 Mar 23, 2021
f28a571
Add special case for latency and errors filter
joshuali925 Mar 23, 2021
61794a6
Fix service map color calculation
joshuali925 Mar 23, 2021
90617d9
Fix error rate plot query
joshuali925 Mar 24, 2021
9ed0de7
Rename traceGroup field to traceGroup.name
joshuali925 Mar 25, 2021
6c98a8d
Update dashboard queries to calculate on parent span level
joshuali925 Mar 25, 2021
b8c3cd0
Update filter fields to use parent span latency and errors
joshuali925 Mar 25, 2021
dba3a5b
Update traces queries to calculate on parent span level
joshuali925 Mar 25, 2021
0993774
Update jest
joshuali925 Mar 25, 2021
4d464b3
Fix percentile filter DSL
joshuali925 Mar 25, 2021
4e7d033
UX changes
joshuali925 Mar 25, 2021
9108d5a
Fix service map query targetResource to use traceGroup.name
joshuali925 Mar 26, 2021
4b7496f
Update jest tests
joshuali925 Mar 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ exports[`Search bar components renders search bar 1`] = `
isLoading={false}
onChange={[Function]}
onSearch={[MockFunction]}
placeholder="Trace ID, trace group name"
placeholder="Trace ID, trace group name, service name"
value="test"
>
<EuiFormControlLayout
Expand All @@ -433,7 +433,7 @@ exports[`Search bar components renders search bar 1`] = `
data-test-subj="search-bar-input-box"
onChange={[Function]}
onKeyUp={[Function]}
placeholder="Trace ID, trace group name"
placeholder="Trace ID, trace group name, service name"
type="search"
value="test"
/>
Expand Down
10 changes: 5 additions & 5 deletions public/components/common/__tests__/helper_functions.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,13 @@ describe('Helper functions', () => {
);
expect(DSL).toEqual(
JSON.parse(
`{"field":"Latency percentile within trace group","operator":"","value":">= 95th","inverted":false,"disabled":false,"custom":{"query":{"bool":{"must":[],"filter":[],"should":[{"bool":{"must":[{"term":{"name":{"value":"order"}}},{"range":{"durationInNanos":{"gte":1000}}}]}}],"must_not":[],"minimum_should_match":1}}}}`
`{"field":"Latency percentile within trace group","operator":"","value":">= 95th","inverted":false,"disabled":false,"custom":{"query":{"bool":{"must":[],"filter":[],"should":[{"bool":{"must":[{"term":{"traceGroup.name":{"value":"order"}}},{"range":{"traceGroup.durationInNanos":{"gte":1000}}}]}}],"must_not":[],"minimum_should_match":1}}}}`
)
);
});

it('converts filters to DSL', () => {
const getTestFilters = (field = 'traceGroup', operator = 'exists') => [
const getTestFilters = (field = 'traceGroup.name', operator = 'exists') => [
[
{
field,
Expand All @@ -139,12 +139,12 @@ describe('Helper functions', () => {
];
const existsDSL = filtersToDsl(...getTestFilters());
expect(JSON.stringify(existsDSL)).toEqual(
`{"query":{"bool":{"must":[{"range":{"startTime":{"gte":"now-5m","lte":"now"}}},{"query_string":{"query":"order"}},{"exists":{"field":"traceGroup"}}],"filter":[],"should":[],"must_not":[]}},"custom":{"timeFilter":[{"range":{"startTime":{"gte":"now-5m","lte":"now"}}}],"serviceNames":[],"serviceNamesExclude":[],"traceGroup":[{"from":"100","to":"∞"}],"traceGroupExclude":[],"percentiles":{"query":{"bool":{"should":[]}}}}}`
"{\"query\":{\"bool\":{\"must\":[{\"range\":{\"startTime\":{\"gte\":\"now-5m\",\"lte\":\"now\"}}},{\"query_string\":{\"query\":\"order\"}},{\"exists\":{\"field\":\"traceGroup.name\"}}],\"filter\":[],\"should\":[],\"must_not\":[]}},\"custom\":{\"timeFilter\":[{\"range\":{\"startTime\":{\"gte\":\"now-5m\",\"lte\":\"now\"}}}],\"serviceNames\":[],\"serviceNamesExclude\":[],\"traceGroup\":[],\"traceGroupExclude\":[],\"percentiles\":{\"query\":{\"bool\":{\"should\":[]}}}}}"
);

const isDSL = filtersToDsl(...getTestFilters('traceGroup', 'is'));
const isDSL = filtersToDsl(...getTestFilters('traceGroup.name', 'is'));
expect(JSON.stringify(isDSL)).toEqual(
`{"query":{"bool":{"must":[{"range":{"startTime":{"gte":"now-5m","lte":"now"}}},{"query_string":{"query":"order"}},{"term":{"traceGroup":{"from":"100","to":"∞"}}}],"filter":[],"should":[],"must_not":[]}},"custom":{"timeFilter":[{"range":{"startTime":{"gte":"now-5m","lte":"now"}}}],"serviceNames":[],"serviceNamesExclude":[],"traceGroup":[{"from":"100","to":"∞"}],"traceGroupExclude":[],"percentiles":{"query":{"bool":{"should":[]}}}}}`
"{\"query\":{\"bool\":{\"must\":[{\"range\":{\"startTime\":{\"gte\":\"now-5m\",\"lte\":\"now\"}}},{\"query_string\":{\"query\":\"order\"}},{\"term\":{\"traceGroup.name\":{\"from\":\"100\",\"to\":\"∞\"}}}],\"filter\":[],\"should\":[],\"must_not\":[]}},\"custom\":{\"timeFilter\":[{\"range\":{\"startTime\":{\"gte\":\"now-5m\",\"lte\":\"now\"}}}],\"serviceNames\":[],\"serviceNamesExclude\":[],\"traceGroup\":[],\"traceGroupExclude\":[],\"percentiles\":{\"query\":{\"bool\":{\"should\":[]}}}}}"
);
const isBetweenDSL = filtersToDsl(...getTestFilters('durationInNanos', 'is between'));
expect(JSON.stringify(isBetweenDSL)).toEqual(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ exports[`Filter popover component renders filter popover 1`] = `
filterFieldOptions={
Array [
Object {
"label": "traceGroup",
"label": "traceGroup.name",
},
Object {
"label": "status.code",
"label": "serviceName",
},
Object {
"label": "error",
},
Object {
"label": "status.message",
},
Object {
"label": "durationInNanos",
"label": "latency",
},
]
}
Expand Down Expand Up @@ -97,16 +100,19 @@ exports[`Filter popover component renders filter popover 1`] = `
options={
Array [
Object {
"label": "traceGroup",
"label": "traceGroup.name",
},
Object {
"label": "serviceName",
},
Object {
"label": "status.code",
"label": "error",
},
Object {
"label": "status.message",
},
Object {
"label": "durationInNanos",
"label": "latency",
},
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('Filter popover component', () => {
wrapper
.find('input')
.at(0)
.simulate('change', [{ label: 'traceGroup' }]);
.simulate('change', [{ label: 'traceGroup.name' }]);
wrapper
.find('input')
.at(1)
Expand Down
35 changes: 22 additions & 13 deletions public/components/common/filters/__tests__/filter_helpers.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
getFilterFields,
getInvertedOperator,
getOperatorOptions,
getType,
getValidFilterFields,
getValueComponent,
} from '../filter_helpers';
Expand All @@ -29,25 +28,33 @@ describe('Filter helper functions', () => {

it('returns fields by page', () => {
const fields = getFilterFields('dashboard');
expect(fields).toEqual(['traceGroup', 'status.code', 'status.message', 'durationInNanos']);
expect(fields).toEqual([
'traceGroup.name',
'serviceName',
'error',
'status.message',
'latency',
]);
});

it('returns valid fields by page', () => {
const dashboardFields = getValidFilterFields('dashboard');
const servicesFields = getValidFilterFields('services');
expect(dashboardFields).toEqual([
'traceGroup',
'status.code',
'traceGroup.name',
'serviceName',
'error',
'status.message',
'durationInNanos',
'latency',
'Latency percentile within trace group',
]);
expect(servicesFields).toEqual([]);
});

it('returns types by fields', () => {
const durationType = getType('durationInNanos');
expect(durationType).toEqual('long');
expect(servicesFields).toEqual([
'traceGroup.name',
'serviceName',
'error',
'status.message',
'latency',
]);
});

it('returns inverted operators', () => {
Expand Down Expand Up @@ -85,7 +92,7 @@ describe('Filter helper functions', () => {

it('renders textfield filter', () => {
const setValue = jest.fn((v) => {});
const wrapper = mount(getValueComponent('is', 0, setValue));
const wrapper = mount(getValueComponent('serviceName', 'is', 0, setValue));
expect(wrapper).toMatchSnapshot();

wrapper.find('input').simulate('change', { target: { value: '100' } });
Expand All @@ -94,7 +101,9 @@ describe('Filter helper functions', () => {

it('renders range field filter', () => {
const setValue = jest.fn((v) => {});
const wrapper = mount(getValueComponent('is not between', { from: '0', to: '100' }, setValue));
const wrapper = mount(
getValueComponent('latency', 'is not between', { from: '0', to: '100' }, setValue)
);
expect(wrapper).toMatchSnapshot();

wrapper
Expand Down
12 changes: 10 additions & 2 deletions public/components/common/filters/filter_edit_popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,19 @@ export function FilterEditPopover(props: {
</EuiFlexItem>
</EuiFlexGroup>
{selectedOperatorOptions.length > 0 &&
getValueComponent(selectedOperatorOptions[0].label, filterValue, setFilterValue)}
getValueComponent(
selectedFieldOptions[0].label,
selectedOperatorOptions[0].label,
filterValue,
setFilterValue
)}
<EuiSpacer size="m" />
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<EuiButtonEmpty data-test-subj="filter-popover-cancel-button" onClick={props.closePopover}>
<EuiButtonEmpty
data-test-subj="filter-popover-cancel-button"
onClick={props.closePopover}
>
Cancel
</EuiButtonEmpty>
</EuiFlexItem>
Expand Down
60 changes: 47 additions & 13 deletions public/components/common/filters/filter_helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@
* permissions and limitations under the License.
*/

import { EuiFieldText, EuiFormControlLayoutDelimited, EuiFormRow, EuiSpacer } from '@elastic/eui';
import {
EuiComboBox,
EuiFieldText,
EuiFormControlLayoutDelimited,
EuiFormRow,
EuiSpacer,
} from '@elastic/eui';
import _ from 'lodash';
import React from 'react';

const getFields = (page) =>
const getFields = (page: 'dashboard' | 'traces' | 'services') =>
({
dashboard: ['traceGroup', 'status.code', 'status.message', 'durationInNanos'],
traces: [
'traceId',
'traceGroup',
'status.code',
'status.message',
'durationInNanos',
],
services: [],
dashboard: ['traceGroup.name', 'serviceName', 'error', 'status.message', 'latency'],
traces: ['traceId', 'traceGroup.name', 'serviceName', 'error', 'status.message', 'latency'],
services: ['traceGroup.name', 'serviceName', 'error', 'status.message', 'latency'],
}[page]);
// filters will take effect and can be manually added
export const getFilterFields = (page: 'dashboard' | 'traces' | 'services') => getFields(page);
Expand All @@ -38,7 +38,7 @@ export const getValidFilterFields = (page: 'dashboard' | 'traces' | 'services')
return fields;
};

export const getType = (field: string): string => {
const getType = (field: string): string => {
const typeMapping = {
attributes: {
host: {
Expand All @@ -63,6 +63,7 @@ export const getType = (field: string): string => {
port: 'long',
},
durationInNanos: 'long',
latency: 'long',
endTime: 'date_nanos',
startTime: 'date_nanos',
};
Expand Down Expand Up @@ -121,7 +122,12 @@ export const getOperatorOptions = (field: string) => {
return operators;
};

export const getValueComponent = (operator: string, value: any, setValue: (v: any) => void) => {
export const getValueComponent = (
field: string,
operator: string,
value: any,
setValue: (v: any) => void
) => {
const textField = (
<>
<EuiSpacer size="s" />
Expand Down Expand Up @@ -183,6 +189,34 @@ export const getValueComponent = (operator: string, value: any, setValue: (v: an
);
};

const getComboBoxField = () => {
return (
<>
<EuiSpacer size="s" />
<EuiFormRow label={'Value'}>
<EuiComboBox
placeholder="Select a value"
options={[
{
label: 'true',
},
{
label: 'false',
},
]}
onChange={setValue}
selectedOptions={value || []}
singleSelection={true}
/>
</EuiFormRow>
</>
);
};

if (field === 'error' && (operator === 'is' || operator === 'is not')) {
return getComboBoxField();
}

const valueMapping = {
is: textField,
'is not': textField,
Expand Down
4 changes: 3 additions & 1 deletion public/components/common/filters/filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,9 @@ export function Filters(props: FiltersOwnProps) {
const value =
typeof filter.value === 'string'
? filter.value
: `${filter.value.from} to ${filter.value.to}`;
: Array.isArray(filter.value) // combo box
? filter.value[0].label
: `${filter.value.from} to ${filter.value.to}`; // range selector
const filterLabel = filter.inverted ? (
<>
<EuiTextColor color={disabled ? 'default' : 'danger'}>{'NOT '}</EuiTextColor>
Expand Down
Loading