mirror of
https://github.com/grafana/grafana.git
synced 2025-01-27 08:47:12 -06:00
Elasticsearch: add additional settings section (#71037)
* Elasticsearch: add additional settings section * Remove extra lines * Elastic config: add divider between name and http settings * Data links: fix subsection title * Remove unused import
This commit is contained in:
parent
7fed3f84f6
commit
d153fd434a
@ -2,7 +2,9 @@ import React, { useEffect, useRef } from 'react';
|
||||
|
||||
import { SIGV4ConnectionConfig } from '@grafana/aws-sdk';
|
||||
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
||||
import { ConfigSection } from '@grafana/experimental';
|
||||
import { Alert, DataSourceHttpSettings } from '@grafana/ui';
|
||||
import { Divider } from 'app/core/components/Divider';
|
||||
import { config } from 'app/core/config';
|
||||
|
||||
import { ElasticsearchOptions } from '../types';
|
||||
@ -36,6 +38,9 @@ export const ConfigEditor = (props: Props) => {
|
||||
Browser access mode in the Elasticsearch datasource is no longer available. Switch to server access mode.
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Divider />
|
||||
|
||||
<DataSourceHttpSettings
|
||||
defaultUrl="http://localhost:9200"
|
||||
dataSourceConfig={options}
|
||||
@ -46,30 +51,39 @@ export const ConfigEditor = (props: Props) => {
|
||||
secureSocksDSProxyEnabled={config.secureSocksDSProxyEnabled}
|
||||
/>
|
||||
|
||||
<ElasticDetails value={options} onChange={onOptionsChange} />
|
||||
<Divider />
|
||||
|
||||
<LogsConfig
|
||||
value={options.jsonData}
|
||||
onChange={(newValue) =>
|
||||
onOptionsChange({
|
||||
...options,
|
||||
jsonData: newValue,
|
||||
})
|
||||
}
|
||||
/>
|
||||
|
||||
<DataLinks
|
||||
value={options.jsonData.dataLinks}
|
||||
onChange={(newValue) => {
|
||||
onOptionsChange({
|
||||
...options,
|
||||
jsonData: {
|
||||
...options.jsonData,
|
||||
dataLinks: newValue,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<ConfigSection
|
||||
title="Additional settings"
|
||||
description="Additional settings are optional settings that can be configured for more control over your data source."
|
||||
isCollapsible={true}
|
||||
isInitiallyOpen
|
||||
>
|
||||
<ElasticDetails value={options} onChange={onOptionsChange} />
|
||||
<Divider hideLine />
|
||||
<LogsConfig
|
||||
value={options.jsonData}
|
||||
onChange={(newValue) =>
|
||||
onOptionsChange({
|
||||
...options,
|
||||
jsonData: newValue,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Divider hideLine />
|
||||
<DataLinks
|
||||
value={options.jsonData.dataLinks}
|
||||
onChange={(newValue) => {
|
||||
onOptionsChange({
|
||||
...options,
|
||||
jsonData: {
|
||||
...options.jsonData,
|
||||
dataLinks: newValue,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</ConfigSection>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -2,7 +2,9 @@ import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
|
||||
import { GrafanaTheme2, VariableOrigin, DataLinkBuiltInVars } from '@grafana/data';
|
||||
import { ConfigSubSection } from '@grafana/experimental';
|
||||
import { Button, useStyles2 } from '@grafana/ui';
|
||||
import { ConfigDescriptionLink } from 'app/core/components/ConfigDescriptionLink';
|
||||
|
||||
import { DataLinkConfig } from '../types';
|
||||
|
||||
@ -10,9 +12,11 @@ import { DataLink } from './DataLink';
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => {
|
||||
return {
|
||||
infoText: css`
|
||||
padding-bottom: ${theme.spacing(2)};
|
||||
color: ${theme.colors.text.secondary};
|
||||
addButton: css`
|
||||
margin-right: 10px;
|
||||
`,
|
||||
container: css`
|
||||
margin-bottom: ${theme.spacing(2)};
|
||||
`,
|
||||
dataLink: css`
|
||||
margin-bottom: ${theme.spacing(1)};
|
||||
@ -29,60 +33,63 @@ export const DataLinks = (props: Props) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h3 className="page-heading">Data links</h3>
|
||||
<ConfigSubSection
|
||||
title="Data links"
|
||||
description={
|
||||
<ConfigDescriptionLink
|
||||
description="Add links to existing fields. Links will be shown in log row details next to the field value."
|
||||
suffix="elasticsearch/#data-links"
|
||||
feature="Elasticsearch data links"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<div className={styles.container}>
|
||||
{value && value.length > 0 && (
|
||||
<div className="gf-form-group">
|
||||
{value.map((field, index) => {
|
||||
return (
|
||||
<DataLink
|
||||
className={styles.dataLink}
|
||||
key={index}
|
||||
value={field}
|
||||
onChange={(newField) => {
|
||||
const newDataLinks = [...value];
|
||||
newDataLinks.splice(index, 1, newField);
|
||||
onChange(newDataLinks);
|
||||
}}
|
||||
onDelete={() => {
|
||||
const newDataLinks = [...value];
|
||||
newDataLinks.splice(index, 1);
|
||||
onChange(newDataLinks);
|
||||
}}
|
||||
suggestions={[
|
||||
{
|
||||
value: DataLinkBuiltInVars.valueRaw,
|
||||
label: 'Raw value',
|
||||
documentation: 'Raw value of the field',
|
||||
origin: VariableOrigin.Value,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={styles.infoText}>
|
||||
Add links to existing fields. Links will be shown in log row details next to the field value.
|
||||
<Button
|
||||
type="button"
|
||||
variant={'secondary'}
|
||||
className={styles.addButton}
|
||||
icon="plus"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
const newDataLinks = [...(value || []), { field: '', url: '' }];
|
||||
onChange(newDataLinks);
|
||||
}}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{value && value.length > 0 && (
|
||||
<div className="gf-form-group">
|
||||
{value.map((field, index) => {
|
||||
return (
|
||||
<DataLink
|
||||
className={styles.dataLink}
|
||||
key={index}
|
||||
value={field}
|
||||
onChange={(newField) => {
|
||||
const newDataLinks = [...value];
|
||||
newDataLinks.splice(index, 1, newField);
|
||||
onChange(newDataLinks);
|
||||
}}
|
||||
onDelete={() => {
|
||||
const newDataLinks = [...value];
|
||||
newDataLinks.splice(index, 1);
|
||||
onChange(newDataLinks);
|
||||
}}
|
||||
suggestions={[
|
||||
{
|
||||
value: DataLinkBuiltInVars.valueRaw,
|
||||
label: 'Raw value',
|
||||
documentation: 'Raw value of the field',
|
||||
origin: VariableOrigin.Value,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
variant={'secondary'}
|
||||
className={css`
|
||||
margin-right: 10px;
|
||||
`}
|
||||
icon="plus"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
const newDataLinks = [...(value || []), { field: '', url: '' }];
|
||||
onChange(newDataLinks);
|
||||
}}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
</>
|
||||
</ConfigSubSection>
|
||||
);
|
||||
};
|
||||
|
@ -1,7 +1,9 @@
|
||||
import React from 'react';
|
||||
|
||||
import { DataSourceSettings, SelectableValue } from '@grafana/data';
|
||||
import { FieldSet, InlineField, Input, Select, InlineSwitch } from '@grafana/ui';
|
||||
import { ConfigSubSection } from '@grafana/experimental';
|
||||
import { InlineField, Input, Select, InlineSwitch } from '@grafana/ui';
|
||||
import { ConfigDescriptionLink } from 'app/core/components/ConfigDescriptionLink';
|
||||
|
||||
import { ElasticsearchOptions, Interval } from '../types';
|
||||
|
||||
@ -20,92 +22,99 @@ type Props = {
|
||||
};
|
||||
export const ElasticDetails = ({ value, onChange }: Props) => {
|
||||
return (
|
||||
<>
|
||||
<FieldSet label="Elasticsearch details">
|
||||
<InlineField label="Index name" htmlFor="es_config_indexName" labelWidth={26}>
|
||||
<Input
|
||||
id="es_config_indexName"
|
||||
value={value.jsonData.index ?? (value.database || '')}
|
||||
onChange={indexChangeHandler(value, onChange)}
|
||||
width={24}
|
||||
placeholder="es-index-name"
|
||||
required
|
||||
/>
|
||||
</InlineField>
|
||||
<ConfigSubSection
|
||||
title="Elasticsearch details"
|
||||
description={
|
||||
<ConfigDescriptionLink
|
||||
description="Specific settings for the Elasticsearch data source."
|
||||
suffix="elasticsearch/#index-settings"
|
||||
feature="Elasticsearch details"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<InlineField label="Index name" htmlFor="es_config_indexName" labelWidth={26}>
|
||||
<Input
|
||||
id="es_config_indexName"
|
||||
value={value.jsonData.index ?? (value.database || '')}
|
||||
onChange={indexChangeHandler(value, onChange)}
|
||||
width={24}
|
||||
placeholder="es-index-name"
|
||||
required
|
||||
/>
|
||||
</InlineField>
|
||||
|
||||
<InlineField label="Pattern" htmlFor="es_config_indexPattern" labelWidth={26}>
|
||||
<Select
|
||||
inputId="es_config_indexPattern"
|
||||
value={indexPatternTypes.find(
|
||||
(pattern) => pattern.value === (value.jsonData.interval === undefined ? 'none' : value.jsonData.interval)
|
||||
)}
|
||||
options={indexPatternTypes}
|
||||
onChange={intervalHandler(value, onChange)}
|
||||
width={24}
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField label="Pattern" htmlFor="es_config_indexPattern" labelWidth={26}>
|
||||
<Select
|
||||
inputId="es_config_indexPattern"
|
||||
value={indexPatternTypes.find(
|
||||
(pattern) => pattern.value === (value.jsonData.interval === undefined ? 'none' : value.jsonData.interval)
|
||||
)}
|
||||
options={indexPatternTypes}
|
||||
onChange={intervalHandler(value, onChange)}
|
||||
width={24}
|
||||
/>
|
||||
</InlineField>
|
||||
|
||||
<InlineField label="Time field name" htmlFor="es_config_timeField" labelWidth={26}>
|
||||
<Input
|
||||
id="es_config_timeField"
|
||||
value={value.jsonData.timeField || ''}
|
||||
onChange={jsonDataChangeHandler('timeField', value, onChange)}
|
||||
width={24}
|
||||
placeholder="@timestamp"
|
||||
required
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField label="Time field name" htmlFor="es_config_timeField" labelWidth={26}>
|
||||
<Input
|
||||
id="es_config_timeField"
|
||||
value={value.jsonData.timeField || ''}
|
||||
onChange={jsonDataChangeHandler('timeField', value, onChange)}
|
||||
width={24}
|
||||
placeholder="@timestamp"
|
||||
required
|
||||
/>
|
||||
</InlineField>
|
||||
|
||||
<InlineField label="Max concurrent Shard Requests" htmlFor="es_config_shardRequests" labelWidth={26}>
|
||||
<Input
|
||||
id="es_config_shardRequests"
|
||||
value={value.jsonData.maxConcurrentShardRequests || ''}
|
||||
onChange={jsonDataChangeHandler('maxConcurrentShardRequests', value, onChange)}
|
||||
width={24}
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField label="Max concurrent Shard Requests" htmlFor="es_config_shardRequests" labelWidth={26}>
|
||||
<Input
|
||||
id="es_config_shardRequests"
|
||||
value={value.jsonData.maxConcurrentShardRequests || ''}
|
||||
onChange={jsonDataChangeHandler('maxConcurrentShardRequests', value, onChange)}
|
||||
width={24}
|
||||
/>
|
||||
</InlineField>
|
||||
|
||||
<InlineField
|
||||
label="Min time interval"
|
||||
htmlFor="es_config_minTimeInterval"
|
||||
labelWidth={26}
|
||||
tooltip={
|
||||
<>
|
||||
A lower limit for the auto group by time interval. Recommended to be set to write frequency, for example{' '}
|
||||
<code>1m</code> if your data is written every minute.
|
||||
</>
|
||||
}
|
||||
error="Value is not valid, you can use number with time unit specifier: y, M, w, d, h, m, s"
|
||||
invalid={!!value.jsonData.timeInterval && !/^\d+(ms|[Mwdhmsy])$/.test(value.jsonData.timeInterval)}
|
||||
>
|
||||
<Input
|
||||
id="es_config_minTimeInterval"
|
||||
value={value.jsonData.timeInterval || ''}
|
||||
onChange={jsonDataChangeHandler('timeInterval', value, onChange)}
|
||||
width={24}
|
||||
placeholder="10s"
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField
|
||||
label="Min time interval"
|
||||
htmlFor="es_config_minTimeInterval"
|
||||
labelWidth={26}
|
||||
tooltip={
|
||||
<>
|
||||
A lower limit for the auto group by time interval. Recommended to be set to write frequency, for example{' '}
|
||||
<code>1m</code> if your data is written every minute.
|
||||
</>
|
||||
}
|
||||
error="Value is not valid, you can use number with time unit specifier: y, M, w, d, h, m, s"
|
||||
invalid={!!value.jsonData.timeInterval && !/^\d+(ms|[Mwdhmsy])$/.test(value.jsonData.timeInterval)}
|
||||
>
|
||||
<Input
|
||||
id="es_config_minTimeInterval"
|
||||
value={value.jsonData.timeInterval || ''}
|
||||
onChange={jsonDataChangeHandler('timeInterval', value, onChange)}
|
||||
width={24}
|
||||
placeholder="10s"
|
||||
/>
|
||||
</InlineField>
|
||||
|
||||
<InlineField label="X-Pack enabled" labelWidth={26}>
|
||||
<InlineField label="X-Pack enabled" labelWidth={26}>
|
||||
<InlineSwitch
|
||||
id="es_config_xpackEnabled"
|
||||
value={value.jsonData.xpack || false}
|
||||
onChange={jsonDataSwitchChangeHandler('xpack', value, onChange)}
|
||||
/>
|
||||
</InlineField>
|
||||
|
||||
{value.jsonData.xpack && (
|
||||
<InlineField label="Include Frozen Indices" htmlFor="es_config_frozenIndices" labelWidth={26}>
|
||||
<InlineSwitch
|
||||
id="es_config_xpackEnabled"
|
||||
value={value.jsonData.xpack || false}
|
||||
onChange={jsonDataSwitchChangeHandler('xpack', value, onChange)}
|
||||
id="es_config_frozenIndices"
|
||||
value={value.jsonData.includeFrozen ?? false}
|
||||
onChange={jsonDataSwitchChangeHandler('includeFrozen', value, onChange)}
|
||||
/>
|
||||
</InlineField>
|
||||
|
||||
{value.jsonData.xpack && (
|
||||
<InlineField label="Include Frozen Indices" htmlFor="es_config_frozenIndices" labelWidth={26}>
|
||||
<InlineSwitch
|
||||
id="es_config_frozenIndices"
|
||||
value={value.jsonData.includeFrozen ?? false}
|
||||
onChange={jsonDataSwitchChangeHandler('includeFrozen', value, onChange)}
|
||||
/>
|
||||
</InlineField>
|
||||
)}
|
||||
</FieldSet>
|
||||
</>
|
||||
)}
|
||||
</ConfigSubSection>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Input, InlineField, FieldSet } from '@grafana/ui';
|
||||
import { ConfigSubSection } from '@grafana/experimental';
|
||||
import { Input, InlineField } from '@grafana/ui';
|
||||
import { ConfigDescriptionLink } from 'app/core/components/ConfigDescriptionLink';
|
||||
|
||||
import { ElasticsearchOptions } from '../types';
|
||||
|
||||
@ -19,7 +21,16 @@ export const LogsConfig = (props: Props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<FieldSet label="Logs">
|
||||
<ConfigSubSection
|
||||
title="Logs"
|
||||
description={
|
||||
<ConfigDescriptionLink
|
||||
description="Configure which fields the data source uses for log messages and log levels."
|
||||
suffix="elasticsearch/#logs"
|
||||
feature="Elasticsearch log fields"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<InlineField label="Message field name" labelWidth={22}>
|
||||
<Input
|
||||
id="es_logs-config_logMessageField"
|
||||
@ -38,6 +49,6 @@ export const LogsConfig = (props: Props) => {
|
||||
width={24}
|
||||
/>
|
||||
</InlineField>
|
||||
</FieldSet>
|
||||
</ConfigSubSection>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user