mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
# Backport This will backport the following commits from `8.x` to `8.17`: - [[Logs UI] Allow editing of non-resolving log views (#210633)](https://github.com/elastic/kibana/pull/210633) <!--- Backport version: 9.6.4 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Felix Stürmer","email":"weltenwort@users.noreply.github.com"},"sourceCommit":{"committedDate":"2025-02-14T14:55:17Z","message":"[Logs UI] Allow editing of non-resolving log views (#210633)\n\nThis changes the settings page of the Logs UI such that it allows editing of log view settings even if the resolution or status check failed. This allows recovery from various situations that were previously only recoverable by resetting the log view completely.","sha":"41cd657811bd1c00ac15860268c018d4d80085ac","branchLabelMapping":{"^v8.16.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:fix","Feature:Logs UI","backport:skip","Team:obs-ux-logs","v8.18.0","v8.17.3"],"title":"[Logs UI] Allow editing of non-resolving log views","number":210633,"url":"https://github.com/elastic/kibana/pull/210633","mergeCommit":{"message":"[Logs UI] Allow editing of non-resolving log views (#210633)\n\nThis changes the settings page of the Logs UI such that it allows editing of log view settings even if the resolution or status check failed. This allows recovery from various situations that were previously only recoverable by resetting the log view completely.","sha":"41cd657811bd1c00ac15860268c018d4d80085ac"}},"sourceBranch":"8.x","suggestedTargetBranches":["8.18","8.17"],"targetPullRequestStates":[{"branch":"8.18","label":"v8.18.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.17","label":"v8.17.3","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT-->
This commit is contained in:
parent
b7cd76ef91
commit
4de5655725
12 changed files with 211 additions and 55 deletions
|
@ -59,7 +59,7 @@ type IndicesConfigurationPanelProps = PropsOf<typeof IndicesConfigurationPanel>;
|
|||
|
||||
type IndicesConfigurationPanelStoryArgs = Pick<
|
||||
IndicesConfigurationPanelProps,
|
||||
'isLoading' | 'isReadOnly'
|
||||
'isLoading' | 'isReadOnly' | 'logViewStatus'
|
||||
> & {
|
||||
availableIndexPatterns: MockIndexPatternSpec[];
|
||||
logIndices: LogIndicesFormState;
|
||||
|
@ -69,6 +69,7 @@ const IndicesConfigurationPanelTemplate: Story<IndicesConfigurationPanelStoryArg
|
|||
isLoading,
|
||||
isReadOnly,
|
||||
logIndices,
|
||||
logViewStatus,
|
||||
}) => {
|
||||
const logIndicesFormElement = useLogIndicesFormElement(logIndices);
|
||||
|
||||
|
@ -78,6 +79,7 @@ const IndicesConfigurationPanelTemplate: Story<IndicesConfigurationPanelStoryArg
|
|||
isLoading={isLoading}
|
||||
isReadOnly={isReadOnly}
|
||||
indicesFormElement={logIndicesFormElement}
|
||||
logViewStatus={logViewStatus}
|
||||
/>
|
||||
<EuiCodeBlock language="json">
|
||||
// field states{'\n'}
|
||||
|
@ -103,6 +105,10 @@ const defaultArgs: IndicesConfigurationPanelStoryArgs = {
|
|||
type: 'index_name' as const,
|
||||
indexName: 'logs-*',
|
||||
},
|
||||
logViewStatus: {
|
||||
index: 'missing',
|
||||
reason: 'remoteClusterNotFound',
|
||||
},
|
||||
availableIndexPatterns: [
|
||||
{
|
||||
id: 'INDEX_PATTERN_A',
|
||||
|
|
|
@ -9,11 +9,14 @@ import { EuiCheckableCard, EuiFormFieldset, EuiSpacer, EuiTitle } from '@elastic
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useUiTracker } from '@kbn/observability-shared-plugin/public';
|
||||
import type {
|
||||
LogDataViewReference,
|
||||
LogIndexReference,
|
||||
LogViewStatus,
|
||||
} from '@kbn/logs-shared-plugin/common';
|
||||
import {
|
||||
logIndexNameReferenceRT,
|
||||
LogDataViewReference,
|
||||
logDataViewReferenceRT,
|
||||
LogIndexReference,
|
||||
logSourcesKibanaAdvancedSettingRT,
|
||||
} from '@kbn/logs-shared-plugin/common';
|
||||
import { EuiCallOut } from '@elastic/eui';
|
||||
|
@ -34,7 +37,8 @@ export const IndicesConfigurationPanel = React.memo<{
|
|||
isLoading: boolean;
|
||||
isReadOnly: boolean;
|
||||
indicesFormElement: FormElement<LogIndexReference | undefined, FormValidationError>;
|
||||
}>(({ isLoading, isReadOnly, indicesFormElement }) => {
|
||||
logViewStatus: LogViewStatus;
|
||||
}>(({ isLoading, isReadOnly, indicesFormElement, logViewStatus }) => {
|
||||
const {
|
||||
services: {
|
||||
http,
|
||||
|
@ -198,6 +202,7 @@ export const IndicesConfigurationPanel = React.memo<{
|
|||
/>
|
||||
)}
|
||||
</EuiCheckableCard>
|
||||
<LogViewStatusWarning logViewStatus={logViewStatus} />
|
||||
{numberOfLogsRules > 0 && indicesFormElement.isDirty && (
|
||||
<>
|
||||
<EuiSpacer size="s" />
|
||||
|
@ -232,6 +237,36 @@ export const IndicesConfigurationPanel = React.memo<{
|
|||
);
|
||||
});
|
||||
|
||||
const LogViewStatusWarning: React.FC<{ logViewStatus: LogViewStatus }> = ({ logViewStatus }) => {
|
||||
if (logViewStatus.index === 'missing') {
|
||||
return (
|
||||
<>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiCallOut title={logIndicesMissingTitle} color="warning" iconType="warning">
|
||||
{logViewStatus.reason === 'noShardsFound' ? (
|
||||
<FormattedMessage
|
||||
id="xpack.infra.sourceConfiguration.logIndicesMissingMessage.noShardsFound"
|
||||
defaultMessage="No shards found for the specified indices."
|
||||
/>
|
||||
) : logViewStatus.reason === 'noIndicesFound' ? (
|
||||
<FormattedMessage
|
||||
id="xpack.infra.sourceConfiguration.logIndicesMissingMessage.noIndicesFound"
|
||||
defaultMessage="No indices found for the specified pattern."
|
||||
/>
|
||||
) : logViewStatus.reason === 'remoteClusterNotFound' ? (
|
||||
<FormattedMessage
|
||||
id="xpack.infra.sourceConfiguration.logIndicesMissingMessage.remoteClusterNotFound"
|
||||
defaultMessage="At least one remote cluster was not found."
|
||||
/>
|
||||
) : null}
|
||||
</EuiCallOut>
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const isDataViewFormElement = isFormElementForType(
|
||||
(value): value is LogDataViewReference | undefined =>
|
||||
value == null || logDataViewReferenceRT.is(value)
|
||||
|
@ -242,3 +277,10 @@ const isIndexNamesFormElement = isFormElementForType(logIndexNameReferenceRT.is)
|
|||
const isKibanaAdvancedSettingFormElement = isFormElementForType(
|
||||
logSourcesKibanaAdvancedSettingRT.is
|
||||
);
|
||||
|
||||
const logIndicesMissingTitle = i18n.translate(
|
||||
'xpack.infra.sourceConfiguration.logIndicesMissingTitle',
|
||||
{
|
||||
defaultMessage: 'Log indices missing',
|
||||
}
|
||||
);
|
||||
|
|
|
@ -20,6 +20,8 @@ import { useKibana } from '@kbn/kibana-react-plugin/public';
|
|||
import { Prompt } from '@kbn/observability-shared-plugin/public';
|
||||
import { useTrackPageview } from '@kbn/observability-shared-plugin/public';
|
||||
import { useLogViewContext } from '@kbn/logs-shared-plugin/public';
|
||||
import type { LogView, LogViewAttributes, LogViewStatus } from '@kbn/logs-shared-plugin/common';
|
||||
import { SourceErrorPage } from '../../../components/source_error_page';
|
||||
import { LogsDeprecationCallout } from '../../../components/logs_deprecation_callout';
|
||||
import { SourceLoadingPage } from '../../../components/source_loading_page';
|
||||
import { useLogsBreadcrumbs } from '../../../hooks/use_logs_breadcrumbs';
|
||||
|
@ -50,14 +52,17 @@ export const LogsSettingsPage = () => {
|
|||
]);
|
||||
|
||||
const {
|
||||
logView,
|
||||
hasFailedLoadingLogView,
|
||||
isInlineLogView,
|
||||
isLoading,
|
||||
isUninitialized,
|
||||
update,
|
||||
latestLoadLogViewFailures,
|
||||
logView,
|
||||
logViewStatus,
|
||||
resolvedLogView,
|
||||
isInlineLogView,
|
||||
retry,
|
||||
revertToDefaultLogView,
|
||||
update,
|
||||
} = useLogViewContext();
|
||||
|
||||
const availableFields = useMemo(
|
||||
|
@ -65,6 +70,47 @@ export const LogsSettingsPage = () => {
|
|||
[resolvedLogView]
|
||||
);
|
||||
|
||||
const isWriteable = shouldAllowEdit && logView != null && logView.origin !== 'internal';
|
||||
|
||||
if ((isLoading || isUninitialized) && logView == null) {
|
||||
return <SourceLoadingPage />;
|
||||
} else if (hasFailedLoadingLogView || logView == null) {
|
||||
return <SourceErrorPage errorMessage={latestLoadLogViewFailures[0].message} retry={retry} />;
|
||||
} else {
|
||||
return (
|
||||
<LogsSettingsPageContent
|
||||
availableFields={availableFields}
|
||||
isInlineLogView={isInlineLogView}
|
||||
isLoading={isLoading}
|
||||
isWriteable={isWriteable}
|
||||
logView={logView}
|
||||
logViewStatus={logViewStatus}
|
||||
revertToDefaultLogView={revertToDefaultLogView}
|
||||
onUpdateLogViewAttributes={update}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const LogsSettingsPageContent = ({
|
||||
availableFields,
|
||||
isInlineLogView,
|
||||
isLoading,
|
||||
isWriteable,
|
||||
logView,
|
||||
logViewStatus,
|
||||
revertToDefaultLogView,
|
||||
onUpdateLogViewAttributes,
|
||||
}: {
|
||||
availableFields: string[];
|
||||
isInlineLogView: boolean;
|
||||
isLoading: boolean;
|
||||
isWriteable: boolean;
|
||||
logView: LogView;
|
||||
logViewStatus: LogViewStatus;
|
||||
revertToDefaultLogView: () => void;
|
||||
onUpdateLogViewAttributes: (logViewAttributes: Partial<LogViewAttributes>) => Promise<void>;
|
||||
}) => {
|
||||
const {
|
||||
sourceConfigurationFormElement,
|
||||
formState,
|
||||
|
@ -74,21 +120,15 @@ export const LogsSettingsPage = () => {
|
|||
} = useLogSourceConfigurationFormState(logView?.attributes);
|
||||
|
||||
const persistUpdates = useCallback(async () => {
|
||||
await update(formState);
|
||||
sourceConfigurationFormElement.resetValue();
|
||||
}, [update, sourceConfigurationFormElement, formState]);
|
||||
|
||||
const isWriteable = useMemo(
|
||||
() => shouldAllowEdit && logView && logView.origin !== 'internal',
|
||||
[shouldAllowEdit, logView]
|
||||
);
|
||||
|
||||
if ((isLoading || isUninitialized) && !resolvedLogView) {
|
||||
return <SourceLoadingPage />;
|
||||
}
|
||||
if (hasFailedLoadingLogView) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
await onUpdateLogViewAttributes(formState);
|
||||
sourceConfigurationFormElement.resetValue();
|
||||
} catch {
|
||||
// the error is handled in the state machine already, but without this the
|
||||
// global promise rejection tracker would complain about it being
|
||||
// unhandled
|
||||
}
|
||||
}, [onUpdateLogViewAttributes, sourceConfigurationFormElement, formState]);
|
||||
|
||||
return (
|
||||
<EuiErrorBoundary>
|
||||
|
@ -124,6 +164,7 @@ export const LogsSettingsPage = () => {
|
|||
isLoading={isLoading}
|
||||
isReadOnly={!isWriteable}
|
||||
indicesFormElement={logIndicesFormElement}
|
||||
logViewStatus={logViewStatus}
|
||||
/>
|
||||
</EuiPanel>
|
||||
<EuiSpacer />
|
||||
|
|
|
@ -107,7 +107,7 @@ describe('Logs UI Observability Homepage Functions', () => {
|
|||
setup();
|
||||
|
||||
getResolvedLogView.mockResolvedValue(createResolvedLogViewMock({ indices: 'test-index' }));
|
||||
getResolvedLogViewStatus.mockResolvedValue({ index: 'missing' });
|
||||
getResolvedLogViewStatus.mockResolvedValue({ index: 'missing', reason: 'noShardsFound' });
|
||||
|
||||
const hasData = getLogsHasDataFetcher(mockedGetStartServices);
|
||||
const response = await hasData();
|
||||
|
|
|
@ -41,6 +41,7 @@ export {
|
|||
FetchLogViewError,
|
||||
FetchLogViewStatusError,
|
||||
ResolveLogViewError,
|
||||
isNoSuchRemoteClusterError,
|
||||
} from './log_views/errors';
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no_export_all
|
||||
|
|
|
@ -38,3 +38,6 @@ export class PutLogViewError extends Error {
|
|||
this.name = 'PutLogViewError';
|
||||
}
|
||||
}
|
||||
|
||||
export const isNoSuchRemoteClusterError = (err: Error) =>
|
||||
err?.message?.includes('no_such_remote_cluster_exception');
|
||||
|
|
|
@ -60,11 +60,16 @@ const resolveLegacyReference = async (
|
|||
}
|
||||
|
||||
const indices = logViewAttributes.logIndices.indexName;
|
||||
const dataViewId = `log-view-${logViewId}`;
|
||||
|
||||
// If we didn't remove the item from the cache here the subsequent call to
|
||||
// create would not have any effect
|
||||
dataViewsService.clearInstanceCache(dataViewId);
|
||||
|
||||
const dataViewReference = await dataViewsService
|
||||
.create(
|
||||
{
|
||||
id: `log-view-${logViewId}`,
|
||||
id: dataViewId,
|
||||
name: logViewAttributes.name,
|
||||
title: indices,
|
||||
timeFieldName: TIMESTAMP_FIELD,
|
||||
|
@ -134,11 +139,16 @@ const resolveKibanaAdvancedSettingReference = async (
|
|||
const indices = (await logSourcesService.getLogSources())
|
||||
.map((logSource) => logSource.indexPattern)
|
||||
.join(',');
|
||||
const dataViewId = `log-view-${logViewId}`;
|
||||
|
||||
// If we didn't remove the item from the cache here the subsequent call to
|
||||
// create would not have any effect
|
||||
dataViewsService.clearInstanceCache(dataViewId);
|
||||
|
||||
const dataViewReference = await dataViewsService
|
||||
.create(
|
||||
{
|
||||
id: `log-view-${logViewId}`,
|
||||
id: dataViewId,
|
||||
name: logViewAttributes.name,
|
||||
title: indices,
|
||||
timeFieldName: TIMESTAMP_FIELD,
|
||||
|
|
|
@ -106,17 +106,25 @@ export const logViewRT = rt.exact(
|
|||
);
|
||||
export type LogView = rt.TypeOf<typeof logViewRT>;
|
||||
|
||||
export const logViewIndexStatusRT = rt.keyof({
|
||||
available: null,
|
||||
empty: null,
|
||||
missing: null,
|
||||
unknown: null,
|
||||
});
|
||||
export type LogViewIndexStatus = rt.TypeOf<typeof logViewIndexStatusRT>;
|
||||
|
||||
export const logViewStatusRT = rt.strict({
|
||||
index: logViewIndexStatusRT,
|
||||
});
|
||||
export const logViewStatusRT = rt.union([
|
||||
rt.strict({
|
||||
index: rt.literal('available'),
|
||||
}),
|
||||
rt.strict({
|
||||
index: rt.literal('empty'),
|
||||
}),
|
||||
rt.strict({
|
||||
index: rt.literal('missing'),
|
||||
reason: rt.keyof({
|
||||
noIndicesFound: null,
|
||||
noShardsFound: null,
|
||||
remoteClusterNotFound: null,
|
||||
}),
|
||||
}),
|
||||
rt.strict({
|
||||
index: rt.literal('unknown'),
|
||||
}),
|
||||
]);
|
||||
export type LogViewStatus = rt.TypeOf<typeof logViewStatusRT>;
|
||||
|
||||
export const persistedLogViewReferenceRT = rt.type({
|
||||
|
|
|
@ -9,7 +9,12 @@ import { useInterpret, useSelector } from '@xstate/react';
|
|||
import createContainer from 'constate';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { waitFor } from 'xstate/lib/waitFor';
|
||||
import { DEFAULT_LOG_VIEW, LogViewAttributes, LogViewReference } from '../../common/log_views';
|
||||
import {
|
||||
DEFAULT_LOG_VIEW,
|
||||
LogViewAttributes,
|
||||
LogViewReference,
|
||||
LogViewStatus,
|
||||
} from '../../common/log_views';
|
||||
import {
|
||||
InitializeFromUrl,
|
||||
UpdateContextInUrl,
|
||||
|
@ -73,7 +78,10 @@ export const useLogView = ({
|
|||
|
||||
const logView = useSelector(logViewStateService, (state) =>
|
||||
state.matches('resolving') ||
|
||||
state.matches('updating') ||
|
||||
state.matches('checkingStatus') ||
|
||||
state.matches('resolutionFailed') ||
|
||||
state.matches('checkingStatusFailed') ||
|
||||
state.matches('resolvedPersistedLogView') ||
|
||||
state.matches('resolvedInlineLogView')
|
||||
? state.context.logView
|
||||
|
@ -82,16 +90,19 @@ export const useLogView = ({
|
|||
|
||||
const resolvedLogView = useSelector(logViewStateService, (state) =>
|
||||
state.matches('checkingStatus') ||
|
||||
state.matches('checkingStatusFailed') ||
|
||||
state.matches('resolvedPersistedLogView') ||
|
||||
state.matches('resolvedInlineLogView')
|
||||
? state.context.resolvedLogView
|
||||
: undefined
|
||||
);
|
||||
|
||||
const logViewStatus = useSelector(logViewStateService, (state) =>
|
||||
state.matches('resolvedPersistedLogView') || state.matches('resolvedInlineLogView')
|
||||
const logViewStatus: LogViewStatus = useSelector(logViewStateService, (state) =>
|
||||
state.matches('resolvedPersistedLogView') ||
|
||||
state.matches('resolvedInlineLogView') ||
|
||||
state.matches('resolutionFailed')
|
||||
? state.context.status
|
||||
: undefined
|
||||
: { index: 'unknown' }
|
||||
);
|
||||
|
||||
const isLoadingLogView = useSelector(logViewStateService, (state) => state.matches('loading'));
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { catchError, from, map, of, throwError } from 'rxjs';
|
||||
import { createMachine, actions, assign } from 'xstate';
|
||||
import { isNoSuchRemoteClusterError } from '../../../../common';
|
||||
import { ILogViewsClient } from '../../../services/log_views';
|
||||
import { NotificationChannel } from '../../xstate_helpers';
|
||||
import { LogViewNotificationEvent, logViewNotificationEventSelectors } from './notifications';
|
||||
|
@ -75,7 +76,7 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith
|
|||
on: {
|
||||
RESOLUTION_FAILED: {
|
||||
target: 'resolutionFailed',
|
||||
actions: 'storeError',
|
||||
actions: ['storeError', 'storeStatusAfterError'],
|
||||
},
|
||||
RESOLUTION_SUCCEEDED: {
|
||||
target: 'checkingStatus',
|
||||
|
@ -250,6 +251,20 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith
|
|||
} as LogViewContextWithStatus)
|
||||
: {}
|
||||
),
|
||||
storeStatusAfterError: assign((context, event) =>
|
||||
'error' in event
|
||||
? ({
|
||||
status: isNoSuchRemoteClusterError(event.error)
|
||||
? {
|
||||
index: 'missing',
|
||||
reason: 'remoteClusterNotFound',
|
||||
}
|
||||
: {
|
||||
index: 'unknown',
|
||||
},
|
||||
} as LogViewContextWithStatus)
|
||||
: {}
|
||||
),
|
||||
storeError: assign((context, event) =>
|
||||
'error' in event
|
||||
? ({
|
||||
|
|
|
@ -71,7 +71,7 @@ export type LogViewTypestate =
|
|||
}
|
||||
| {
|
||||
value: 'updating';
|
||||
context: LogViewContextWithReference;
|
||||
context: LogViewContextWithReference & LogViewContextWithLogView;
|
||||
}
|
||||
| {
|
||||
value: 'loadingFailed';
|
||||
|
@ -83,11 +83,17 @@ export type LogViewTypestate =
|
|||
}
|
||||
| {
|
||||
value: 'resolutionFailed';
|
||||
context: LogViewContextWithReference & LogViewContextWithLogView & LogViewContextWithError;
|
||||
context: LogViewContextWithReference &
|
||||
LogViewContextWithLogView &
|
||||
LogViewContextWithStatus &
|
||||
LogViewContextWithError;
|
||||
}
|
||||
| {
|
||||
value: 'checkingStatusFailed';
|
||||
context: LogViewContextWithReference & LogViewContextWithLogView & LogViewContextWithError;
|
||||
context: LogViewContextWithReference &
|
||||
LogViewContextWithLogView &
|
||||
LogViewContextWithResolvedLogView &
|
||||
LogViewContextWithError;
|
||||
};
|
||||
|
||||
export type LogViewContext = LogViewTypestate['context'];
|
||||
|
|
|
@ -25,6 +25,7 @@ import {
|
|||
PutLogViewError,
|
||||
ResolvedLogView,
|
||||
resolveLogView,
|
||||
isNoSuchRemoteClusterError,
|
||||
} from '../../../common/log_views';
|
||||
import { decodeOrThrow } from '../../../common/runtime_types';
|
||||
import { ILogViewsClient } from './types';
|
||||
|
@ -69,7 +70,7 @@ export class LogViewsClient implements ILogViewsClient {
|
|||
}
|
||||
|
||||
public async getResolvedLogViewStatus(resolvedLogView: ResolvedLogView): Promise<LogViewStatus> {
|
||||
const indexStatus = await lastValueFrom(
|
||||
return await lastValueFrom(
|
||||
this.search({
|
||||
params: {
|
||||
ignore_unavailable: true,
|
||||
|
@ -81,31 +82,43 @@ export class LogViewsClient implements ILogViewsClient {
|
|||
},
|
||||
})
|
||||
).then(
|
||||
({ rawResponse }) => {
|
||||
({ rawResponse }): LogViewStatus => {
|
||||
if (rawResponse._shards.total <= 0) {
|
||||
return 'missing' as const;
|
||||
return {
|
||||
index: 'missing',
|
||||
reason: 'noShardsFound',
|
||||
};
|
||||
}
|
||||
|
||||
const totalHits = decodeTotalHits(rawResponse.hits.total);
|
||||
if (typeof totalHits === 'number' ? totalHits > 0 : totalHits.value > 0) {
|
||||
return 'available' as const;
|
||||
return {
|
||||
index: 'available',
|
||||
};
|
||||
}
|
||||
|
||||
return 'empty' as const;
|
||||
return {
|
||||
index: 'empty',
|
||||
};
|
||||
},
|
||||
(err) => {
|
||||
(err): LogViewStatus => {
|
||||
if (err.status === 404) {
|
||||
return 'missing' as const;
|
||||
return {
|
||||
index: 'missing',
|
||||
reason: 'noIndicesFound',
|
||||
};
|
||||
} else if (err != null && isNoSuchRemoteClusterError(err)) {
|
||||
return {
|
||||
index: 'missing',
|
||||
reason: 'remoteClusterNotFound',
|
||||
};
|
||||
}
|
||||
|
||||
throw new FetchLogViewStatusError(
|
||||
`Failed to check status of log indices of "${resolvedLogView.indices}": ${err}`
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
index: indexStatus,
|
||||
};
|
||||
}
|
||||
|
||||
public async putLogView(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue