Skip to content

Commit

Permalink
Feat: fe: logs pipelines severity parsing processor (#4149)
Browse files Browse the repository at this point in the history
  • Loading branch information
raj-k-singh authored Dec 5, 2023
1 parent 4644b1c commit 112783d
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Input, InputProps } from 'antd';
import { ChangeEventHandler, useState } from 'react';

function CSVInput({ value, onChange, ...otherProps }: InputProps): JSX.Element {
const [inputValue, setInputValue] = useState(
((value as string[]) || []).join(', '),
);

const onChangeHandler = (onChange as unknown) as (v: string[]) => void;

const onInputChange: ChangeEventHandler<HTMLInputElement> = (e) => {
const newValue = e.target.value;
setInputValue(newValue);

if (onChangeHandler) {
const splitValues = newValue.split(',').map((v) => v.trim());
onChangeHandler(splitValues);
}
};

// eslint-disable-next-line react/jsx-props-no-spreading
return <Input value={inputValue} onChange={onInputChange} {...otherProps} />;
}

export default CSVInput;
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import './styles.scss';

import { Form, Input, Select } from 'antd';
import { ModalFooterTitle } from 'container/PipelinePage/styles';
import { useTranslation } from 'react-i18next';

import { formValidationRules } from '../config';
import { processorFields, ProcessorFormField } from './config';
import {
Container,
FormWrapper,
PipelineIndexIcon,
StyledSelect,
} from './styles';
import CSVInput from './FormFields/CSVInput';
import { FormWrapper, PipelineIndexIcon, StyledSelect } from './styles';

function ProcessorFieldInput({
fieldData,
Expand All @@ -25,35 +23,63 @@ function ProcessorFieldInput({
return null;
}

// Do not render display elements for hidden inputs.
if (fieldData?.hidden) {
return (
<Form.Item
name={fieldData.name}
initialValue={fieldData.initialValue}
dependencies={fieldData.dependencies || []}
style={{ display: 'none' }}
>
<Input type="hidden" />
</Form.Item>
);
}

let inputField;
if (fieldData?.options) {
inputField = (
<StyledSelect>
{fieldData.options.map(({ value, label }) => (
<Select.Option key={value + label} value={value}>
{label}
</Select.Option>
))}
</StyledSelect>
);
} else if (Array.isArray(fieldData?.initialValue)) {
inputField = <CSVInput placeholder={t(fieldData.placeholder)} />;
} else {
inputField = <Input placeholder={t(fieldData.placeholder)} />;
}

return (
<Container>
<PipelineIndexIcon size="small">
{Number(fieldData.id) + 1}
</PipelineIndexIcon>
<div
className={
fieldData?.compact
? 'compact-processor-field-container'
: 'processor-field-container'
}
>
{!fieldData?.compact && (
<PipelineIndexIcon size="small">
{Number(fieldData.id) + 1}
</PipelineIndexIcon>
)}
<FormWrapper>
<Form.Item
required={false}
label={<ModalFooterTitle>{fieldData.fieldName}</ModalFooterTitle>}
key={fieldData.id}
name={fieldData.name}
initialValue={fieldData.initialValue}
rules={fieldData.rules ? fieldData.rules : formValidationRules}
dependencies={fieldData.dependencies || []}
>
{fieldData?.options ? (
<StyledSelect>
{fieldData.options.map(({ value, label }) => (
<Select.Option key={value + label} value={value}>
{label}
</Select.Option>
))}
</StyledSelect>
) : (
<Input placeholder={t(fieldData.placeholder)} />
)}
{inputField}
</Form.Item>
</FormWrapper>
</Container>
</div>
);
}

Expand All @@ -63,9 +89,12 @@ interface ProcessorFieldInputProps {

function ProcessorForm({ processorType }: ProcessorFormProps): JSX.Element {
return (
<div>
<div className="processor-form-container">
{processorFields[processorType]?.map((fieldData: ProcessorFormField) => (
<ProcessorFieldInput key={fieldData.id} fieldData={fieldData} />
<ProcessorFieldInput
key={fieldData.name + String(fieldData.initialValue)}
fieldData={fieldData}
/>
))}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const processorTypes: Array<ProcessorType> = [
{ key: 'json_parser', value: 'json_parser', label: 'Json Parser' },
{ key: 'trace_parser', value: 'trace_parser', label: 'Trace Parser' },
{ key: 'time_parser', value: 'time_parser', label: 'Timestamp Parser' },
{ key: 'severity_parser', value: 'severity_parser', label: 'Severity Parser' },
{ key: 'add', value: 'add', label: 'Add' },
{ key: 'remove', value: 'remove', label: 'Remove' },
// { key: 'retain', value: 'retain', label: 'Retain' }, @Chintan - Commented as per Nitya's suggestion
Expand All @@ -31,20 +32,26 @@ export type ProcessorFieldOption = {
value: string;
};

// TODO(Raj): Refactor Processor Form code after putting e2e UI tests in place.
export type ProcessorFormField = {
id: number;
fieldName: string;
placeholder: string;
name: string | NamePath;
rules?: Array<Rule>;
initialValue?: string;
hidden?: boolean;
initialValue?: boolean | string | Array<string>;
dependencies?: Array<string | NamePath>;
options?: Array<ProcessorFieldOption>;
shouldRender?: (form: FormInstance) => boolean;
onFormValuesChanged?: (
changedValues: ProcessorData,
form: FormInstance,
) => void;

// Should this field have its own row or should it
// be packed with other compact fields.
compact?: boolean;
};

const traceParserFieldValidator: RuleRender = (form) => ({
Expand Down Expand Up @@ -317,6 +324,85 @@ export const processorFields: { [key: string]: Array<ProcessorFormField> } = {
initialValue: '%Y-%m-%dT%H:%M:%S.%f%z',
},
],
severity_parser: [
{
id: 1,
fieldName: 'Name of Severity Parsing Processor',
placeholder: 'processor_name_placeholder',
name: 'name',
},
{
id: 2,
fieldName: 'Parse Severity Value From',
placeholder: 'processor_parsefrom_placeholder',
name: 'parse_from',
initialValue: 'attributes.logLevel',
},
{
id: 3,
fieldName: 'Values for level TRACE',
placeholder: 'Specify comma separated values. Eg: trace, 0',
name: ['mapping', 'trace'],
rules: [],
initialValue: ['trace'],
compact: true,
},
{
id: 4,
fieldName: 'Values for level DEBUG',
placeholder: 'Specify comma separated values. Eg: debug, 2xx',
name: ['mapping', 'debug'],
rules: [],
initialValue: ['debug'],
compact: true,
},
{
id: 5,
fieldName: 'Values for level INFO',
placeholder: 'Specify comma separated values. Eg: info, 3xx',
name: ['mapping', 'info'],
rules: [],
initialValue: ['info'],
compact: true,
},
{
id: 6,
fieldName: 'Values for level WARN',
placeholder: 'Specify comma separated values. Eg: warning, 4xx',
name: ['mapping', 'warn'],
rules: [],
initialValue: ['warn'],
compact: true,
},
{
id: 7,
fieldName: 'Values for level ERROR',
placeholder: 'Specify comma separated values. Eg: error, 5xx',
name: ['mapping', 'error'],
rules: [],
initialValue: ['error'],
compact: true,
},
{
id: 8,
fieldName: 'Values for level FATAL',
placeholder: 'Specify comma separated values. Eg: fatal, panic',
name: ['mapping', 'fatal'],
rules: [],
initialValue: ['fatal'],
compact: true,
},
{
id: 9,
fieldName: 'Override Severity Text',
placeholder:
'Should the parsed severity set both severity and severityText?',
name: ['overwrite_text'],
rules: [],
initialValue: true,
hidden: true,
},
],
retain: [
{
id: 1,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

.processor-form-container {
position: relative;
width: 100%;

display: flex;
flex-wrap: wrap
}

.processor-field-container {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0rem;
gap: 1rem;
width: 100%;
}

.compact-processor-field-container {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 0rem;
min-width: 40%;
flex-grow: 1;
margin-left: 2.5rem;
}
8 changes: 7 additions & 1 deletion frontend/src/pages/Pipelines/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import Spinner from 'components/Spinner';
import ChangeHistory from 'container/PipelinePage/Layouts/ChangeHistory';
import PipelinePage from 'container/PipelinePage/Layouts/Pipeline';
import { useNotifications } from 'hooks/useNotifications';
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
import { useEffect, useMemo } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { useTranslation } from 'react-i18next';
import { useQuery } from 'react-query';
import { SuccessResponse } from 'types/api';
Expand Down Expand Up @@ -77,7 +79,11 @@ function Pipelines(): JSX.Element {
return <Spinner height="75vh" tip="Loading Pipelines..." />;
}

return <Tabs defaultActiveKey="pipelines" items={tabItems} />;
return (
<ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
<Tabs defaultActiveKey="pipelines" items={tabItems} />;
</ErrorBoundary>
);
}

export default Pipelines;

0 comments on commit 112783d

Please sign in to comment.