[SLO] Add dependencies for Burn Rate rule suppression (#177078)

## 🍒  Summary

This PR adds a rule dependency feature to the SLO Burn Rate rule to
enable rule suppression when one of the dependencies meets the
suppression criteria.

### 📟 Use case

When you add a rule dependency to your SLO Burn Rate rule, you will also
choose which action groups you want to suppress on. For example, if you
have rule `A` which depends on rule `B` and you want to suppress the
actions of rule `A` when rule `B` is triggering `Critical` or `High`,
you'd add rule `B` and pick the action groups `Critical` and `High`.
When rule `B` is triggering either of those action groups, ALL of the
actions for rule `A` will be suppressed.

When an action is suppressed, we will trigger a `Suppressed` action
group an set the context variable `{context.suppressedAction}` to the
action that would have been trigger if they rule wasn't suppressed. This
will allow users to create an "action" for `Suppressed` alerts so they
can still create notification without waking up the team for a
`Critical` or `High` severity alert.

If you have 2 rules that use a group by, then the suppression will
happen on the intersection of the `slo.instanceId`. For example, imagine
we have a Nginx Proxy in front of an Node.js web service and we've
created an availability SLO based on `status_code < 500` for both,
grouped-by `url.domain`. When the Node.js app responds with a `500`, the
Nginx Proxy's SLO will start to degrade because of the Node.js service.
The admins for the Nginx Proxy would like to only receive alerts if the
Node.js web services is "healthy" so they've listed the Node.js burn
rate rule as a dependency to suppress on `Critical` or `High` burn
rates.

When one of the domains, `you-got.mail`, starts to throw 500's and the
burn rate becomes `High`, the rule will suppress the alert for the
`you-got.mail` Nginx Proxy instance. If one of the other domains,
`box.mail`, for Nginx started throwing `502` because of a
mis-configuration, the alert would trigger normally because the
`box.mail` instance of the rule dependency for the Node.js web service
is still healthy (or not triggering `Critical` or `High`).

The suppression between group-by SLOs and non-group-by SLOs works like
this:

- SLO with a group-by depends on a non-grouped-by SLO, all the instances
of the group by will be suppressed.
- SLO without a group-by depends on an SLO with a group-by, the
non-grouped SLO will be suppressed if ANY of the instances of the
group-by are triggering the "suppress on" action groups.

### 💻 Screenshots

Adding a rule dependency for MongoDB to a Node.js web app

<img width="764" alt="image"
src="da2fd411-2a8e-4433-a505-2c4111e115be">

In this scenario, Nginx Proxies to Admin Console which reads data from
MongoDB. The connection between MongoDB and the Admin Console has a
network outage which causes the MongoDB rule to trigger a `Critical`
action group and suppresses the `Critical` action for the Admin Console.
The Admin Console also goes `Critical` which then suppresses the rule
for the Nginx Proxy.

<img width="1784" alt="image"
src="2db75993-8912-4769-83f8-240de811a92f">

### ⚙️ How it works

- Execute the primary rule and evaluate if should trigger any actions
- If the primary rule is triggering, execute each of the dependencies
(in the same process using the same function) and suppress when:
- For group-by SLOs that depend on another SLO with a group by, we
suppress the intersection between the instanceIds.
- For group-by SLOs that depend on a non-group-by SLO, we suppress all
the instanceIds.
- For non-group-by SLO that depends on a group-by SLO, we suppress if
ANY instanceId matches. (not recommended)

### 🔬 How to test

- Add the following lines to your `config/kibana.dev.yaml`:
  - `server.basePath: '/kibana'`
  - `server.publicBaseUrl: 'http://localhost:5601/kibana'`
- Start with the following command: `node x-pack/scripts/data_forge.js
--events-per-cycle 50 --lookback now-1d --dataset fake_stack
--install-kibana-assets --kibana-url http://localhost:5601/kibana
--event-template good`
- Wait till the log message says `info Waiting 60000ms`
- Create 2 SLOs:
- "Admin Console Availability" using the "Custom Query" SLI with the
`Admin Console` DataView, set the "Good query" to
`http.response.status_code < 500` and the set the "Total query" to
`http.response.status_code: *` using a rolling `7d` time window
- "MongoDB Availability" using the "Custom Query" SLI with the
`Heartbeat` DataView, set the "Good query" to `event.outcome: "success"`
and the set the "Total query" to `event.outcome: *` using a rolling `7d`
time window
- You should have 2 burn rate rules that were created by default
- Open the "Admin Console Availability Burn Rate rule" and add the
"MongoDB Availability Burn Rate rule" as the dependency with `Critical`
and `High` action groups to "Suppress on".
- Save the rule
- Stop the first `data_forge.js` command
- Start `node x-pack/scripts/data_forge.js --events-per-cycle 50
--lookback now --dataset fake_stack --install-kibana-assets --kibana-url
http://localhost:5601/kibana --event-template bad`

Once the Burn Rate rules go `Critical`, you should see the "MongoDB
Availability Burn Rate rule" reason message should start with
`CRITICAL:...` and the "Admin Console Availability Burn Rate rule"
reason message should start with `SUPPRESSED - CRITICAL: ...`

Fixes #173653

---------

Co-authored-by: Panagiota Mitsopoulou <giota85@gmail.com>
Co-authored-by: Dominique Clarke <doclarke71@gmail.com>
Co-authored-by: Kevin Delemme <kdelemme@gmail.com>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Dominique Clarke <dominique.clarke@elastic.co>
This commit is contained in:
Chris Cowan 2024-04-16 04:25:50 -06:00 committed by GitHub
parent cefdb33a67
commit 96dc2a5104
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 1817 additions and 40 deletions

View file

@ -9534,6 +9534,75 @@ Object {
"presence": "optional",
},
"keys": Object {
"dependencies": Object {
"flags": Object {
"default": [Function],
"error": [Function],
"presence": "optional",
},
"items": Array [
Object {
"flags": Object {
"default": Object {
"special": "deep",
},
"error": [Function],
"presence": "optional",
},
"keys": Object {
"actionGroupsToSuppressOn": Object {
"flags": Object {
"error": [Function],
},
"items": Array [
Object {
"flags": Object {
"error": [Function],
"presence": "optional",
},
"rules": Array [
Object {
"args": Object {
"method": [Function],
},
"name": "custom",
},
],
"type": "string",
},
],
"type": "array",
},
"ruleId": Object {
"flags": Object {
"error": [Function],
},
"rules": Array [
Object {
"args": Object {
"method": [Function],
},
"name": "custom",
},
],
"type": "string",
},
},
"preferences": Object {
"stripUnknown": Object {
"objects": false,
},
},
"type": "object",
},
],
"metas": Array [
Object {
"x-oas-optional": true,
},
],
"type": "array",
},
"sloId": Object {
"flags": Object {
"error": [Function],

View file

@ -41,6 +41,14 @@ export const LOW_PRIORITY_ACTION = {
}),
};
export const SUPPRESSED_PRIORITY_ACTION_ID = 'slo.burnRate.suppressed';
export const SUPPRESSED_PRIORITY_ACTION = {
id: SUPPRESSED_PRIORITY_ACTION_ID,
name: i18n.translate('xpack.slo.alerting.burnRate.suppressedPriorityAction', {
defaultMessage: 'Suppressed',
}),
};
export const SLO_MODEL_VERSION = 2;
export const SLO_RESOURCES_VERSION = 3.2;
export const SLO_RESOURCES_VERSION_MAJOR = 3;

View file

@ -0,0 +1,16 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import * as t from 'io-ts';
export const DependencyRT = t.type({
ruleId: t.string,
actionGroupsToSuppressOn: t.array(t.string),
});
export const DependenciesRT = t.array(DependencyRT);
export type Dependency = t.OutputOf<typeof DependencyRT>;

View file

@ -12,17 +12,18 @@ import { ALL_VALUE, SLOResponse } from '@kbn/slo-schema';
import { EuiCallOut, EuiSpacer, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { useFetchSloDetails } from '../../hooks/use_fetch_slo_details';
import { BurnRateRuleParams, WindowSchema } from '../../typings';
import { BurnRateRuleParams, WindowSchema, Dependency } from '../../typings';
import { SloSelector } from './slo_selector';
import { ValidationBurnRateRuleResult } from './validation';
import { createNewWindow, Windows } from './windows';
import { BURN_RATE_DEFAULTS } from './constants';
import { AlertTimeTable } from './alert_time_table';
import { getGroupKeysProse } from '../../utils/slo/groupings';
import { Dependencies } from './dependencies';
type Props = Pick<
RuleTypeParamsExpressionProps<BurnRateRuleParams>,
'ruleParams' | 'setRuleParams'
'ruleParams' | 'setRuleParams' | 'id'
> &
ValidationBurnRateRuleResult;
@ -34,6 +35,7 @@ export function BurnRateRuleEditor(props: Props) {
const [selectedSlo, setSelectedSlo] = useState<SLOResponse | undefined>(undefined);
const [windowDefs, setWindowDefs] = useState<WindowSchema[]>(ruleParams?.windows || []);
const [dependencies, setDependencies] = useState<Dependency[]>(ruleParams?.dependencies || []);
useEffect(() => {
setSelectedSlo(initialSlo);
@ -57,6 +59,10 @@ export function BurnRateRuleEditor(props: Props) {
setRuleParams('windows', windowDefs);
}, [windowDefs, setRuleParams]);
useEffect(() => {
setRuleParams('dependencies', dependencies);
}, [dependencies, setRuleParams]);
return (
<>
<EuiTitle size="xs">
@ -94,6 +100,13 @@ export function BurnRateRuleEditor(props: Props) {
<AlertTimeTable slo={selectedSlo} windows={windowDefs} />
</>
)}
{selectedSlo && (
<Dependencies
currentRuleId={props.id}
dependencies={dependencies}
onChange={setDependencies}
/>
)}
</>
);
}

View file

@ -0,0 +1,173 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import {
EuiBadge,
EuiBasicTable,
EuiFlexGroup,
EuiFlexItem,
EuiSpacer,
EuiTableActionsColumnType,
EuiText,
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { useFetchSLOsWithBurnRateRules } from '../../hooks/use_fetch_slos_with_burn_rate_rules';
import { Dependency } from '../../../common/types';
import {
ALERT_ACTION,
HIGH_PRIORITY_ACTION,
LOW_PRIORITY_ACTION,
MEDIUM_PRIORITY_ACTION,
} from '../../../common/constants';
import { DependencyEditor } from './dependency_editor';
import { TechnicalPreviewBadge } from '../technical_preview_badge';
const ACTION_GROUP_OPTIONS = [
{ value: ALERT_ACTION.id, label: ALERT_ACTION.name },
{ value: HIGH_PRIORITY_ACTION.id, label: HIGH_PRIORITY_ACTION.name },
{ value: MEDIUM_PRIORITY_ACTION.id, label: MEDIUM_PRIORITY_ACTION.name },
{ value: LOW_PRIORITY_ACTION.id, label: LOW_PRIORITY_ACTION.name },
];
interface DependenciesProps {
currentRuleId?: string;
dependencies: Dependency[];
onChange: (depencencies: Dependency[]) => void;
}
interface DependencyTableRow {
index: number;
dependency: Dependency;
actionGroupsToSuppressOn: string[];
}
export function Dependencies({ currentRuleId, dependencies, onChange }: DependenciesProps) {
const { isLoading, data: allRules } = useFetchSLOsWithBurnRateRules({});
const dependencyRuleIds = dependencies.map((dep) => dep.ruleId);
const availableRules = currentRuleId
? allRules?.filter((rule) => rule.id !== currentRuleId && !dependencyRuleIds.includes(rule.id))
: allRules;
const handleAddDependency = (dependency: Dependency) => {
onChange([...dependencies, dependency]);
};
const handleChange = (index: number, dependency: Dependency) => {
onChange(dependencies.map((dep, idx) => (idx === index ? dependency : dep)));
};
const handleDelete = (index: number) => {
onChange(dependencies.filter((_dep, idx) => idx !== index));
};
const rows = dependencies.map((dependency, index) => {
const rule = allRules?.find(({ id }) => id === dependency.ruleId);
return {
index,
name: rule?.name,
actionGroupsToSuppressOn: dependency.actionGroupsToSuppressOn,
dependency,
};
});
const columns = [
{
field: 'name',
truncateText: true,
name: i18n.translate('xpack.slo.rules.dependencies.ruleColumn', {
defaultMessage: 'Rule',
}),
},
{
field: 'actionGroupsToSuppressOn',
name: i18n.translate('xpack.slo.rules.dependencies.supressOnColumn', {
defaultMessage: 'Suppress on',
}),
render: (groups: string[]) => {
return groups.map((group) => {
const actionGroup = ACTION_GROUP_OPTIONS.find((g) => g.value === group);
return <EuiBadge color="hollow">{actionGroup?.label}</EuiBadge>;
});
},
},
{
width: '50px',
actions: [
{
render: (row: DependencyTableRow) => {
const handleSubmit = (dep: Dependency) => {
handleChange(row.index, dep);
};
const selectedRule = allRules?.find(({ id }) => id === row.dependency.ruleId);
return (
<DependencyEditor
isLoading={isLoading}
onSubmit={handleSubmit}
dependency={row.dependency}
rules={
availableRules && selectedRule
? [...availableRules, selectedRule]
: availableRules
}
/>
);
},
},
{
icon: 'trash',
type: 'icon',
color: 'danger',
name: 'Delete',
description: 'Delete dependency',
onClick: (row: DependencyTableRow) => {
handleDelete(row.index);
},
},
],
} as EuiTableActionsColumnType<DependencyTableRow>,
];
return (
<>
<EuiFlexGroup>
<EuiFlexItem grow={1}>
<EuiTitle size="xs">
<h5>
{i18n.translate('xpack.slo.rules.dependencies.title', {
defaultMessage: 'Rule dependencies',
})}
</h5>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={0}>
<TechnicalPreviewBadge />
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="s" />
<EuiText size="s">
<p>
{i18n.translate('xpack.slo.rules.dependencies.description', {
defaultMessage:
'Configure rule dependencies and designate the serverity action groups you want to use to suppress the current rule. For instance, if you choose to suppress on the "Critical" and "High" action groups, the current rule will abstain from executing any actions of its severity groups when the associated rule dependency breaches its threshold. Instead, it will execute a "Suppressed" action group in response to the dependency trigger.',
})}
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiBasicTable columns={columns} items={rows} />
<EuiSpacer size="s" />
<DependencyEditor
rules={availableRules}
isLoading={isLoading}
onSubmit={handleAddDependency}
/>
<EuiSpacer size="m" />
</>
);
}

View file

@ -0,0 +1,166 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import {
EuiButtonEmpty,
EuiButtonIcon,
EuiComboBox,
EuiComboBoxOptionOption,
EuiForm,
EuiFormRow,
EuiPopover,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useState } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { Rule } from '@kbn/triggers-actions-ui-plugin/public';
import { isRight } from 'fp-ts/lib/Either';
import { SloRule } from '../../hooks/use_fetch_slos_with_burn_rate_rules';
import { Dependency, DependencyRT } from '../../../common/types';
import {
ALERT_ACTION,
HIGH_PRIORITY_ACTION,
LOW_PRIORITY_ACTION,
MEDIUM_PRIORITY_ACTION,
} from '../../../common/constants';
const ACTION_GROUP_OPTIONS = [
{ value: ALERT_ACTION.id, label: ALERT_ACTION.name },
{ value: HIGH_PRIORITY_ACTION.id, label: HIGH_PRIORITY_ACTION.name },
{ value: MEDIUM_PRIORITY_ACTION.id, label: MEDIUM_PRIORITY_ACTION.name },
{ value: LOW_PRIORITY_ACTION.id, label: LOW_PRIORITY_ACTION.name },
];
interface DependencyEditorProps {
isLoading: boolean;
onSubmit: (dependency: Dependency) => void;
dependency?: Dependency;
rules?: Array<Rule<SloRule>>;
}
export function DependencyEditor({
isLoading,
onSubmit,
dependency,
rules,
}: DependencyEditorProps) {
const isEditMode = dependency != null;
const [isOpen, setPopoverState] = useState(false);
const [partialDependency, setPartialDependency] = useState<Partial<Dependency>>(dependency || {});
const handleOpenPopover = () => setPopoverState(true);
const handleClosePopover = () => {
if (!isEditMode) {
setPartialDependency({});
}
setPopoverState(false);
};
const handleRuleSelection = (opts: Array<EuiComboBoxOptionOption<string>>) => {
if (opts.length > 0 && opts[0].value) {
setPartialDependency((previous) => ({ ...previous, ruleId: opts[0].value }));
}
};
const handleActionGroupSelection = (opts: Array<EuiComboBoxOptionOption<string>>) => {
if (opts.length > 0 && opts.every((opt) => !!opt.value)) {
const values = opts.map((opt) => opt.value);
setPartialDependency((previous) => ({
...previous,
actionGroupsToSuppressOn: values as string[],
}));
}
};
const rulesOptions = rules?.map((rule) => ({ label: rule.name, value: rule.id })) ?? [];
const selectedRuleOption = rulesOptions?.filter((opt) => opt.value === partialDependency.ruleId);
const selectedRule = rules?.find((rule) => rule.id === partialDependency.ruleId);
const ruleActionGroups =
(selectedRule && selectedRule.params.windows.map((winDef) => winDef.actionGroup)) || [];
const actionGroupOptions = ACTION_GROUP_OPTIONS.filter((group) =>
ruleActionGroups.includes(group.value)
);
const selectedActionGroups = ACTION_GROUP_OPTIONS.filter((group) =>
partialDependency.actionGroupsToSuppressOn?.includes(group.value)
);
const handleSubmit = () => {
const dep = DependencyRT.decode(partialDependency);
if (isRight(dep)) {
onSubmit(dep.right);
}
handleClosePopover();
};
const button = isEditMode ? (
<EuiButtonIcon
isDisabled={isLoading}
data-test-subj="sloBurnRateRuleEditDependencyButton"
color={'primary'}
size="s"
iconType={'pencil'}
onClick={handleOpenPopover}
aria-label={i18n.translate('xpack.slo.rules.editDependencyAriaLabel', {
defaultMessage: 'Edit dependency',
})}
/>
) : (
<EuiButtonEmpty
isDisabled={isLoading || rules?.length === 0}
data-test-subj="sloBurnRateRuleAddDependencyButton"
color={'primary'}
size="s"
iconType={'plusInCircleFilled'}
onClick={handleOpenPopover}
aria-label={i18n.translate('xpack.slo.rules.addDependencyAriaLabel', {
defaultMessage: 'Add dependency',
})}
>
<FormattedMessage id="xpack.slo.rules.addDependencyLabel" defaultMessage="Add dependency" />
</EuiButtonEmpty>
);
return (
<EuiPopover button={button} isOpen={isOpen} closePopover={handleSubmit}>
<div style={{ width: 400 }}>
<EuiForm component="form">
<EuiFormRow
label={i18n.translate('xpack.slo.rules.addDependencyForm.ruleLabel', {
defaultMessage: 'Rule (required)',
})}
>
<EuiComboBox
compressed
fullWidth
options={rulesOptions}
singleSelection={{ asPlainText: true }}
isLoading={isLoading}
onChange={handleRuleSelection}
selectedOptions={selectedRuleOption}
/>
</EuiFormRow>
<EuiFormRow
label={i18n.translate('xpack.slo.rules.addDependencyForm.suppressOnLabel', {
defaultMessage: 'Suppress on (required)',
})}
>
<EuiComboBox
compressed
fullWidth
isDisabled={!partialDependency.ruleId}
options={actionGroupOptions}
onChange={handleActionGroupSelection}
selectedOptions={selectedActionGroups}
/>
</EuiFormRow>
</EuiForm>
</div>
</EuiPopover>
);
}

View file

@ -5,14 +5,7 @@
* 2.0.
*/
import {
EuiBetaBadge,
EuiButtonGroup,
EuiFlexGroup,
EuiFlexItem,
EuiPanel,
EuiTitle,
} from '@elastic/eui';
import { EuiButtonGroup, EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { SLOWithSummaryResponse } from '@kbn/slo-schema';
import moment from 'moment';
@ -20,6 +13,7 @@ import React, { useEffect, useState } from 'react';
import { useFetchSloBurnRates } from '../../../hooks/use_fetch_slo_burn_rates';
import { ErrorRateChart } from '../error_rate_chart';
import { BurnRate } from './burn_rate';
import { TechnicalPreviewBadge } from '../../technical_preview_badge';
interface Props {
slo: SLOWithSummaryResponse;
@ -83,20 +77,7 @@ export function BurnRates({ slo, isAutoRefreshing, burnRateOptions }: Props) {
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiBetaBadge
label={i18n.translate('xpack.slo.burnRate.technicalPreviewBadgeTitle', {
defaultMessage: 'Technical Preview',
})}
size="s"
tooltipPosition="bottom"
tooltipContent={i18n.translate(
'xpack.slo.burnRate.technicalPreviewBadgeDescription',
{
defaultMessage:
'This functionality is in technical preview and is subject to change or may be removed in future versions. The design and code is less mature than official generally available features and is being provided as-is with no warranties. Technical preview features are not subject to the support service level agreement of official generally available features.',
}
)}
/>
<TechnicalPreviewBadge />
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexItem grow={false}>

View file

@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { EuiBetaBadge } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
export function TechnicalPreviewBadge() {
return (
<EuiBetaBadge
label={i18n.translate('xpack.slo.technicalPreviewBadgeTitle', {
defaultMessage: 'Technical Preview',
})}
size="s"
tooltipPosition="bottom"
tooltipContent={i18n.translate('xpack.slo.technicalPreviewBadgeDescription', {
defaultMessage:
'This functionality is in technical preview and is subject to change or may be removed in future versions. The design and code is less mature than official generally available features and is being provided as-is with no warranties. Technical preview features are not subject to the support service level agreement of official generally available features.',
})}
/>
);
}

View file

@ -56,6 +56,7 @@ export const sloKeys = {
range: { start: number; end: number },
groupings?: Record<string, unknown>
) => [...sloKeys.all, 'preview', indicator, range, groupings] as const,
burnRateRules: (search: string) => [...sloKeys.all, 'burnRateRules', search],
};
export type SloKeys = typeof sloKeys;

View file

@ -0,0 +1,103 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import {
QueryObserverResult,
RefetchOptions,
RefetchQueryFilters,
useQuery,
} from '@tanstack/react-query';
import type { Rule } from '@kbn/triggers-actions-ui-plugin/public';
import { BASE_ALERTING_API_PATH } from '@kbn/alerting-plugin/common';
import { HttpSetup } from '@kbn/core/public';
import { useKibana } from '../utils/kibana_react';
import { sloKeys } from './query_key_factory';
import { WindowSchema } from '../typings';
export interface SloRule extends Record<string, unknown> {
windows: WindowSchema[];
}
interface RuleApiResponse {
page: number;
total: number;
per_page: number;
data: Array<Rule<SloRule>>;
}
export interface UseFetchSLOsWithBurnRateRuleParams {
search?: string;
}
export interface UseFetchSLOsWithBurnRateRulesResponse {
isInitialLoading: boolean;
isLoading: boolean;
isRefetching: boolean;
isSuccess: boolean;
isError: boolean;
data: Array<Rule<SloRule>> | undefined;
refetch: <TPageData>(
options?: (RefetchOptions & RefetchQueryFilters<TPageData>) | undefined
) => Promise<QueryObserverResult<Array<Rule<SloRule>> | undefined, unknown>>;
}
async function fetchRules({
search,
http,
signal,
}: {
search?: string;
http: HttpSetup;
signal?: AbortSignal;
}) {
const filter = 'alert.attributes.alertTypeId:slo.rules.burnRate';
const query = {
search,
filter,
fields: ['id', 'params.windows', 'name'],
per_page: 1000,
};
const response = await http.get<RuleApiResponse>(`${BASE_ALERTING_API_PATH}/rules/_find`, {
query,
signal,
});
return response.data;
}
export function useFetchSLOsWithBurnRateRules({
search = '',
}: UseFetchSLOsWithBurnRateRuleParams): UseFetchSLOsWithBurnRateRulesResponse {
const { http } = useKibana().services;
const { isInitialLoading, isLoading, isError, isSuccess, isRefetching, data, refetch } = useQuery(
{
queryKey: sloKeys.burnRateRules(search),
queryFn: async ({ signal }) => {
try {
return fetchRules({ search, http, signal });
} catch (error) {
// ignore error for retrieving slos
}
},
refetchOnWindowFocus: false,
keepPreviousData: true,
}
);
return {
data,
isLoading,
isInitialLoading,
isRefetching,
isSuccess,
isError,
refetch,
};
}

View file

@ -6,6 +6,7 @@
*/
import { RuleTypeParams } from '@kbn/alerting-plugin/common';
import { Dependency } from '../../../common/types';
type DurationUnit = 'm' | 'h' | 'd' | 'w' | 'M';
@ -26,6 +27,7 @@ interface WindowSchema {
interface BurnRateRuleParams extends RuleTypeParams {
sloId: string;
windows: WindowSchema[];
dependencies?: Dependency[];
}
interface ChartData {
@ -33,4 +35,4 @@ interface ChartData {
value: number | undefined;
}
export type { BurnRateRuleParams, ChartData, Duration, DurationUnit, WindowSchema };
export type { BurnRateRuleParams, ChartData, Duration, DurationUnit, WindowSchema, Dependency };

View file

@ -9,6 +9,7 @@ import { v4 as uuidv4 } from 'uuid';
import {
IBasePath,
IUiSettingsClient,
SavedObject,
SavedObjectsClientContract,
SavedObjectsFindResponse,
} from '@kbn/core/server';
@ -29,6 +30,7 @@ import { getRuleExecutor } from './executor';
import { createSLO } from '../../../services/fixtures/slo';
import { SLO, StoredSLO } from '../../../domain/models';
import { SharePluginStart } from '@kbn/share-plugin/server';
import { Rule } from '@kbn/alerting-plugin/common';
import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks';
import {
BurnRateAlertState,
@ -44,6 +46,7 @@ import {
ALERT_ACTION,
ALERT_ACTION_ID,
HIGH_PRIORITY_ACTION_ID,
SUPPRESSED_PRIORITY_ACTION,
} from '../../../../common/constants';
import { EvaluationBucket } from './lib/evaluate';
import {
@ -55,6 +58,7 @@ import {
ALERT_EVALUATION_THRESHOLD,
ALERT_EVALUATION_VALUE,
ALERT_REASON,
SLO_BURN_RATE_RULE_TYPE_ID,
} from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names';
import {
generateAboveThresholdKey,
@ -97,6 +101,41 @@ function createFindResponse(sloList: SLO[]): SavedObjectsFindResponse<StoredSLO>
};
}
function createGetRuleResponse(
ruleId: string,
ruleParams: BurnRateRuleParams
): SavedObject<Rule<BurnRateRuleParams>> {
return {
id: ruleId,
type: 'alert',
references: [],
attributes: {
id: ruleId,
enabled: true,
name: 'Fake Parent Rule for SLO Burn Rate',
alertTypeId: SLO_BURN_RATE_RULE_TYPE_ID,
consumer: 'observability',
schedule: { interval: '1m' },
params: ruleParams,
tags: [],
actions: [],
createdBy: 'nobody',
createdAt: new Date(),
updatedAt: new Date(),
updatedBy: 'nobody',
apiKey: 'some-fake-key',
apiKeyOwner: 'some-user',
muteAll: false,
mutedInstanceIds: [],
revision: 1,
executionStatus: {
status: 'ok',
lastExecutionDate: new Date(),
},
},
};
}
function getTimeRange() {
const date = new Date(Date.now()).toISOString();
return { dateStart: date, dateEnd: date };
@ -403,6 +442,139 @@ describe('BurnRateRuleExecutor', () => {
});
});
it('schedules a suppressed alert when both windows of first window definition burn rate have reached the threshold but the dependency matches', async () => {
const slo = createSLO({ objective: { target: 0.9 } });
const dependencyRuleParams = someRuleParamsWithWindows({ sloId: slo.id });
const ruleParams = someRuleParamsWithWindows({
sloId: slo.id,
dependencies: [{ ruleId: `partent-rule`, actionGroupsToSuppressOn: [ALERT_ACTION.id] }],
});
soClientMock.find.mockResolvedValueOnce(createFindResponse([slo]));
const buckets = [
{
instanceId: 'foo',
windows: [
{ shortWindowBurnRate: 2.1, longWindowBurnRate: 2.3 },
{ shortWindowBurnRate: 0.9, longWindowBurnRate: 1.2 },
],
},
{
instanceId: 'bar',
windows: [
{ shortWindowBurnRate: 2.2, longWindowBurnRate: 2.5 },
{ shortWindowBurnRate: 0.9, longWindowBurnRate: 1.2 },
],
},
];
esClientMock.search.mockResolvedValueOnce(
generateEsResponse(ruleParams, buckets, { instanceId: 'bar' })
);
esClientMock.search.mockResolvedValueOnce(
generateEsResponse(ruleParams, [], { instanceId: 'bar' })
);
// evaluateDependendes mocks
soClientMock.get.mockResolvedValueOnce(
createGetRuleResponse('parent-rule', dependencyRuleParams)
);
soClientMock.find.mockResolvedValueOnce(createFindResponse([slo]));
esClientMock.search.mockResolvedValueOnce(
generateEsResponse(ruleParams, buckets, { instanceId: 'bar' })
);
esClientMock.search.mockResolvedValueOnce(
generateEsResponse(ruleParams, [], { instanceId: 'bar' })
);
// @ts-ignore
servicesMock.alertsClient!.report.mockImplementation(({ id }: { id: string }) => ({
uuid: `uuid-${id}`,
start: new Date().toISOString(),
}));
const executor = getRuleExecutor({
basePath: basePathMock,
alertsLocator: alertsLocatorMock,
});
await executor({
params: ruleParams,
startedAt: new Date(),
services: servicesMock,
executionId: 'irrelevant',
logger: loggerMock,
previousStartedAt: null,
rule: {} as SanitizedRuleConfig,
spaceId: 'irrelevant',
state: {},
flappingSettings: DEFAULT_FLAPPING_SETTINGS,
getTimeRange,
});
expect(servicesMock.alertsClient?.report).toBeCalledWith({
id: 'foo',
actionGroup: SUPPRESSED_PRIORITY_ACTION.id,
state: {
alertState: AlertStates.ALERT,
},
payload: {
[ALERT_REASON]:
'SUPPRESSED - CRITICAL: The burn rate for the past 1h is 2.3 and for the past 5m is 2.1 for foo. Alert when above 2 for both windows',
[ALERT_EVALUATION_THRESHOLD]: 2,
[ALERT_EVALUATION_VALUE]: 2.1,
[SLO_ID_FIELD]: slo.id,
[SLO_REVISION_FIELD]: slo.revision,
[SLO_INSTANCE_ID_FIELD]: 'foo',
},
});
expect(servicesMock.alertsClient?.report).toBeCalledWith({
id: 'bar',
actionGroup: SUPPRESSED_PRIORITY_ACTION.id,
state: {
alertState: AlertStates.ALERT,
},
payload: {
[ALERT_REASON]:
'SUPPRESSED - CRITICAL: The burn rate for the past 1h is 2.5 and for the past 5m is 2.2 for bar. Alert when above 2 for both windows',
[ALERT_EVALUATION_THRESHOLD]: 2,
[ALERT_EVALUATION_VALUE]: 2.2,
[SLO_ID_FIELD]: slo.id,
[SLO_REVISION_FIELD]: slo.revision,
[SLO_INSTANCE_ID_FIELD]: 'bar',
},
});
expect(servicesMock.alertsClient?.setAlertData).toHaveBeenNthCalledWith(1, {
id: 'foo',
context: expect.objectContaining({
longWindow: { burnRate: 2.3, duration: '1h' },
shortWindow: { burnRate: 2.1, duration: '5m' },
burnRateThreshold: 2,
reason:
'SUPPRESSED - CRITICAL: The burn rate for the past 1h is 2.3 and for the past 5m is 2.1 for foo. Alert when above 2 for both windows',
alertDetailsUrl: 'mockedAlertsLocator > getLocation',
}),
});
expect(servicesMock.alertsClient?.setAlertData).toHaveBeenNthCalledWith(2, {
id: 'bar',
context: expect.objectContaining({
longWindow: { burnRate: 2.5, duration: '1h' },
shortWindow: { burnRate: 2.2, duration: '5m' },
burnRateThreshold: 2,
reason:
'SUPPRESSED - CRITICAL: The burn rate for the past 1h is 2.5 and for the past 5m is 2.2 for bar. Alert when above 2 for both windows',
alertDetailsUrl: 'mockedAlertsLocator > getLocation',
}),
});
expect(alertsLocatorMock.getLocation).toBeCalledWith({
baseUrl: 'https://kibana.dev',
kuery: 'kibana.alert.uuid: "uuid-foo"',
rangeFrom: expect.stringMatching(ISO_DATE_REGEX),
spaceId: 'irrelevant',
});
});
it('schedules an alert when both windows of second window definition burn rate have reached the threshold', async () => {
const slo = createSLO({ objective: { target: 0.9 } });
const ruleParams = someRuleParamsWithWindows({ sloId: slo.id });

View file

@ -43,8 +43,11 @@ import {
HIGH_PRIORITY_ACTION,
MEDIUM_PRIORITY_ACTION,
LOW_PRIORITY_ACTION,
SUPPRESSED_PRIORITY_ACTION,
} from '../../../../common/constants';
import { evaluate } from './lib/evaluate';
import { evaluateDependencies } from './lib/evaluate_dependencies';
import { shouldSuppressInstanceId } from './lib/should_suppress_instance_id';
export const getRuleExecutor = ({
basePath,
@ -91,6 +94,19 @@ export const getRuleExecutor = ({
const { dateEnd } = getTimeRange('1m');
const results = await evaluate(esClient.asCurrentUser, slo, params, new Date(dateEnd));
const suppressResults =
params.dependencies && results.some((res) => res.shouldAlert)
? (
await evaluateDependencies(
soClient,
esClient.asCurrentUser,
sloRepository,
params.dependencies,
new Date(dateEnd)
)
).activeRules
: [];
if (results.length > 0) {
const alertLimit = alertsClient.getAlertLimitValue();
let hasReachedLimit = false;
@ -113,6 +129,7 @@ export const getRuleExecutor = ({
`/app/observability/slos/${slo.id}${urlQuery}`
);
if (shouldAlert) {
const shouldSuppress = shouldSuppressInstanceId(suppressResults, instanceId);
if (scheduledActionsCount >= alertLimit) {
// need to set this so that warning is displayed in the UI and in the logs
hasReachedLimit = true;
@ -125,14 +142,18 @@ export const getRuleExecutor = ({
longWindowBurnRate,
shortWindowDuration,
shortWindowBurnRate,
windowDef
windowDef,
shouldSuppress
);
const alertId = instanceId;
const actionGroup = shouldSuppress
? SUPPRESSED_PRIORITY_ACTION.id
: windowDef.actionGroup;
const { uuid, start } = alertsClient.report({
id: alertId,
actionGroup: windowDef.actionGroup,
actionGroup,
state: {
alertState: AlertStates.ALERT,
},
@ -167,6 +188,7 @@ export const getRuleExecutor = ({
sloName: slo.name,
sloInstanceId: instanceId,
slo,
suppressedAction: shouldSuppress ? windowDef.actionGroup : null,
};
alertsClient.setAlertData({ id: alertId, context });
@ -234,14 +256,20 @@ function buildReason(
longWindowBurnRate: number,
shortWindowDuration: Duration,
shortWindowBurnRate: number,
windowDef: WindowSchema
windowDef: WindowSchema,
suppressed: boolean
) {
const actionGroupName = suppressed
? `${upperCase(SUPPRESSED_PRIORITY_ACTION.name)} - ${upperCase(
getActionGroupName(actionGroup)
)}`
: upperCase(getActionGroupName(actionGroup));
if (instanceId === ALL_VALUE) {
return i18n.translate('xpack.slo.alerting.burnRate.reason', {
defaultMessage:
'{actionGroupName}: The burn rate for the past {longWindowDuration} is {longWindowBurnRate} and for the past {shortWindowDuration} is {shortWindowBurnRate}. Alert when above {burnRateThreshold} for both windows',
values: {
actionGroupName: upperCase(getActionGroupName(actionGroup)),
actionGroupName,
longWindowDuration: longWindowDuration.format(),
longWindowBurnRate: numeral(longWindowBurnRate).format('0.[00]'),
shortWindowDuration: shortWindowDuration.format(),
@ -254,7 +282,7 @@ function buildReason(
defaultMessage:
'{actionGroupName}: The burn rate for the past {longWindowDuration} is {longWindowBurnRate} and for the past {shortWindowDuration} is {shortWindowBurnRate} for {instanceId}. Alert when above {burnRateThreshold} for both windows',
values: {
actionGroupName: upperCase(getActionGroupName(actionGroup)),
actionGroupName,
longWindowDuration: longWindowDuration.format(),
longWindowBurnRate: numeral(longWindowBurnRate).format('0.[00]'),
shortWindowDuration: shortWindowDuration.format(),

View file

@ -15,7 +15,10 @@ import {
import { SLO } from '../../../../domain/models';
import { BurnRateRuleParams } from '../types';
export function createBurnRateRule(slo: SLO, params: Partial<BurnRateRuleParams> = {}) {
export function createBurnRateRule(
slo: SLO,
params: Partial<BurnRateRuleParams> = {}
): BurnRateRuleParams {
return {
sloId: slo.id,
windows: [

View file

@ -0,0 +1,66 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { ElasticsearchClient } from '@kbn/core/server';
import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
import { Rule } from '@kbn/alerting-plugin/common';
import { ALL_VALUE } from '@kbn/slo-schema';
import { Dependency } from '../../../../../common/types';
import { KibanaSavedObjectsSLORepository } from '../../../../services';
import { BurnRateRuleParams } from '../types';
import { SLO } from '../../../../domain/models';
import { evaluate } from './evaluate';
export interface ActiveRule {
rule: Rule<BurnRateRuleParams>;
slo: SLO;
instanceIdsToSuppress: string[];
suppressAll: boolean;
}
export interface EvaulateDependenciesResponse {
activeRules: ActiveRule[];
}
export async function evaluateDependencies(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
sloRepository: KibanaSavedObjectsSLORepository,
dependencies: Dependency[],
startedAt: Date
): Promise<EvaulateDependenciesResponse> {
const activeRules = await Promise.all(
dependencies.map(async (dependency) => {
const rule = await fetchRule(soClient, dependency.ruleId);
const slo = await sloRepository.findById(rule.params.sloId);
const paramsWithSuppressOnWindows = {
...rule.params,
windows: rule.params.windows.filter((winDef) =>
dependency.actionGroupsToSuppressOn.includes(winDef.actionGroup)
),
};
const results = await evaluate(esClient, slo, paramsWithSuppressOnWindows, startedAt);
const instanceIdsToSuppress = results
.filter((res) => res.shouldAlert)
.map((res) => res.instanceId);
const suppressAll =
instanceIdsToSuppress.length > 0 && instanceIdsToSuppress.every((id) => id === ALL_VALUE);
return {
rule,
slo,
instanceIdsToSuppress: suppressAll ? [] : instanceIdsToSuppress,
suppressAll,
};
})
);
return { activeRules };
}
async function fetchRule(soClient: SavedObjectsClientContract, ruleId: string) {
const response = await soClient.get<Rule<BurnRateRuleParams>>('alert', ruleId);
return response.attributes;
}

View file

@ -0,0 +1,50 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { SLO } from '../../../../domain/models';
import { Rule } from '@kbn/alerting-plugin/common';
import { BurnRateRuleParams } from '../types';
import { shouldSuppressInstanceId } from './should_suppress_instance_id';
import { ALL_VALUE } from '@kbn/slo-schema';
describe('shouldSuppressInstanceId', () => {
it('should suppress when supressAll is encountered', () => {
const results = [
{
slo: {} as unknown as SLO,
rule: {} as unknown as Rule<BurnRateRuleParams>,
suppressAll: true,
instanceIdsToSuppress: [],
},
];
expect(shouldSuppressInstanceId(results, 'foo')).toBeTruthy();
expect(shouldSuppressInstanceId(results, ALL_VALUE)).toBeTruthy();
});
it('should suppress when instanceId is ALL_VALUE and any instanceId matches', () => {
const results = [
{
slo: {} as unknown as SLO,
rule: {} as unknown as Rule<BurnRateRuleParams>,
suppressAll: false,
instanceIdsToSuppress: ['foo'],
},
];
expect(shouldSuppressInstanceId(results, ALL_VALUE)).toBeTruthy();
});
it('should suppress when instanceId is matching the same instanceId in the results', () => {
const results = [
{
slo: {} as unknown as SLO,
rule: {} as unknown as Rule<BurnRateRuleParams>,
suppressAll: false,
instanceIdsToSuppress: ['foo'],
},
];
expect(shouldSuppressInstanceId(results, 'foo')).toBeTruthy();
expect(shouldSuppressInstanceId(results, 'bar')).not.toBeTruthy();
});
});

View file

@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { ALL_VALUE } from '@kbn/slo-schema';
import { ActiveRule } from './evaluate_dependencies';
export function shouldSuppressInstanceId(results: ActiveRule[], instanceId: string) {
return results.reduce((acc, res) => {
if (acc === true) return acc;
if (res.suppressAll === true) return true;
if (instanceId === ALL_VALUE && res.instanceIdsToSuppress.length > 0) return true;
return (
res.instanceIdsToSuppress.length > 0 &&
res.instanceIdsToSuppress.some((id) => id === instanceId)
);
}, false);
}

View file

@ -24,6 +24,7 @@ import {
HIGH_PRIORITY_ACTION,
LOW_PRIORITY_ACTION,
MEDIUM_PRIORITY_ACTION,
SUPPRESSED_PRIORITY_ACTION,
} from '../../../../common/constants';
import { getRuleExecutor } from './executor';
@ -43,6 +44,11 @@ const windowSchema = schema.object({
actionGroup: schema.string(),
});
const dependency = schema.object({
ruleId: schema.string(),
actionGroupsToSuppressOn: schema.arrayOf(schema.string()),
});
export function sloBurnRateRuleType(
basePath: IBasePath,
alertsLocator?: LocatorPublic<AlertsLocatorParams>
@ -50,6 +56,7 @@ export function sloBurnRateRuleType(
const paramsSchema = schema.object({
sloId: schema.string(),
windows: schema.arrayOf(windowSchema),
dependencies: schema.maybe(schema.arrayOf(dependency)),
});
return {
id: SLO_BURN_RATE_RULE_TYPE_ID,
@ -67,7 +74,13 @@ export function sloBurnRateRuleType(
},
},
defaultActionGroupId: ALERT_ACTION.id,
actionGroups: [ALERT_ACTION, HIGH_PRIORITY_ACTION, MEDIUM_PRIORITY_ACTION, LOW_PRIORITY_ACTION],
actionGroups: [
ALERT_ACTION,
HIGH_PRIORITY_ACTION,
MEDIUM_PRIORITY_ACTION,
LOW_PRIORITY_ACTION,
SUPPRESSED_PRIORITY_ACTION,
],
category: DEFAULT_APP_CATEGORIES.observability.id,
producer: sloFeatureId,
minimumLicenseRequired: 'platinum' as LicenseType,
@ -86,6 +99,7 @@ export function sloBurnRateRuleType(
{ name: 'sloId', description: sloIdActionVariableDescription },
{ name: 'sloName', description: sloNameActionVariableDescription },
{ name: 'sloInstanceId', description: sloInstanceIdActionVariableDescription },
{ name: 'suppressedAction', description: suppressedActionVariableDescription },
],
},
alerts: {
@ -159,3 +173,10 @@ export const sloInstanceIdActionVariableDescription = i18n.translate(
defaultMessage: 'The SLO instance id.',
}
);
export const suppressedActionVariableDescription = i18n.translate(
'xpack.slo.alerting.suppressedActionDescription',
{
defaultMessage: 'The suppressed action group.',
}
);

View file

@ -15,6 +15,7 @@ import {
HIGH_PRIORITY_ACTION,
MEDIUM_PRIORITY_ACTION,
LOW_PRIORITY_ACTION,
SUPPRESSED_PRIORITY_ACTION,
} from '../../../../common/constants';
export enum AlertStates {
@ -31,9 +32,15 @@ export interface WindowSchema {
actionGroup: string;
}
interface Dependency {
ruleId: string;
actionGroupsToSuppressOn: string[];
}
export type BurnRateRuleParams = {
sloId: string;
windows: WindowSchema[];
dependencies?: Dependency[];
} & Record<string, any>;
export type BurnRateRuleTypeState = RuleTypeState; // no specific rule state
export type BurnRateAlertState = AlertState; // no specific alert state
@ -43,4 +50,5 @@ export type BurnRateAllowedActionGroups = ActionGroupIdsOf<
| typeof HIGH_PRIORITY_ACTION
| typeof MEDIUM_PRIORITY_ACTION
| typeof LOW_PRIORITY_ACTION
| typeof SUPPRESSED_PRIORITY_ACTION
>;

View file

@ -30492,6 +30492,257 @@
"xpack.observability.ux.dashboard.webCoreVitals.help": "Découvrez",
"xpack.observability.ux.dashboard.webCoreVitals.helpAriaLabel": "aide",
"xpack.observability.ux.service.help": "Le service RUM comportant le plus de trafic est sélectionné",
"xpack.slo.alerting.burnRate.reason": "{actionGroupName} : Le taux d'avancement pour le (les) dernier(s) {longWindowDuration} est de {longWindowBurnRate} et pour le (les) dernier(s) {shortWindowDuration} est de {shortWindowBurnRate}. Alerter si supérieur à {burnRateThreshold} pour les deux fenêtres",
"xpack.slo.alerting.burnRate.reasonForInstanceId": "{actionGroupName} : Le taux d'avancement pour le (les) dernier(s) {longWindowDuration} est de {longWindowBurnRate} et pour le (les) dernier(s) {shortWindowDuration} est de {shortWindowBurnRate} pour {instanceId}. Alerter si supérieur à {burnRateThreshold} pour les deux fenêtres",
"xpack.slo.burnRate.breachedStatustSubtitle": "Au rythme actuel, le budget d'erreur sera épuisé en {hour} heures.",
"xpack.slo.burnRate.threshold": "Le seuil est {threshold}x",
"xpack.slo.create.errorNotification": "Un problème est survenu lors de la création de {name}",
"xpack.slo.deleteConfirmationModal.title": "Supprimer {name} ?",
"xpack.slo.duration.day": "{duration, plural, one {1 jour} many {# jours} other {# jours}}",
"xpack.slo.duration.hour": "{duration, plural, one {1 heure} many {# heures} other {# heures}}",
"xpack.slo.duration.minute": "{duration, plural, one {1 minute} many {# minutes} other {# minutes}}",
"xpack.slo.duration.month": "{duration, plural, one {1 mois} many {# mois} other {# mois}}",
"xpack.slo.duration.week": "{duration, plural, one {1 semaine} many {# semaines} other {# prochaines semaines}}",
"xpack.slo.indicatorTypeBadge.exploreInApm": "Afficher les détails de {service}",
"xpack.slo.rules.burnRate.errors.invalidThresholdValue": "Le seuil du taux d'avancement doit être compris entre 1 et {maxBurnRate}.",
"xpack.slo.rules.groupByMessage": "Le SLO que vous avez sélectionné a été créé avec une partition sur \"{groupByField}\". Cette règle surveille et génère une alerte pour chaque instance trouvée dans le champ de partition.",
"xpack.slo.rules.longWindowDuration.tooltip": "Période historique sur laquelle le taux d'avancement est calculé. Une période historique plus courte de {shortWindowDuration} minutes (1/12 de la période historique) sera utilisée pour une récupération plus rapide",
"xpack.slo.slo.activeAlertsBadge.label": "{count, plural, one {# alerte} many {# alertes} other {Alertes #}}",
"xpack.slo.slo.delete.errorNotification": "Impossible de supprimer {name}",
"xpack.slo.slo.delete.successNotification": "{name} supprimé",
"xpack.slo.slo.timeWindow.calendar": "{elapsed}/{total} jours",
"xpack.slo.sloDetails.errorBudgetChartPanel.duration": "{duration}",
"xpack.slo.sloDetails.overview.apmSource.environmentLabel": "environnement : {value}",
"xpack.slo.sloDetails.overview.apmSource.serviceLabel": "service : {value}",
"xpack.slo.sloDetails.overview.apmSource.transactionNameLabel": "nom de transaction : {value}",
"xpack.slo.sloDetails.overview.apmSource.transactionTypeLabel": "type de transaction : {value}",
"xpack.slo.sloDetails.overview.calendarAlignedTimeWindow": "calendrier {duration} aligné",
"xpack.slo.sloDetails.overview.observedValueSubtitle": "{value} (l'objectif est {objective})",
"xpack.slo.sloDetails.overview.rollingTimeWindow": "{duration} en cours",
"xpack.slo.sloDetails.overview.timeslicesBudgetingMethodDetails": "{duration} sections, {target} cible",
"xpack.slo.sloDetails.sliHistoryChartPanel.duration": "{duration}",
"xpack.slo.sloEdit.rollingTimeWindow.days": "{number} jours",
"xpack.slo.update.errorNotification": "Un problème est survenu lors de la mise à jour de {name}",
"xpack.slo.update.successNotification": "Mise à jour réussie de {name}",
"xpack.slo.alerting.alertDetailsUrlDescription": "Lien vers laffichage de résolution des problèmes dalerte pour voir plus de contextes et de détails. La chaîne sera vide si server.publicBaseUrl n'est pas configuré.",
"xpack.slo.alerting.burnRate.alertAction": "Critique",
"xpack.slo.alerting.burnRate.highPriorityAction": "Élevé",
"xpack.slo.alerting.burnRate.lowPriorityAction": "Bas",
"xpack.slo.alerting.burnRate.mediumPriorityAction": "Moyenne",
"xpack.slo.alerting.reasonDescription": "Une description concise de la raison du signalement",
"xpack.slo.alerting.sloIdDescription": "Identificateur unique du SLO.",
"xpack.slo.alerting.sloInstanceIdDescription": "ID d'instance du SLO.",
"xpack.slo.alerting.sloNameDescription": "Nom SLO.",
"xpack.slo.alerting.thresholdDescription": "Valeur de seuil du taux d'avancement.",
"xpack.slo.alerting.timestampDescription": "Horodatage du moment où l'alerte a été détectée.",
"xpack.slo.alerting.viewInAppUrlDescription": "L'URL de la page de détails du SLO pour effectuer une enquête plus approfondie.",
"xpack.slo.alerting.windowDescription": "Durée de fenêtre avec la valeur du taux d'avancement associée.",
"xpack.slo.budgetingMethod.occurrences": "Occurrences",
"xpack.slo.budgetingMethod.timeslices": "Intervalles de temps",
"xpack.slo.burnRate.breachedStatustTitle": "Valeur critique dépassée",
"xpack.slo.burnRate.noDataStatusSubtitle": "En attente de plus de données.",
"xpack.slo.burnRate.noDataStatusTitle": "Aucune valeur",
"xpack.slo.burnRate.okStatusSubtitle": "Aucun risque d'épuisement du budget d'erreurs.",
"xpack.slo.burnRate.okStatusTitle": "Valeur acceptable",
"xpack.slo.burnRate.timeRangeBtnLegend": "Sélectionner la plage temporelle",
"xpack.slo.burnRate.title": "Taux d'avancement",
"xpack.slo.deleteConfirmationModal.cancelButtonLabel": "Annuler",
"xpack.slo.deleteConfirmationModal.deleteButtonLabel": "Supprimer",
"xpack.slo.deleteConfirmationModal.descriptionText": "Vous ne pouvez pas récupérer ce SLO après l'avoir supprimé.",
"xpack.slo.duration.daily": "Quotidien",
"xpack.slo.duration.hourly": "Par heure",
"xpack.slo.duration.minutely": "Par minute",
"xpack.slo.duration.monthly": "Mensuel",
"xpack.slo.duration.weekly": "Hebdomadaire",
"xpack.slo.globalDiagnosis.errorNotification": "Vous ne disposez pas des autorisations nécessaires pour utiliser cette fonctionnalité.",
"xpack.slo.indicators.apmAvailability": "Disponibilité APM",
"xpack.slo.indicators.apmLatency": "Latence APM",
"xpack.slo.indicators.customKql": "KQL personnalisé",
"xpack.slo.indicators.customMetric": "Indicateur personnalisé",
"xpack.slo.indicators.histogram": "Indicateur d'histogramme",
"xpack.slo.item.actions.button": "Actions",
"xpack.slo.item.actions.clone": "Cloner",
"xpack.slo.item.actions.createRule": "Créer une règle d'alerte",
"xpack.slo.item.actions.delete": "Supprimer",
"xpack.slo.item.actions.details": "Détails",
"xpack.slo.item.actions.edit": "Modifier",
"xpack.slo.item.actions.manageRules": "Gérer les règles",
"xpack.slo.list.emptyMessage": "Il n'existe aucun résultat pour vos critères.",
"xpack.slo.list.emptyTitle": "Aucun résultat",
"xpack.slo.list.errorMessage": "Une erreur s'est produite lors du chargement des SLO. Contactez votre administrateur pour obtenir de l'aide.",
"xpack.slo.list.errorNotification": "Un problème est survenu lors de la récupération des SLO",
"xpack.slo.list.errorTitle": "Impossible de charger les SLO",
"xpack.slo.list.search": "Interroger vos SLO...",
"xpack.slo.list.sortBy.errorBudgetConsumed": "Budget d'erreur consommé",
"xpack.slo.list.sortBy.errorBudgetRemaining": "Budget d'erreur restant",
"xpack.slo.list.sortBy.sliValue": "Valeur SLI",
"xpack.slo.list.sortBy.sloStatus": "Statut SLO",
"xpack.slo.rules.actionGroupSelectorLabel": "Groupe daction",
"xpack.slo.rules.addWindowAriaLabel": "Ajouter une fenêtre",
"xpack.slo.rules.burnRate.defaultActionMessage": "\\{\\{context.reason\\}\\}\n\n\\{\\{rule.name\\}\\} est actif selon les conditions suivantes :\n\n- SLO : \\{\\{context.sloName\\}\\}'\n- Le taux d'avancement lors des derniers/dernières \\{\\{context.longWindow.duration\\}\\} est de \\{\\{context.longWindow.burnRate\\}\\}\n- Le taux d'avancement lors des derniers/dernières \\{\\{context.shortWindow.duration\\}\\} est de \\{\\{context.shortWindow.burnRate\\}\\}\n- Seuil : \\{\\{context.burnRateThreshold\\}\\}\n\n[Voir les détails de lalerte](\\{\\{context.alertDetailsUrl\\}\\})\n",
"xpack.slo.rules.burnRate.defaultRecoveryMessage": "\\{\\{context.reason\\}\\}\n\n\\{\\{rule.name\\}\\} a récupéré.\n\n- SLO : \\{\\{context.sloName\\}\\}'\n- Le taux d'avancement lors des derniers/dernières \\{\\{context.longWindow.duration\\}\\} est de \\{\\{context.longWindow.burnRate\\}\\}\n- Le taux d'avancement lors des derniers/dernières \\{\\{context.shortWindow.duration\\}\\} est de \\{\\{context.shortWindow.burnRate\\}\\}\n- Seuil : \\{\\{context.burnRateThreshold\\}\\}\n\n[Voir les détails de lalerte](\\{\\{context.alertDetailsUrl\\}\\})\n",
"xpack.slo.rules.burnRate.description": "Alerte lorsque votre taux d'avancement SLO est trop élevé sur une période définie.",
"xpack.slo.rules.burnRate.errors.burnRateThresholdRequired": "Le seuil de taux d'avancement est requis.",
"xpack.slo.rules.burnRate.errors.sloRequired": "Le SLO est requis.",
"xpack.slo.rules.burnRate.errors.windowDurationRequired": "La période historique est requise.",
"xpack.slo.rules.burnRate.name": "Taux d'avancement SLO",
"xpack.slo.rules.burnRate.rowLabel": "Seuil du taux d'avancement",
"xpack.slo.rules.burnRate.tooltip": "Le taux d'avancement correspond à la vitesse à laquelle le service consomme le budget d'erreur au cours de la période historique.",
"xpack.slo.rules.deleteWindowLabel": "Effacer la fenêtre",
"xpack.slo.rules.longWindow.errorText": "La période historique doit être comprise entre 1 et 72 heures.",
"xpack.slo.rules.longWindow.rowLabel": "Historique (heures)",
"xpack.slo.rules.longWindow.valueLabel": "Période historique en heures",
"xpack.slo.rules.sloSelector.ariaLabel": "SLO",
"xpack.slo.rules.sloSelector.placeholder": "Sélectionner un SLO",
"xpack.slo.rules.sloSelector.rowLabel": "SLO",
"xpack.slo.slo.activeAlertsBadge.ariaLabel": "badge alertes actives",
"xpack.slo.slo.item.actions.clone": "Cloner",
"xpack.slo.slo.item.actions.delete": "Supprimer",
"xpack.slo.slo.rulesBadge.popover": "Il n'y a pas encore de règles configurées pour ce SLO. Vous ne recevrez pas d'alertes lorsque le SLO est dépassé.",
"xpack.slo.sloDetails.errorBudgetChartPanel.chartTitle": "Budget d'erreur restant",
"xpack.slo.sloDetails.errorBudgetChartPanel.remaining": "Restant",
"xpack.slo.sloDetails.errorBudgetChartPanel.title": "Utilisation du budget d'erreur",
"xpack.slo.sloDetails.headerControl.actions": "Actions",
"xpack.slo.sloDetails.headerControl.createBurnRateRule": "Créer une règle d'alerte",
"xpack.slo.sloDetails.headerControl.edit": "Modifier",
"xpack.slo.sloDetails.headerTitle.createdMessage": "Créé le",
"xpack.slo.sloDetails.headerTitle.lastUpdatedMessage": "Dernière mise à jour le",
"xpack.slo.sloDetails.overview.apmSource": "Source APM",
"xpack.slo.sloDetails.overview.budgetingMethodTitle": "Méthode de budgétisation",
"xpack.slo.sloDetails.overview.descriptionTitle": "Description",
"xpack.slo.sloDetails.overview.indicatorTypeTitle": "Type dindicateur",
"xpack.slo.sloDetails.overview.observedValueTitle": "Valeur observée",
"xpack.slo.sloDetails.overview.tagsTitle": "Balises",
"xpack.slo.sloDetails.overview.timeWindowTitle": "Fenêtre temporelle",
"xpack.slo.sloDetails.sliHistoryChartPanel.chartTitle": "Valeur SLI",
"xpack.slo.sloDetails.sliHistoryChartPanel.current": "Valeur observée",
"xpack.slo.sloDetails.sliHistoryChartPanel.objective": "Objectif",
"xpack.slo.sloDetails.sliHistoryChartPanel.title": "SLI historique",
"xpack.slo.sloDetails.tab.alertsLabel": "Alertes",
"xpack.slo.sloDetails.tab.overviewLabel": "Aperçu",
"xpack.slo.sloEdit.apm.filter.tooltip": "Cette requête KQL est utilisée pour filtrer les indicateurs APM sur certains critères pertinents pour ce SLO.",
"xpack.slo.sloEdit.apm.serviceName.tooltip": "Il s'agit du service APM monitoré par ce SLO.",
"xpack.slo.sloEdit.apmAvailability.serviceEnvironment": "Environnement de service",
"xpack.slo.sloEdit.apmAvailability.serviceEnvironment.placeholder": "Sélectionner l'environnement",
"xpack.slo.sloEdit.apmAvailability.serviceName": "Nom de service",
"xpack.slo.sloEdit.apmAvailability.serviceName.placeholder": "Sélectionner le service APM",
"xpack.slo.sloEdit.apmAvailability.transactionName": "Nom de la transaction",
"xpack.slo.sloEdit.apmAvailability.transactionName.placeholder": "Sélectionner le nom de la transaction",
"xpack.slo.sloEdit.apmAvailability.transactionType": "Type de transaction",
"xpack.slo.sloEdit.apmAvailability.transactionType.placeholder": "Sélectionner le type de la transaction",
"xpack.slo.sloEdit.apmLatency.filter": "Filtre de requête",
"xpack.slo.sloEdit.apmLatency.filter.placeholder": "Filtre personnalisé à appliquer à l'index",
"xpack.slo.sloEdit.apmLatency.serviceEnvironment": "Environnement de service",
"xpack.slo.sloEdit.apmLatency.serviceEnvironment.placeholder": "Sélectionner l'environnement",
"xpack.slo.sloEdit.apmLatency.serviceName": "Nom de service",
"xpack.slo.sloEdit.apmLatency.serviceName.placeholder": "Sélectionner le service APM",
"xpack.slo.sloEdit.apmLatency.threshold.placeholder": "Seuil (ms)",
"xpack.slo.sloEdit.apmLatency.threshold.tooltip": "Configurez le seuil en millisecondes définissant les \"bonnes\" requêtes ou les requêtes \"réussies\" pour le SLO.",
"xpack.slo.sloEdit.apmLatency.transactionName": "Nom de la transaction",
"xpack.slo.sloEdit.apmLatency.transactionName.placeholder": "Sélectionner le nom de la transaction",
"xpack.slo.sloEdit.apmLatency.transactionType": "Type de transaction",
"xpack.slo.sloEdit.apmLatency.transactionType.placeholder": "Sélectionner le type de la transaction",
"xpack.slo.sloEdit.budgetingMethod.label": "Méthode de budgétisation",
"xpack.slo.sloEdit.budgetingMethod.tooltip": "Le SLO basé sur les occurrences utilise le rapport entre les bons événements et le nombre total d'événements au cours de la fenêtre temporelle. Le SLO basé sur les intervalles de temps utilise le rapport entre les bons intervalles de temps et le nombre total d'intervalles de temps au cours de la fenêtre temporelle.",
"xpack.slo.sloEdit.calendarTimeWindow.monthly": "Mensuel",
"xpack.slo.sloEdit.calendarTimeWindow.weekly": "Hebdomadaire",
"xpack.slo.sloEdit.cancelButton": "Annuler",
"xpack.slo.sloEdit.createSloButton": "Créer un SLO",
"xpack.slo.sloEdit.customKql.indexSelection.label": "Index",
"xpack.slo.sloEdit.dataPreviewChart.errorMessage": "Les paramètres d'indicateur actuels ne sont pas valides",
"xpack.slo.sloEdit.dataPreviewChart.explanationMessage": "Remplir les champs d'indicateur pour visualiser les indicateurs actuels",
"xpack.slo.sloEdit.dataPreviewChart.panelLabel": "Aperçu du SLI",
"xpack.slo.sloEdit.dataPreviewChart.xTitle": "Dernière heure",
"xpack.slo.sloEdit.dataPreviewChart.yTitle": "SLI",
"xpack.slo.sloEdit.definition.sliType": "Choisir le type de SLI",
"xpack.slo.sloEdit.definition.title": "Définir un SLI",
"xpack.slo.sloEdit.description.sloDescription": "Description",
"xpack.slo.sloEdit.description.sloDescriptionPlaceholder": "Brève description du SLO",
"xpack.slo.sloEdit.description.sloName": "Nom SLO",
"xpack.slo.sloEdit.description.sloNamePlaceholder": "Nom du SLO",
"xpack.slo.sloEdit.description.title": "Décrire le SLO",
"xpack.slo.sloEdit.editSloButton": "Mettre à jour le SLO",
"xpack.slo.sloEdit.fieldSelector.all": "Tous",
"xpack.slo.sloEdit.groupBy.label": "Partition conditionnée",
"xpack.slo.sloEdit.groupBy.placeholder": "Sélectionner un champ facultatif selon lequel effectuer la partition",
"xpack.slo.sloEdit.groupBy.tooltip": "Créer des SLO individuels pour chaque valeur du champ sélectionné.",
"xpack.slo.sloEdit.objectives.title": "Définir des objectifs",
"xpack.slo.sloEdit.sliType.customKql.customFilter": "Filtre personnalisé à appliquer à l'index",
"xpack.slo.sloEdit.sliType.customKql.customFilter.tooltip": "Cette requête KQL peut être utilisée pour filtrer les documents avec certains critères pertinents.",
"xpack.slo.sloEdit.sliType.customKql.goodQuery": "Bonne question",
"xpack.slo.sloEdit.sliType.customKql.goodQuery.tooltip": "Cette requête KQL doit renvoyer un sous-ensemble d'événements considérés comme \"bons\" ou \"réussis\" aux fins du calcul du SLO. La requête doit filtrer les événements en fonction de certains critères pertinents, tels que les codes de statut, les messages d'erreur ou d'autres champs pertinents.",
"xpack.slo.sloEdit.sliType.customKql.goodQueryPlaceholder": "Définir les bons événements",
"xpack.slo.sloEdit.sliType.customKql.queryFilter": "Filtre de requête",
"xpack.slo.sloEdit.sliType.customKql.totalQuery": "Total de la requête",
"xpack.slo.sloEdit.sliType.customKql.totalQuery.tooltip": "Cette requête KQL doit renvoyer tous les événements pertinents pour le calcul du SLO, y compris les bons et les mauvais événements.",
"xpack.slo.sloEdit.sliType.customKql.totalQueryPlaceholder": "Définir le total d'événements",
"xpack.slo.sloEdit.sliType.customMetric.addMetricAriaLabel": "Ajouter un indicateur",
"xpack.slo.sloEdit.sliType.customMetric.addMetricLabel": "Ajouter un indicateur",
"xpack.slo.sloEdit.sliType.customMetric.customFilter": "Filtre personnalisé à appliquer à l'index",
"xpack.slo.sloEdit.sliType.customMetric.customFilter.tooltip": "Cette requête KQL peut être utilisée pour filtrer les documents avec certains critères pertinents.",
"xpack.slo.sloEdit.sliType.customMetric.deleteLabel": "Supprimer un indicateur",
"xpack.slo.sloEdit.sliType.customMetric.equation.invalidCharacters": "Le champ d'équation prend en charge uniquement les caractères suivants : A-Z, +, -, /, *, (, ), ?, !, &, :, |, >, <, =",
"xpack.slo.sloEdit.sliType.customMetric.equationHelpText": "Accepte les équations mathématiques de base, les caractères valides sont : A-Z, +, -, /, *, (, ), ?, !, &, :, |, >, <, =",
"xpack.slo.sloEdit.sliType.customMetric.equationLabel": "Équation",
"xpack.slo.sloEdit.sliType.customMetric.filterLabel": "Filtre",
"xpack.slo.sloEdit.sliType.customMetric.goodTitle": "Bons événements",
"xpack.slo.sloEdit.sliType.customMetric.metricField.placeholder": "Sélectionner un champ dindicateur",
"xpack.slo.sloEdit.sliType.customMetric.metricLabel": "Indicateur",
"xpack.slo.sloEdit.sliType.customMetric.queryFilter": "Filtre de requête",
"xpack.slo.sloEdit.sliType.customMetric.totalEquation.tooltip": "Ceci est compatible avec des calculs de base (A + B / C) et la logique booléenne (A < B ? A : B).",
"xpack.slo.sloEdit.sliType.customMetric.totalMetric.tooltip": "Les données de ce champ seront agrégées avec lagréation de \"somme\".",
"xpack.slo.sloEdit.sliType.customMetric.totalTitle": "Total des événements",
"xpack.slo.sloEdit.sliType.histogram.aggregation.placeholder": "Choisir une agrégation",
"xpack.slo.sloEdit.sliType.histogram.aggregationLabel": "Agrégation",
"xpack.slo.sloEdit.sliType.histogram.aggregationTooltip": "L'agrégation \"value count\" (nombre de valeurs) renvoie le nombre total pour le champ d'histogramme. \"Range\" (plage) renvoie le nombre tiré du champ d'histogramme compris dans la plage définie ci-dessous.",
"xpack.slo.sloEdit.sliType.histogram.customFilter": "Filtre personnalisé à appliquer à l'index",
"xpack.slo.sloEdit.sliType.histogram.customFilter.tooltip": "Cette requête KQL peut être utilisée pour filtrer les documents avec certains critères pertinents.",
"xpack.slo.sloEdit.sliType.histogram.fromLabel": "De",
"xpack.slo.sloEdit.sliType.histogram.fromTooltip": "La valeur \"from\" (de) est inclusive.",
"xpack.slo.sloEdit.sliType.histogram.goodTitle": "Bons événements",
"xpack.slo.sloEdit.sliType.histogram.kqlFilterLabel": "Filtre KQL",
"xpack.slo.sloEdit.sliType.histogram.metricField.placeholder": "Sélectionner un champ d'histogramme",
"xpack.slo.sloEdit.sliType.histogram.metricLabel": "Champ",
"xpack.slo.sloEdit.sliType.histogram.query.tooltip": "Cette requête KQL doit renvoyer un sous-ensemble d'événements pour cet indicateur.",
"xpack.slo.sloEdit.sliType.histogram.queryFilter": "Filtre de requête",
"xpack.slo.sloEdit.sliType.histogram.rangeLabel": "Plage",
"xpack.slo.sloEdit.sliType.histogram.sourceTitle": "Source",
"xpack.slo.sloEdit.sliType.histogram.toLabel": "À",
"xpack.slo.sloEdit.sliType.histogram.totalTitle": "Total des événements",
"xpack.slo.sloEdit.sliType.histogram.toTooltip": "La valeur \"to\" (à) n'est PAS inclusive.",
"xpack.slo.sloEdit.sliType.histogram.valueCountLabel": "Compte de valeurs",
"xpack.slo.sloEdit.tags.label": "Balises",
"xpack.slo.sloEdit.tags.placeholder": "Ajouter des balises",
"xpack.slo.sloEdit.targetSlo.label": "Cible/SLO (%)",
"xpack.slo.sloEdit.targetSlo.tooltip": "L'objectif cible en pourcentage pour le SLO.",
"xpack.slo.sloEdit.timeSliceTarget.label": "Cible d'intervalle de temps (%)",
"xpack.slo.sloEdit.timeSliceTarget.tooltip": "La cible d'intervalle de temps individuel utilisée pour déterminer si l'intervalle est bon ou mauvais.",
"xpack.slo.sloEdit.timesliceWindow.label": "Fenêtre d'intervalle de temps (en minutes)",
"xpack.slo.sloEdit.timesliceWindow.tooltip": "La taille de la fenêtre d'intervalle de temps utilisée pour évaluer les données.",
"xpack.slo.sloEdit.timestampField.label": "Champ d'horodatage",
"xpack.slo.sloEdit.timestampField.placeholder": "Sélectionner un champ d'horodatage",
"xpack.slo.sloEdit.timeWindow.calendarAligned": "Alignée sur le calendrier",
"xpack.slo.sloEdit.timeWindow.rolling": "Glissante",
"xpack.slo.sloEdit.timeWindowDuration.label": "Durée",
"xpack.slo.sloEdit.timeWindowDuration.tooltip": "La durée de la fenêtre temporelle utilisée pour calculer le SLO.",
"xpack.slo.sloEdit.timeWindowType.label": "Fenêtre temporelle",
"xpack.slo.sloEdit.timeWindowType.tooltip": "Choisissez entre une fenêtre glissante ou alignée sur le calendrier.",
"xpack.slo.sloList.welcomePrompt.buttonLabel": "Créer un SLO",
"xpack.slo.sloList.welcomePrompt.getStartedMessage": "Pour commencer, créez votre premier SLO.",
"xpack.slo.sloList.welcomePrompt.learnMore": "Envie d'en savoir plus ?",
"xpack.slo.sloList.welcomePrompt.learnMoreLink": "Lisez les documents",
"xpack.slo.sloList.welcomePrompt.messageParagraph1": "Mesurez les indicateurs clés importants pour l'entreprise, tels que les indicateurs et les objectifs de niveau de service (SLI/SLO), afin de respecter les SLA établis.",
"xpack.slo.sloList.welcomePrompt.messageParagraph2": "Communiquez facilement sur la disponibilité et la fiabilité de vos services grâce à des informations en temps réel, et ce, pour la plus grande satisfaction des différents intervenants.",
"xpack.slo.sloList.welcomePrompt.needLicenseMessage": "Vous avez besoin d'un abonnement Elastic Cloud ou d'une licence Platinum pour utiliser les SLO.",
"xpack.slo.sloList.welcomePrompt.signupForCloud": "S'inscrire à Elastic Cloud",
"xpack.slo.sloList.welcomePrompt.signupForLicense": "S'inscrire pour une licence",
"xpack.slo.sloList.welcomePrompt.title": "Surveiller et respecter vos SLO",
"xpack.slo.sloStatusBadge.degrading": "Dégradation",
"xpack.slo.sloStatusBadge.forecasted": "Prévu",
"xpack.slo.sloStatusBadge.healthy": "Intègre",
"xpack.slo.sloStatusBadge.noData": "Aucune donnée",
"xpack.slo.sloStatusBadge.noDataTooltip": "L'agrégation et la mise à disposition des données peut prendre un peu de temps.",
"xpack.slo.sloStatusBadge.violated": "Violation",
"xpack.observabilityAiAssistant.chatCollapsedItems.hideEvents": "Masquer {count} événements",
"xpack.observabilityAiAssistant.chatCollapsedItems.showEvents": "Montrer {count} événements",
"xpack.observabilityAiAssistant.chatCompletionError.tokenLimitReachedError": "Limite de token atteinte. La limite de token est {tokenLimit}, mais la conversation actuelle a {tokenCount} tokens.",

View file

@ -30464,6 +30464,257 @@
"xpack.observability.ux.dashboard.webCoreVitals.help": "詳細",
"xpack.observability.ux.dashboard.webCoreVitals.helpAriaLabel": "ヘルプ",
"xpack.observability.ux.service.help": "最大トラフィックのRUMサービスが選択されています",
"xpack.slo.alerting.burnRate.reason": "{actionGroupName}:過去{longWindowDuration}のバーンレートは{longWindowBurnRate}で、過去{shortWindowDuration}のバーンレートは{shortWindowBurnRate}です。両期間とも{burnRateThreshold}を超えたらアラート",
"xpack.slo.alerting.burnRate.reasonForInstanceId": "{actionGroupName}:過去{longWindowDuration}のバーンレートは{longWindowBurnRate}、{instanceId}の過去{shortWindowDuration}のバーンレートは{shortWindowBurnRate}です。両期間とも{burnRateThreshold}を超えたらアラート",
"xpack.slo.burnRate.breachedStatustSubtitle": "現在のレートでは、エラー予算は{hour}時間後に使い果たされます。",
"xpack.slo.burnRate.threshold": "しきい値は{threshold}xです",
"xpack.slo.create.errorNotification": "{name}の作成中に問題が発生しました",
"xpack.slo.deleteConfirmationModal.title": "{name}を削除しますか?",
"xpack.slo.duration.day": "{duration, plural, other {#日}}",
"xpack.slo.duration.hour": "{duration, plural, other {#時間}}",
"xpack.slo.duration.minute": "{duration, plural, other {#分}}",
"xpack.slo.duration.month": "{duration, plural, other {#月}}",
"xpack.slo.duration.week": "{duration, plural, other {#週}}",
"xpack.slo.indicatorTypeBadge.exploreInApm": "{service}詳細を表示",
"xpack.slo.rules.burnRate.errors.invalidThresholdValue": "バーンレートしきい値は1以上{maxBurnRate}以下でなければなりません。",
"xpack.slo.rules.groupByMessage": "選択したSLOは\"{groupByField}\"にパーティションが作成されました。このルールは、パーティションフィールドで見つかったすべてのインスタンスを監視し、アラートを生成します。",
"xpack.slo.rules.longWindowDuration.tooltip": "バーンレートが計算されるルックバック期間。ルックバック期間を{shortWindowDuration}分ルックバック期間の1/12と短くすることで、より高速な復帰が可能になります",
"xpack.slo.slo.activeAlertsBadge.label": "{count, plural, other {#件のアラート}}",
"xpack.slo.slo.delete.errorNotification": "{name}の削除に失敗しました",
"xpack.slo.slo.delete.successNotification": "{name}が削除されました",
"xpack.slo.slo.timeWindow.calendar": "{elapsed}/{total}日",
"xpack.slo.sloDetails.errorBudgetChartPanel.duration": "過去{duration}",
"xpack.slo.sloDetails.overview.apmSource.environmentLabel": "環境:{value}",
"xpack.slo.sloDetails.overview.apmSource.serviceLabel": "サービス:{value}",
"xpack.slo.sloDetails.overview.apmSource.transactionNameLabel": "transactionName: {value}",
"xpack.slo.sloDetails.overview.apmSource.transactionTypeLabel": "transactionType: {value}",
"xpack.slo.sloDetails.overview.calendarAlignedTimeWindow": "{duration}カレンダーが調整されました",
"xpack.slo.sloDetails.overview.observedValueSubtitle": "{objective}(目的は{value}",
"xpack.slo.sloDetails.overview.rollingTimeWindow": "{duration}ローリング",
"xpack.slo.sloDetails.overview.timeslicesBudgetingMethodDetails": "{duration}スライス、{target}ターゲット",
"xpack.slo.sloDetails.sliHistoryChartPanel.duration": "過去{duration}",
"xpack.slo.sloEdit.rollingTimeWindow.days": "{number}日",
"xpack.slo.update.errorNotification": "{name}の更新中にエラーが発生しました",
"xpack.slo.update.successNotification": "正常に{name}を更新しました",
"xpack.slo.alerting.alertDetailsUrlDescription": "アラートトラブルシューティングビューにリンクして、さらに詳しい状況や詳細を確認できます。server.publicBaseUrlが構成されていない場合は、空の文字列になります。",
"xpack.slo.alerting.burnRate.alertAction": "重大",
"xpack.slo.alerting.burnRate.highPriorityAction": "高",
"xpack.slo.alerting.burnRate.lowPriorityAction": "低",
"xpack.slo.alerting.burnRate.mediumPriorityAction": "中",
"xpack.slo.alerting.reasonDescription": "アラートの理由の簡潔な説明",
"xpack.slo.alerting.sloIdDescription": "SLO一意のID。",
"xpack.slo.alerting.sloInstanceIdDescription": "SLOインスタンスID。",
"xpack.slo.alerting.sloNameDescription": "SLO名。",
"xpack.slo.alerting.thresholdDescription": "バーンレートしきい値。",
"xpack.slo.alerting.timestampDescription": "アラートが検出された時点のタイムスタンプ。",
"xpack.slo.alerting.viewInAppUrlDescription": "詳細な調査を支援するSLO詳細ページへのURL。",
"xpack.slo.alerting.windowDescription": "関連付けられたバーンレート値の期間。",
"xpack.slo.budgetingMethod.occurrences": "オカレンス",
"xpack.slo.budgetingMethod.timeslices": "タイムスライス",
"xpack.slo.burnRate.breachedStatustTitle": "重大値違反",
"xpack.slo.burnRate.noDataStatusSubtitle": "その他のデータを待機中です。",
"xpack.slo.burnRate.noDataStatusTitle": "値なし",
"xpack.slo.burnRate.okStatusSubtitle": "エラー予算が枯渇するリスクはありません。",
"xpack.slo.burnRate.okStatusTitle": "許容値",
"xpack.slo.burnRate.timeRangeBtnLegend": "時間範囲を選択",
"xpack.slo.burnRate.title": "バーンレート",
"xpack.slo.deleteConfirmationModal.cancelButtonLabel": "キャンセル",
"xpack.slo.deleteConfirmationModal.deleteButtonLabel": "削除",
"xpack.slo.deleteConfirmationModal.descriptionText": "このSLOを削除した後、復元することはできません。",
"xpack.slo.duration.daily": "日ごと",
"xpack.slo.duration.hourly": "1 時間ごと",
"xpack.slo.duration.minutely": "毎分",
"xpack.slo.duration.monthly": "月ごと",
"xpack.slo.duration.weekly": "週ごと",
"xpack.slo.globalDiagnosis.errorNotification": "この機能を使用する権限がありません。",
"xpack.slo.indicators.apmAvailability": "APM可用性",
"xpack.slo.indicators.apmLatency": "APMレイテンシ",
"xpack.slo.indicators.customKql": "カスタムKQL",
"xpack.slo.indicators.customMetric": "カスタムメトリック",
"xpack.slo.indicators.histogram": "ヒストグラムメトリック",
"xpack.slo.item.actions.button": "アクション",
"xpack.slo.item.actions.clone": "クローンを作成",
"xpack.slo.item.actions.createRule": "新しいアラートルールを作成",
"xpack.slo.item.actions.delete": "削除",
"xpack.slo.item.actions.details": "詳細",
"xpack.slo.item.actions.edit": "編集",
"xpack.slo.item.actions.manageRules": "ルールの管理",
"xpack.slo.list.emptyMessage": "条件に合った結果はありません。",
"xpack.slo.list.emptyTitle": "成果がありません",
"xpack.slo.list.errorMessage": "SLOオブジェクトの読み込みエラーが発生しました。ヘルプについては、管理者にお問い合わせください。",
"xpack.slo.list.errorNotification": "SLOの取得中に問題が発生しました",
"xpack.slo.list.errorTitle": "SLOを読み込めません",
"xpack.slo.list.search": "SLOを検索...",
"xpack.slo.list.sortBy.errorBudgetConsumed": "エラー予算が消費されました",
"xpack.slo.list.sortBy.errorBudgetRemaining": "残り予算エラー",
"xpack.slo.list.sortBy.sliValue": "SLI値",
"xpack.slo.list.sortBy.sloStatus": "SLOステータス",
"xpack.slo.rules.actionGroupSelectorLabel": "アクショングループ",
"xpack.slo.rules.addWindowAriaLabel": "時間枠を追加",
"xpack.slo.rules.burnRate.defaultActionMessage": "\\{\\{context.reason\\}\\}\n\n\\{\\{rule.name\\}\\}は次の条件でアクティブです。\n\n- SLO: \\{\\{context.sloName\\}\\}'\n- 過去\\{\\{context.longWindow.duration\\}\\}のバーンレートが\\{\\{context.longWindow.burnRate\\}\\}である\n- 過去\\{\\{context.shortWindow.duration\\}\\}のバーンレートが\\{\\{context.shortWindow.burnRate\\}\\}である\n- Threshold: \\{\\{context.burnRateThreshold\\}\\}\n\n[アラート詳細を表示](\\{\\{context.alertDetailsUrl\\}\\})\n",
"xpack.slo.rules.burnRate.defaultRecoveryMessage": "\\{\\{context.reason\\}\\}\n\n\\{\\{rule.name\\}\\}が回復しました。\n\n- SLO: \\{\\{context.sloName\\}\\}'\n- 過去\\{\\{context.longWindow.duration\\}\\}のバーンレートが\\{\\{context.longWindow.burnRate\\}\\}である\n- 過去\\{\\{context.shortWindow.duration\\}\\}のバーンレートが\\{\\{context.shortWindow.burnRate\\}\\}である\n- Threshold: \\{\\{context.burnRateThreshold\\}\\}\n\n[アラート詳細を表示](\\{\\{context.alertDetailsUrl\\}\\})\n",
"xpack.slo.rules.burnRate.description": "SLOバーンレートが定義された期間で高すぎるときにアラートを通知します。",
"xpack.slo.rules.burnRate.errors.burnRateThresholdRequired": "バーンレートしきい値は必須です。",
"xpack.slo.rules.burnRate.errors.sloRequired": "SLOが必要です。",
"xpack.slo.rules.burnRate.errors.windowDurationRequired": "ループバック期間は必須です。",
"xpack.slo.rules.burnRate.name": "SLOバーンレート",
"xpack.slo.rules.burnRate.rowLabel": "バーンレートしきい値",
"xpack.slo.rules.burnRate.tooltip": "バーンレートは、サービスがルックバック期間でエラー予算をどの程度速く消費するのかを示します。",
"xpack.slo.rules.deleteWindowLabel": "時間枠を削除",
"xpack.slo.rules.longWindow.errorText": "ループバック期間は172時間でなければなりません。",
"xpack.slo.rules.longWindow.rowLabel": "ルックバック(時間)",
"xpack.slo.rules.longWindow.valueLabel": "ルックバック期間(時間)",
"xpack.slo.rules.sloSelector.ariaLabel": "SLO",
"xpack.slo.rules.sloSelector.placeholder": "SLOを選択",
"xpack.slo.rules.sloSelector.rowLabel": "SLO",
"xpack.slo.slo.activeAlertsBadge.ariaLabel": "アクティブアラートバッジ",
"xpack.slo.slo.item.actions.clone": "クローンを作成",
"xpack.slo.slo.item.actions.delete": "削除",
"xpack.slo.slo.rulesBadge.popover": "このSLOではまだルールが構成されていません。SLOに違反したときにアラートを受信しません。",
"xpack.slo.sloDetails.errorBudgetChartPanel.chartTitle": "残り予算エラー",
"xpack.slo.sloDetails.errorBudgetChartPanel.remaining": "残り",
"xpack.slo.sloDetails.errorBudgetChartPanel.title": "エラー予算バーンダウン",
"xpack.slo.sloDetails.headerControl.actions": "アクション",
"xpack.slo.sloDetails.headerControl.createBurnRateRule": "新しいアラートルールを作成",
"xpack.slo.sloDetails.headerControl.edit": "編集",
"xpack.slo.sloDetails.headerTitle.createdMessage": "作成日時",
"xpack.slo.sloDetails.headerTitle.lastUpdatedMessage": "最終更新日",
"xpack.slo.sloDetails.overview.apmSource": "APMソース",
"xpack.slo.sloDetails.overview.budgetingMethodTitle": "予算設定方法",
"xpack.slo.sloDetails.overview.descriptionTitle": "説明",
"xpack.slo.sloDetails.overview.indicatorTypeTitle": "インジケータータイプ",
"xpack.slo.sloDetails.overview.observedValueTitle": "観測された値",
"xpack.slo.sloDetails.overview.tagsTitle": "タグ",
"xpack.slo.sloDetails.overview.timeWindowTitle": "時間枠",
"xpack.slo.sloDetails.sliHistoryChartPanel.chartTitle": "SLI値",
"xpack.slo.sloDetails.sliHistoryChartPanel.current": "観測された値",
"xpack.slo.sloDetails.sliHistoryChartPanel.objective": "目的",
"xpack.slo.sloDetails.sliHistoryChartPanel.title": "履歴SLI",
"xpack.slo.sloDetails.tab.alertsLabel": "アラート",
"xpack.slo.sloDetails.tab.overviewLabel": "概要",
"xpack.slo.sloEdit.apm.filter.tooltip": "このKQLクエリは、このSLOの一部の関連する情報でAPMメトリックをフィルタリングするために使用されます。",
"xpack.slo.sloEdit.apm.serviceName.tooltip": "これはこのSLOによって監視されるAPMサービスです。",
"xpack.slo.sloEdit.apmAvailability.serviceEnvironment": "サービス環境",
"xpack.slo.sloEdit.apmAvailability.serviceEnvironment.placeholder": "環境を選択",
"xpack.slo.sloEdit.apmAvailability.serviceName": "サービス名",
"xpack.slo.sloEdit.apmAvailability.serviceName.placeholder": "APMサービスを選択",
"xpack.slo.sloEdit.apmAvailability.transactionName": "トランザクション名",
"xpack.slo.sloEdit.apmAvailability.transactionName.placeholder": "トランザクション名を選択",
"xpack.slo.sloEdit.apmAvailability.transactionType": "トランザクションタイプ",
"xpack.slo.sloEdit.apmAvailability.transactionType.placeholder": "トランザクションタイプを選択",
"xpack.slo.sloEdit.apmLatency.filter": "クエリのフィルター",
"xpack.slo.sloEdit.apmLatency.filter.placeholder": "インデックスで適用するカスタムフィルター",
"xpack.slo.sloEdit.apmLatency.serviceEnvironment": "サービス環境",
"xpack.slo.sloEdit.apmLatency.serviceEnvironment.placeholder": "環境を選択",
"xpack.slo.sloEdit.apmLatency.serviceName": "サービス名",
"xpack.slo.sloEdit.apmLatency.serviceName.placeholder": "APMサービスを選択",
"xpack.slo.sloEdit.apmLatency.threshold.placeholder": "しきい値(ミリ秒)",
"xpack.slo.sloEdit.apmLatency.threshold.tooltip": "SLOで「良好」または「成功」リクエストを定義するしきい値ミリ秒を構成します。",
"xpack.slo.sloEdit.apmLatency.transactionName": "トランザクション名",
"xpack.slo.sloEdit.apmLatency.transactionName.placeholder": "トランザクション名を選択",
"xpack.slo.sloEdit.apmLatency.transactionType": "トランザクションタイプ",
"xpack.slo.sloEdit.apmLatency.transactionType.placeholder": "トランザクションタイプを選択",
"xpack.slo.sloEdit.budgetingMethod.label": "予算設定方法",
"xpack.slo.sloEdit.budgetingMethod.tooltip": "出現に基づくSLOは、該当期間における、合計イベント数に対する良好なイベント数の比率を使用します。タイムスライスに基づくSLOは、該当期間における、合計タイムスライス数に対する良好なタイムスライス数の比率を使用します。",
"xpack.slo.sloEdit.calendarTimeWindow.monthly": "月ごと",
"xpack.slo.sloEdit.calendarTimeWindow.weekly": "週ごと",
"xpack.slo.sloEdit.cancelButton": "キャンセル",
"xpack.slo.sloEdit.createSloButton": "SLOの作成",
"xpack.slo.sloEdit.customKql.indexSelection.label": "インデックス",
"xpack.slo.sloEdit.dataPreviewChart.errorMessage": "現在のインジケーター設定は無効です",
"xpack.slo.sloEdit.dataPreviewChart.explanationMessage": "インジケーターフィールドに入力すると、現在のメトリックが可視化されます。",
"xpack.slo.sloEdit.dataPreviewChart.panelLabel": "SLIプレビュー",
"xpack.slo.sloEdit.dataPreviewChart.xTitle": "過去 1 時間",
"xpack.slo.sloEdit.dataPreviewChart.yTitle": "SLI",
"xpack.slo.sloEdit.definition.sliType": "SLIタイプを選択",
"xpack.slo.sloEdit.definition.title": "SLIを定義",
"xpack.slo.sloEdit.description.sloDescription": "説明",
"xpack.slo.sloEdit.description.sloDescriptionPlaceholder": "SLOの簡潔な説明",
"xpack.slo.sloEdit.description.sloName": "SLO名",
"xpack.slo.sloEdit.description.sloNamePlaceholder": "SLOの名前",
"xpack.slo.sloEdit.description.title": "SLOの説明",
"xpack.slo.sloEdit.editSloButton": "SLOの更新",
"xpack.slo.sloEdit.fieldSelector.all": "すべて",
"xpack.slo.sloEdit.groupBy.label": "パーティション",
"xpack.slo.sloEdit.groupBy.placeholder": "パーティション分割する任意のフィールドを選択",
"xpack.slo.sloEdit.groupBy.tooltip": "選択したフィールドの値ごとに個別のSLOを作成します。",
"xpack.slo.sloEdit.objectives.title": "目標を設定",
"xpack.slo.sloEdit.sliType.customKql.customFilter": "インデックスで適用するカスタムフィルター",
"xpack.slo.sloEdit.sliType.customKql.customFilter.tooltip": "このKQLクエリを使用して、一部の関連する条件でドキュメントをフィルタリングできます。",
"xpack.slo.sloEdit.sliType.customKql.goodQuery": "良いクエリ",
"xpack.slo.sloEdit.sliType.customKql.goodQuery.tooltip": "このKQLクエリは、SLOを計算する目的で、「良好」または「成功」と見なされるイベントのサブセットを返します。このクエリは、ステータスコード、エラー、メッセージ、または他の関連するフィールドなどの一部の関連する条件に基づいて、イベントをフィルタリングします。",
"xpack.slo.sloEdit.sliType.customKql.goodQueryPlaceholder": "良いイベントを定義",
"xpack.slo.sloEdit.sliType.customKql.queryFilter": "クエリのフィルター",
"xpack.slo.sloEdit.sliType.customKql.totalQuery": "合計クエリ",
"xpack.slo.sloEdit.sliType.customKql.totalQuery.tooltip": "このKQLクエリは、良好なイベントと問題があるイベントの両方を含む、SLO計算に関連するすべてのイベントを返します。",
"xpack.slo.sloEdit.sliType.customKql.totalQueryPlaceholder": "合計イベントを定義",
"xpack.slo.sloEdit.sliType.customMetric.addMetricAriaLabel": "メトリックを追加",
"xpack.slo.sloEdit.sliType.customMetric.addMetricLabel": "メトリックを追加",
"xpack.slo.sloEdit.sliType.customMetric.customFilter": "インデックスで適用するカスタムフィルター",
"xpack.slo.sloEdit.sliType.customMetric.customFilter.tooltip": "このKQLクエリを使用して、一部の関連する条件でドキュメントをフィルタリングできます。",
"xpack.slo.sloEdit.sliType.customMetric.deleteLabel": "メトリックを削除",
"xpack.slo.sloEdit.sliType.customMetric.equation.invalidCharacters": "等式フィールドでは次の文字のみを使用できますA-Z、+、-、/、*、(、)、?、!、&、:、|、>、<、=",
"xpack.slo.sloEdit.sliType.customMetric.equationHelpText": "基本的な数式をサポートします。有効な文字A-Z、+、-、/、*、(、)、?、!、&、:、|、>、<、=",
"xpack.slo.sloEdit.sliType.customMetric.equationLabel": "式",
"xpack.slo.sloEdit.sliType.customMetric.filterLabel": "フィルター",
"xpack.slo.sloEdit.sliType.customMetric.goodTitle": "良好なイベント数",
"xpack.slo.sloEdit.sliType.customMetric.metricField.placeholder": "メトリックフィールドを選択",
"xpack.slo.sloEdit.sliType.customMetric.metricLabel": "メトリック",
"xpack.slo.sloEdit.sliType.customMetric.queryFilter": "クエリのフィルター",
"xpack.slo.sloEdit.sliType.customMetric.totalEquation.tooltip": "これは基本的な数学ロジックA + B / CとブールロジックA < B ?A :Bをサポートします。",
"xpack.slo.sloEdit.sliType.customMetric.totalMetric.tooltip": "このフィールドのデータは「sum」集計で集約されます。",
"xpack.slo.sloEdit.sliType.customMetric.totalTitle": "合計イベント数",
"xpack.slo.sloEdit.sliType.histogram.aggregation.placeholder": "集約を選択してください",
"xpack.slo.sloEdit.sliType.histogram.aggregationLabel": "アグリゲーション",
"xpack.slo.sloEdit.sliType.histogram.aggregationTooltip": "\"value count\"集約は、ヒストグラムフィールドの合計カウントを返します。Rangeは、ヒストグラムフィールドから、以下で定義された範囲内のカウントを返します。",
"xpack.slo.sloEdit.sliType.histogram.customFilter": "インデックスで適用するカスタムフィルター",
"xpack.slo.sloEdit.sliType.histogram.customFilter.tooltip": "このKQLクエリを使用して、一部の関連する条件でドキュメントをフィルタリングできます。",
"xpack.slo.sloEdit.sliType.histogram.fromLabel": "開始:",
"xpack.slo.sloEdit.sliType.histogram.fromTooltip": "\"from\"値は含まれます。",
"xpack.slo.sloEdit.sliType.histogram.goodTitle": "良好なイベント数",
"xpack.slo.sloEdit.sliType.histogram.kqlFilterLabel": "KQLフィルター",
"xpack.slo.sloEdit.sliType.histogram.metricField.placeholder": "ヒストグラムフィールドを選択",
"xpack.slo.sloEdit.sliType.histogram.metricLabel": "フィールド",
"xpack.slo.sloEdit.sliType.histogram.query.tooltip": "このKQLクエリは、このインジケーターのイベントのサブセットを返します。",
"xpack.slo.sloEdit.sliType.histogram.queryFilter": "クエリのフィルター",
"xpack.slo.sloEdit.sliType.histogram.rangeLabel": "範囲",
"xpack.slo.sloEdit.sliType.histogram.sourceTitle": "送信元",
"xpack.slo.sloEdit.sliType.histogram.toLabel": "終了:",
"xpack.slo.sloEdit.sliType.histogram.totalTitle": "合計イベント数",
"xpack.slo.sloEdit.sliType.histogram.toTooltip": "\"to\"値は含まれません。",
"xpack.slo.sloEdit.sliType.histogram.valueCountLabel": "値カウント",
"xpack.slo.sloEdit.tags.label": "タグ",
"xpack.slo.sloEdit.tags.placeholder": "タグを追加",
"xpack.slo.sloEdit.targetSlo.label": "目標 / SLO%",
"xpack.slo.sloEdit.targetSlo.tooltip": "SLOの目標%)。",
"xpack.slo.sloEdit.timeSliceTarget.label": "タイムスライス目標(%",
"xpack.slo.sloEdit.timeSliceTarget.tooltip": "スライスが良好か問題があるかどうかを判断するために使用される、個別のタイムスライス目標。",
"xpack.slo.sloEdit.timesliceWindow.label": "タイムスライス期間(分)",
"xpack.slo.sloEdit.timesliceWindow.tooltip": "データを評価するために使用されるタイムスライス期間サイズ。",
"xpack.slo.sloEdit.timestampField.label": "タイムスタンプフィールド",
"xpack.slo.sloEdit.timestampField.placeholder": "タイムスタンプフィールドを選択",
"xpack.slo.sloEdit.timeWindow.calendarAligned": "カレンダーが調整されました",
"xpack.slo.sloEdit.timeWindow.rolling": "ローリング",
"xpack.slo.sloEdit.timeWindowDuration.label": "期間",
"xpack.slo.sloEdit.timeWindowDuration.tooltip": "SLOを計算するために使用される時間枠期間。",
"xpack.slo.sloEdit.timeWindowType.label": "時間枠",
"xpack.slo.sloEdit.timeWindowType.tooltip": "ローリング時間枠とカレンダー時間枠のどちらかを選択します。",
"xpack.slo.sloList.welcomePrompt.buttonLabel": "SLOの作成",
"xpack.slo.sloList.welcomePrompt.getStartedMessage": "開始するには、まずSLOを作成します。",
"xpack.slo.sloList.welcomePrompt.learnMore": "詳細について",
"xpack.slo.sloList.welcomePrompt.learnMoreLink": "<b>ドキュメント</b><b>を読む</b>",
"xpack.slo.sloList.welcomePrompt.messageParagraph1": "SLAを遂行するには、SLIサービスレベル指標やSLOサービスレベル目標など、ビジネス上重要なメトリックを計測する必要があります。",
"xpack.slo.sloList.welcomePrompt.messageParagraph2": "リアルタイムなインサイトを入手して、サービスのアップタイムや信頼性を手軽に利害関係者向けのレポートにまとめましょう。",
"xpack.slo.sloList.welcomePrompt.needLicenseMessage": "SLOを使用するには、Elastic Cloudサブスクリプションまたはプレミアムライセンスが必要です。",
"xpack.slo.sloList.welcomePrompt.signupForCloud": "Elastic Cloudに登録",
"xpack.slo.sloList.welcomePrompt.signupForLicense": "ライセンスを登録",
"xpack.slo.sloList.welcomePrompt.title": "SLOを追跡して遵守",
"xpack.slo.sloStatusBadge.degrading": "劣化",
"xpack.slo.sloStatusBadge.forecasted": "予測",
"xpack.slo.sloStatusBadge.healthy": "正常",
"xpack.slo.sloStatusBadge.noData": "データなし",
"xpack.slo.sloStatusBadge.noDataTooltip": "データが集約され、利用可能になるまでには時間がかかる場合があります。",
"xpack.slo.sloStatusBadge.violated": "違反",
"xpack.observabilityAiAssistant.chatCollapsedItems.hideEvents": "{count}件のイベントを非表示",
"xpack.observabilityAiAssistant.chatCollapsedItems.showEvents": "{count}件のイベントを表示",
"xpack.observabilityAiAssistant.chatCompletionError.tokenLimitReachedError": "トークンの上限に達しました。トークンの上限は{tokenLimit}ですが、現在の会話には{tokenCount}個のトークンがあります。",

View file

@ -30504,6 +30504,257 @@
"xpack.observability.ux.dashboard.webCoreVitals.help": "详细了解",
"xpack.observability.ux.dashboard.webCoreVitals.helpAriaLabel": "帮助",
"xpack.observability.ux.service.help": "选择流量最高的 RUM 服务",
"xpack.slo.alerting.burnRate.reason": "{actionGroupName}:过去 {longWindowDuration} 的消耗速度为 {longWindowBurnRate} 且过去 {shortWindowDuration} 为 {shortWindowBurnRate}。两个窗口超出 {burnRateThreshold} 时告警",
"xpack.slo.alerting.burnRate.reasonForInstanceId": "{actionGroupName}:过去 {longWindowDuration} 的消耗速度为 {longWindowBurnRate},且对于 {instanceId},过去 {shortWindowDuration} 为 {shortWindowBurnRate}。两个窗口超出 {burnRateThreshold} 时告警",
"xpack.slo.burnRate.breachedStatustSubtitle": "按照当前的速率,错误预算将在 {hour} 小时后耗尽。",
"xpack.slo.burnRate.threshold": "阈值为 {threshold}x",
"xpack.slo.create.errorNotification": "创建 {name} 时出现问题",
"xpack.slo.deleteConfirmationModal.title": "删除 {name}",
"xpack.slo.duration.day": "{duration, plural, other {# 天}}",
"xpack.slo.duration.hour": "{duration, plural, other {# 小时}}",
"xpack.slo.duration.minute": "{duration, plural, other {# 分钟}}",
"xpack.slo.duration.month": "{duration, plural, other {# 个月}}",
"xpack.slo.duration.week": "{duration, plural, other {# 周}}",
"xpack.slo.indicatorTypeBadge.exploreInApm": "查看 {service} 详情",
"xpack.slo.rules.burnRate.errors.invalidThresholdValue": "消耗速度阈值必须介于 1 和 {maxBurnRate} 之间。",
"xpack.slo.rules.groupByMessage": "已使用分区在“{groupByField}”上创建您选定的 SLO。此规则将监测在分区字段中发现的每个实例并为其生成告警。",
"xpack.slo.rules.longWindowDuration.tooltip": "在其间计算消耗速度的回顾期。将使用 {shortWindowDuration} 分钟的较短回顾期1/12 的回顾期)以便更快恢复",
"xpack.slo.slo.activeAlertsBadge.label": "{count, plural, other {# 个告警}}",
"xpack.slo.slo.delete.errorNotification": "无法删除{name}",
"xpack.slo.slo.delete.successNotification": "已删除 {name}",
"xpack.slo.slo.timeWindow.calendar": "{elapsed}/{total} 天",
"xpack.slo.sloDetails.errorBudgetChartPanel.duration": "过去 {duration}",
"xpack.slo.sloDetails.overview.apmSource.environmentLabel": "环境:{value}",
"xpack.slo.sloDetails.overview.apmSource.serviceLabel": "服务:{value}",
"xpack.slo.sloDetails.overview.apmSource.transactionNameLabel": "事务名称:{value}",
"xpack.slo.sloDetails.overview.apmSource.transactionTypeLabel": "事务类型:{value}",
"xpack.slo.sloDetails.overview.calendarAlignedTimeWindow": "{duration} 日历已对齐",
"xpack.slo.sloDetails.overview.observedValueSubtitle": "{value}(目标为 {objective}",
"xpack.slo.sloDetails.overview.rollingTimeWindow": "{duration} 滚动",
"xpack.slo.sloDetails.overview.timeslicesBudgetingMethodDetails": "{duration} 切片,{target} 目标",
"xpack.slo.sloDetails.sliHistoryChartPanel.duration": "过去 {duration}",
"xpack.slo.sloEdit.rollingTimeWindow.days": "{number} 天",
"xpack.slo.update.errorNotification": "更新 {name} 时出现问题",
"xpack.slo.update.successNotification": "成功更新 {name}",
"xpack.slo.alerting.alertDetailsUrlDescription": "链接到告警故障排除视图获取进一步的上下文和详情。如果未配置 server.publicBaseUrl这将为空字符串。",
"xpack.slo.alerting.burnRate.alertAction": "紧急",
"xpack.slo.alerting.burnRate.highPriorityAction": "高",
"xpack.slo.alerting.burnRate.lowPriorityAction": "低",
"xpack.slo.alerting.burnRate.mediumPriorityAction": "中",
"xpack.slo.alerting.reasonDescription": "告警原因的简洁描述",
"xpack.slo.alerting.sloIdDescription": "SLO 唯一标识符。",
"xpack.slo.alerting.sloInstanceIdDescription": "SLO 实例 ID。",
"xpack.slo.alerting.sloNameDescription": "SLO 名称。",
"xpack.slo.alerting.thresholdDescription": "消耗速度阈值。",
"xpack.slo.alerting.timestampDescription": "检测到告警时的时间戳。",
"xpack.slo.alerting.viewInAppUrlDescription": "SLO 详情页面的 URL以帮助进行进一步调查。",
"xpack.slo.alerting.windowDescription": "带有关联的消耗速度值的窗口持续时间。",
"xpack.slo.budgetingMethod.occurrences": "发生次数",
"xpack.slo.budgetingMethod.timeslices": "时间片",
"xpack.slo.burnRate.breachedStatustTitle": "已超出临界值",
"xpack.slo.burnRate.noDataStatusSubtitle": "等待更多数据。",
"xpack.slo.burnRate.noDataStatusTitle": "无值",
"xpack.slo.burnRate.okStatusSubtitle": "没有错误预算耗尽风险。",
"xpack.slo.burnRate.okStatusTitle": "可接受的值",
"xpack.slo.burnRate.timeRangeBtnLegend": "选择时间范围",
"xpack.slo.burnRate.title": "消耗速度",
"xpack.slo.deleteConfirmationModal.cancelButtonLabel": "取消",
"xpack.slo.deleteConfirmationModal.deleteButtonLabel": "删除",
"xpack.slo.deleteConfirmationModal.descriptionText": "此 SLO 删除后无法恢复。",
"xpack.slo.duration.daily": "每日",
"xpack.slo.duration.hourly": "每小时",
"xpack.slo.duration.minutely": "每分钟",
"xpack.slo.duration.monthly": "每月",
"xpack.slo.duration.weekly": "每周",
"xpack.slo.globalDiagnosis.errorNotification": "您没有适当权限,无法使用此功能。",
"xpack.slo.indicators.apmAvailability": "APM 可用性",
"xpack.slo.indicators.apmLatency": "APM 延迟",
"xpack.slo.indicators.customKql": "定制 KQL",
"xpack.slo.indicators.customMetric": "定制指标",
"xpack.slo.indicators.histogram": "直方图指标",
"xpack.slo.item.actions.button": "操作",
"xpack.slo.item.actions.clone": "克隆",
"xpack.slo.item.actions.createRule": "创建新告警规则",
"xpack.slo.item.actions.delete": "删除",
"xpack.slo.item.actions.details": "详情",
"xpack.slo.item.actions.edit": "编辑",
"xpack.slo.item.actions.manageRules": "管理规则",
"xpack.slo.list.emptyMessage": "没有匹配您的条件的结果。",
"xpack.slo.list.emptyTitle": "无结果",
"xpack.slo.list.errorMessage": "加载 SLO 时出错。请联系您的管理员寻求帮助。",
"xpack.slo.list.errorNotification": "提取 SLO 时出现问题",
"xpack.slo.list.errorTitle": "无法加载 SLO",
"xpack.slo.list.search": "搜索您的 SLO......",
"xpack.slo.list.sortBy.errorBudgetConsumed": "已消耗错误预算",
"xpack.slo.list.sortBy.errorBudgetRemaining": "剩余错误预算",
"xpack.slo.list.sortBy.sliValue": "SLI 值",
"xpack.slo.list.sortBy.sloStatus": "SLO 状态",
"xpack.slo.rules.actionGroupSelectorLabel": "操作组",
"xpack.slo.rules.addWindowAriaLabel": "添加窗口",
"xpack.slo.rules.burnRate.defaultActionMessage": "\\{\\{context.reason\\}\\}\n\n\\{\\{rule.name\\}\\} 为活动状态,条件如下:\n\n- SLO\\{\\{context.sloName\\}\\}'\n- 过去 \\{\\{context.longWindow.duration\\}\\} 的消耗速度为 \\{\\{context.longWindow.burnRate\\}\\}\n- 过去 \\{\\{context.shortWindow.duration\\}\\} 的消耗速度为 \\{\\{context.shortWindow.burnRate\\}\\}\n- Threshold: \\{\\{context.burnRateThreshold\\}\\}\n\n[查看告警详情](\\{\\{context.alertDetailsUrl\\}\\})\n",
"xpack.slo.rules.burnRate.defaultRecoveryMessage": "\\{\\{context.reason\\}\\}\n\n\\{\\{rule.name\\}\\} 已恢复。\n\n- SLO\\{\\{context.sloName\\}\\}'\n- 过去 \\{\\{context.longWindow.duration\\}\\} 的消耗速度为 \\{\\{context.longWindow.burnRate\\}\\}\n- 过去 \\{\\{context.shortWindow.duration\\}\\} 的消耗速度为 \\{\\{context.shortWindow.burnRate\\}\\}\n- Threshold: \\{\\{context.burnRateThreshold\\}\\}\n\n[查看告警详情](\\{\\{context.alertDetailsUrl\\}\\})\n",
"xpack.slo.rules.burnRate.description": "在定义的期间内 SLO 消耗速度过高时告警。",
"xpack.slo.rules.burnRate.errors.burnRateThresholdRequired": "“消耗速度阈值”必填。",
"xpack.slo.rules.burnRate.errors.sloRequired": "“SLO”必填。",
"xpack.slo.rules.burnRate.errors.windowDurationRequired": "“回顾期”必填。",
"xpack.slo.rules.burnRate.name": "SLO 消耗速度",
"xpack.slo.rules.burnRate.rowLabel": "消耗速度阈值",
"xpack.slo.rules.burnRate.tooltip": "消耗速度是指服务在回顾期内耗用错误预算的速度。",
"xpack.slo.rules.deleteWindowLabel": "删除窗口",
"xpack.slo.rules.longWindow.errorText": "回顾期必须介于 1 到 72 小时之间。",
"xpack.slo.rules.longWindow.rowLabel": "回顾(小时)",
"xpack.slo.rules.longWindow.valueLabel": "回顾期(小时)",
"xpack.slo.rules.sloSelector.ariaLabel": "SLO",
"xpack.slo.rules.sloSelector.placeholder": "选择 SLO",
"xpack.slo.rules.sloSelector.rowLabel": "SLO",
"xpack.slo.slo.activeAlertsBadge.ariaLabel": "活动告警徽章",
"xpack.slo.slo.item.actions.clone": "克隆",
"xpack.slo.slo.item.actions.delete": "删除",
"xpack.slo.slo.rulesBadge.popover": "尚未为此 SLO 配置任何规则。超出 SLO 时,您不会收到告警。",
"xpack.slo.sloDetails.errorBudgetChartPanel.chartTitle": "剩余错误预算",
"xpack.slo.sloDetails.errorBudgetChartPanel.remaining": "剩余",
"xpack.slo.sloDetails.errorBudgetChartPanel.title": "错误预算逐渐减少",
"xpack.slo.sloDetails.headerControl.actions": "操作",
"xpack.slo.sloDetails.headerControl.createBurnRateRule": "创建新告警规则",
"xpack.slo.sloDetails.headerControl.edit": "编辑",
"xpack.slo.sloDetails.headerTitle.createdMessage": "创建日期",
"xpack.slo.sloDetails.headerTitle.lastUpdatedMessage": "上次更新时间",
"xpack.slo.sloDetails.overview.apmSource": "APM 源",
"xpack.slo.sloDetails.overview.budgetingMethodTitle": "预算编制方法",
"xpack.slo.sloDetails.overview.descriptionTitle": "描述",
"xpack.slo.sloDetails.overview.indicatorTypeTitle": "指标类型",
"xpack.slo.sloDetails.overview.observedValueTitle": "观察值",
"xpack.slo.sloDetails.overview.tagsTitle": "标签",
"xpack.slo.sloDetails.overview.timeWindowTitle": "时间窗口",
"xpack.slo.sloDetails.sliHistoryChartPanel.chartTitle": "SLI 值",
"xpack.slo.sloDetails.sliHistoryChartPanel.current": "观察值",
"xpack.slo.sloDetails.sliHistoryChartPanel.objective": "目标",
"xpack.slo.sloDetails.sliHistoryChartPanel.title": "历史 SLI",
"xpack.slo.sloDetails.tab.alertsLabel": "告警",
"xpack.slo.sloDetails.tab.overviewLabel": "概览",
"xpack.slo.sloEdit.apm.filter.tooltip": "此 KQL 查询用于根据该 SLO 的某些相关条件筛选 APM 指标。",
"xpack.slo.sloEdit.apm.serviceName.tooltip": "这是受该 SLO 监测的 APM 服务。",
"xpack.slo.sloEdit.apmAvailability.serviceEnvironment": "服务环境",
"xpack.slo.sloEdit.apmAvailability.serviceEnvironment.placeholder": "选择环境",
"xpack.slo.sloEdit.apmAvailability.serviceName": "服务名称",
"xpack.slo.sloEdit.apmAvailability.serviceName.placeholder": "选择 APM 服务",
"xpack.slo.sloEdit.apmAvailability.transactionName": "事务名称",
"xpack.slo.sloEdit.apmAvailability.transactionName.placeholder": "选择事务名称",
"xpack.slo.sloEdit.apmAvailability.transactionType": "事务类型",
"xpack.slo.sloEdit.apmAvailability.transactionType.placeholder": "选择事务类型",
"xpack.slo.sloEdit.apmLatency.filter": "查询筛选",
"xpack.slo.sloEdit.apmLatency.filter.placeholder": "要对索引应用的定制筛选",
"xpack.slo.sloEdit.apmLatency.serviceEnvironment": "服务环境",
"xpack.slo.sloEdit.apmLatency.serviceEnvironment.placeholder": "选择环境",
"xpack.slo.sloEdit.apmLatency.serviceName": "服务名称",
"xpack.slo.sloEdit.apmLatency.serviceName.placeholder": "选择 APM 服务",
"xpack.slo.sloEdit.apmLatency.threshold.placeholder": "阈值 (ms)",
"xpack.slo.sloEdit.apmLatency.threshold.tooltip": "配置为 SLO 定义“良好”或“成功”请求的阈值(毫秒)。",
"xpack.slo.sloEdit.apmLatency.transactionName": "事务名称",
"xpack.slo.sloEdit.apmLatency.transactionName.placeholder": "选择事务名称",
"xpack.slo.sloEdit.apmLatency.transactionType": "事务类型",
"xpack.slo.sloEdit.apmLatency.transactionType.placeholder": "选择事务类型",
"xpack.slo.sloEdit.budgetingMethod.label": "预算编制方法",
"xpack.slo.sloEdit.budgetingMethod.tooltip": "基于发生次数的 SLO 使用时间窗口内良好事件数与事件总数的比率。基于时间片的 SLO 使用时间窗口内良好时间片与时间片总数的比率。",
"xpack.slo.sloEdit.calendarTimeWindow.monthly": "每月",
"xpack.slo.sloEdit.calendarTimeWindow.weekly": "每周",
"xpack.slo.sloEdit.cancelButton": "取消",
"xpack.slo.sloEdit.createSloButton": "创建 SLO",
"xpack.slo.sloEdit.customKql.indexSelection.label": "索引",
"xpack.slo.sloEdit.dataPreviewChart.errorMessage": "当前指标设置无效",
"xpack.slo.sloEdit.dataPreviewChart.explanationMessage": "填写指标字段以查看当前指标的可视化",
"xpack.slo.sloEdit.dataPreviewChart.panelLabel": "SLI 预览",
"xpack.slo.sloEdit.dataPreviewChart.xTitle": "过去一小时",
"xpack.slo.sloEdit.dataPreviewChart.yTitle": "SLI",
"xpack.slo.sloEdit.definition.sliType": "选择 SLI 类型",
"xpack.slo.sloEdit.definition.title": "定义 SLI",
"xpack.slo.sloEdit.description.sloDescription": "描述",
"xpack.slo.sloEdit.description.sloDescriptionPlaceholder": "SLO 的简短描述",
"xpack.slo.sloEdit.description.sloName": "SLO 名称",
"xpack.slo.sloEdit.description.sloNamePlaceholder": "SLO 的名称",
"xpack.slo.sloEdit.description.title": "描述 SLO",
"xpack.slo.sloEdit.editSloButton": "更新 SLO",
"xpack.slo.sloEdit.fieldSelector.all": "全部",
"xpack.slo.sloEdit.groupBy.label": "分区依据",
"xpack.slo.sloEdit.groupBy.placeholder": "选择要依据其分区的可选字段",
"xpack.slo.sloEdit.groupBy.tooltip": "为选定字段中的每个值创建单个 SLO。",
"xpack.slo.sloEdit.objectives.title": "设定目标",
"xpack.slo.sloEdit.sliType.customKql.customFilter": "要对索引应用的定制筛选",
"xpack.slo.sloEdit.sliType.customKql.customFilter.tooltip": "此 KQL 查询可用于基于某些相关条件来筛选文档。",
"xpack.slo.sloEdit.sliType.customKql.goodQuery": "良好查询",
"xpack.slo.sloEdit.sliType.customKql.goodQuery.tooltip": "此 KQL 查询应返回用于计算 SLO 时被视为“良好”或“成功”的事件的子集。此查询应基于某些相关条件(如状态代码、错误消息或其他相关字段)筛选事件。",
"xpack.slo.sloEdit.sliType.customKql.goodQueryPlaceholder": "定义良好事件",
"xpack.slo.sloEdit.sliType.customKql.queryFilter": "查询筛选",
"xpack.slo.sloEdit.sliType.customKql.totalQuery": "查询总数",
"xpack.slo.sloEdit.sliType.customKql.totalQuery.tooltip": "此 KQL 查询应返回与 SLO 计算相关的所有事件,包括良好和不良事件。",
"xpack.slo.sloEdit.sliType.customKql.totalQueryPlaceholder": "定义事件总数",
"xpack.slo.sloEdit.sliType.customMetric.addMetricAriaLabel": "添加指标",
"xpack.slo.sloEdit.sliType.customMetric.addMetricLabel": "添加指标",
"xpack.slo.sloEdit.sliType.customMetric.customFilter": "要对索引应用的定制筛选",
"xpack.slo.sloEdit.sliType.customMetric.customFilter.tooltip": "此 KQL 查询可用于基于某些相关条件来筛选文档。",
"xpack.slo.sloEdit.sliType.customMetric.deleteLabel": "删除指标",
"xpack.slo.sloEdit.sliType.customMetric.equation.invalidCharacters": "方程字段仅支持以下字符A-Z、+、-、/、*、(、)、?、!、&、:、|、>、<、=",
"xpack.slo.sloEdit.sliType.customMetric.equationHelpText": "支持基本数学方程有效字符包括A-Z、+、-、/、*、(、)、?、!、&、:、|、>、<、=",
"xpack.slo.sloEdit.sliType.customMetric.equationLabel": "方程",
"xpack.slo.sloEdit.sliType.customMetric.filterLabel": "筛选",
"xpack.slo.sloEdit.sliType.customMetric.goodTitle": "良好事件",
"xpack.slo.sloEdit.sliType.customMetric.metricField.placeholder": "选择指标字段",
"xpack.slo.sloEdit.sliType.customMetric.metricLabel": "指标",
"xpack.slo.sloEdit.sliType.customMetric.queryFilter": "查询筛选",
"xpack.slo.sloEdit.sliType.customMetric.totalEquation.tooltip": "这支持基本数学 (A + B / C) 和布尔逻辑 (A < B ?A :B)。",
"xpack.slo.sloEdit.sliType.customMetric.totalMetric.tooltip": "来自该字段的此类数据将使用“求和”聚合进行汇总。",
"xpack.slo.sloEdit.sliType.customMetric.totalTitle": "事件合计",
"xpack.slo.sloEdit.sliType.histogram.aggregation.placeholder": "选择聚合",
"xpack.slo.sloEdit.sliType.histogram.aggregationLabel": "聚合",
"xpack.slo.sloEdit.sliType.histogram.aggregationTooltip": "“值计数”聚合将返回直方图字段的总计数。范围将返回在下面定义的范围内的直方图字段中的计数。",
"xpack.slo.sloEdit.sliType.histogram.customFilter": "要对索引应用的定制筛选",
"xpack.slo.sloEdit.sliType.histogram.customFilter.tooltip": "此 KQL 查询可用于基于某些相关条件来筛选文档。",
"xpack.slo.sloEdit.sliType.histogram.fromLabel": "自",
"xpack.slo.sloEdit.sliType.histogram.fromTooltip": "“from”值具有包容性。",
"xpack.slo.sloEdit.sliType.histogram.goodTitle": "良好事件",
"xpack.slo.sloEdit.sliType.histogram.kqlFilterLabel": "KQL 筛选",
"xpack.slo.sloEdit.sliType.histogram.metricField.placeholder": "选择直方图字段",
"xpack.slo.sloEdit.sliType.histogram.metricLabel": "字段",
"xpack.slo.sloEdit.sliType.histogram.query.tooltip": "此 KQL 查询应返回该指标的事件的子集。",
"xpack.slo.sloEdit.sliType.histogram.queryFilter": "查询筛选",
"xpack.slo.sloEdit.sliType.histogram.rangeLabel": "范围",
"xpack.slo.sloEdit.sliType.histogram.sourceTitle": "源",
"xpack.slo.sloEdit.sliType.histogram.toLabel": "至",
"xpack.slo.sloEdit.sliType.histogram.totalTitle": "事件合计",
"xpack.slo.sloEdit.sliType.histogram.toTooltip": "“to”值不具有包容性。",
"xpack.slo.sloEdit.sliType.histogram.valueCountLabel": "值计数",
"xpack.slo.sloEdit.tags.label": "标签",
"xpack.slo.sloEdit.tags.placeholder": "添加标签",
"xpack.slo.sloEdit.targetSlo.label": "目标/SLO (%)",
"xpack.slo.sloEdit.targetSlo.tooltip": "SLO 的目标值 (%)。",
"xpack.slo.sloEdit.timeSliceTarget.label": "时间片目标 (%)",
"xpack.slo.sloEdit.timeSliceTarget.tooltip": "用于确定切片是良好还是不良的单个时间片目标。",
"xpack.slo.sloEdit.timesliceWindow.label": "时间片窗口(分钟)",
"xpack.slo.sloEdit.timesliceWindow.tooltip": "用于评估接收的数据的时间片窗口大小。",
"xpack.slo.sloEdit.timestampField.label": "时间戳字段",
"xpack.slo.sloEdit.timestampField.placeholder": "选择时间戳字段",
"xpack.slo.sloEdit.timeWindow.calendarAligned": "日历已对齐",
"xpack.slo.sloEdit.timeWindow.rolling": "滚动",
"xpack.slo.sloEdit.timeWindowDuration.label": "持续时间",
"xpack.slo.sloEdit.timeWindowDuration.tooltip": "用于在其间计算 SLO 的时间窗口持续时间。",
"xpack.slo.sloEdit.timeWindowType.label": "时间窗口",
"xpack.slo.sloEdit.timeWindowType.tooltip": "选择滚动或日历对齐窗口。",
"xpack.slo.sloList.welcomePrompt.buttonLabel": "创建 SLO",
"xpack.slo.sloList.welcomePrompt.getStartedMessage": "要开始使用,请创建您的首个 SLO。",
"xpack.slo.sloList.welcomePrompt.learnMore": "希望了解详情?",
"xpack.slo.sloList.welcomePrompt.learnMoreLink": "阅读文档",
"xpack.slo.sloList.welcomePrompt.messageParagraph1": "衡量对业务十分重要的关键指标,如服务级别指标和服务级别目标 (SLI/SLO),努力实现 SLA。",
"xpack.slo.sloList.welcomePrompt.messageParagraph2": "通过实时洞察,轻松向利益相关者报告服务的运行时间和可靠性。",
"xpack.slo.sloList.welcomePrompt.needLicenseMessage": "您需要 Elastic Cloud 订阅或白金级许可证才能使用 SLO。",
"xpack.slo.sloList.welcomePrompt.signupForCloud": "注册 Elastic Cloud",
"xpack.slo.sloList.welcomePrompt.signupForLicense": "注册许可证",
"xpack.slo.sloList.welcomePrompt.title": "跟踪和实现 SLO",
"xpack.slo.sloStatusBadge.degrading": "正在降级",
"xpack.slo.sloStatusBadge.forecasted": "已预测",
"xpack.slo.sloStatusBadge.healthy": "运行正常",
"xpack.slo.sloStatusBadge.noData": "无数据",
"xpack.slo.sloStatusBadge.noDataTooltip": "在聚合数据并且数据可用之前,可能需要花费一些时间。",
"xpack.slo.sloStatusBadge.violated": "已违规",
"xpack.observabilityAiAssistant.chatCollapsedItems.hideEvents": "隐藏 {count} 个事件",
"xpack.observabilityAiAssistant.chatCollapsedItems.showEvents": "显示 {count} 个事件",
"xpack.observabilityAiAssistant.chatCompletionError.tokenLimitReachedError": "达到了词元限制。词元限制为 {tokenLimit},但当前对话具有 {tokenCount} 个词元。",

View file

@ -23,9 +23,15 @@ interface WindowSchema {
actionGroup: string;
}
interface Dependency {
ruleId: string;
actionGroupsToSuppressOn: string[];
}
export interface SloBurnRateRuleParams {
sloId: string;
windows: WindowSchema[];
dependencies?: Dependency[];
}
interface SloParams {

View file

@ -27,6 +27,8 @@ export default function ({ getService }: FtrProviderContext) {
describe('Burn rate rule', () => {
const RULE_TYPE_ID = 'slo.rules.burnRate';
const DATA_VIEW = 'kbn-data-forge-fake_hosts.fake_hosts-*';
const RULE_ALERT_INDEX = '.alerts-observability.slo.alerts-default';
const ALERT_ACTION_INDEX = 'alert-action-slo';
const DATA_VIEW_ID = 'data-view-id';
let dataForgeConfig: PartialConfig;
@ -85,8 +87,7 @@ export default function ({ getService }: FtrProviderContext) {
await cleanup({ client: esClient, config: dataForgeConfig, logger });
});
// FLAKY: https://github.com/elastic/kibana/issues/173653
describe.skip('Rule creation', () => {
describe('Rule creation', () => {
it('creates rule successfully', async () => {
actionId = await alertingApi.createIndexConnector({
name: 'Index Connector: Slo Burn rate API test',
@ -117,10 +118,10 @@ export default function ({ getService }: FtrProviderContext) {
groupBy: '*',
});
const createdRule = await alertingApi.createRule({
const dependencyRule = await alertingApi.createRule({
tags: ['observability'],
consumer: 'observability',
name: 'SLO Burn Rate rule',
name: 'SLO Burn Rate rule - Dependency',
ruleTypeId: RULE_TYPE_ID,
schedule: {
interval: '1m',
@ -131,7 +132,7 @@ export default function ({ getService }: FtrProviderContext) {
{
id: '1',
actionGroup: 'slo.burnRate.alert',
burnRateThreshold: 14.4,
burnRateThreshold: 3.36,
maxBurnRateThreshold: 720,
longWindow: {
value: 1,
@ -145,7 +146,7 @@ export default function ({ getService }: FtrProviderContext) {
{
id: '2',
actionGroup: 'slo.burnRate.high',
burnRateThreshold: 6,
burnRateThreshold: 1.4,
maxBurnRateThreshold: 120,
longWindow: {
value: 6,
@ -159,7 +160,7 @@ export default function ({ getService }: FtrProviderContext) {
{
id: '3',
actionGroup: 'slo.burnRate.medium',
burnRateThreshold: 3,
burnRateThreshold: 0.7,
maxBurnRateThreshold: 30,
longWindow: {
value: 24,
@ -173,7 +174,85 @@ export default function ({ getService }: FtrProviderContext) {
{
id: '4',
actionGroup: 'slo.burnRate.low',
burnRateThreshold: 1,
burnRateThreshold: 0.234,
maxBurnRateThreshold: 10,
longWindow: {
value: 72,
unit: 'h',
},
shortWindow: {
value: 360,
unit: 'm',
},
},
],
},
actions: [],
});
const createdRule = await alertingApi.createRule({
tags: ['observability'],
consumer: 'observability',
name: 'SLO Burn Rate rule',
ruleTypeId: RULE_TYPE_ID,
schedule: {
interval: '1m',
},
params: {
sloId: 'my-custom-id',
dependencies: [
{
ruleId: dependencyRule.id,
actionGroupsToSuppressOn: ['slo.burnRate.alert', 'slo.burnRate.high'],
},
],
windows: [
{
id: '1',
actionGroup: 'slo.burnRate.alert',
burnRateThreshold: 3.36,
maxBurnRateThreshold: 720,
longWindow: {
value: 1,
unit: 'h',
},
shortWindow: {
value: 5,
unit: 'm',
},
},
{
id: '2',
actionGroup: 'slo.burnRate.high',
burnRateThreshold: 1.4,
maxBurnRateThreshold: 120,
longWindow: {
value: 6,
unit: 'h',
},
shortWindow: {
value: 30,
unit: 'm',
},
},
{
id: '3',
actionGroup: 'slo.burnRate.medium',
burnRateThreshold: 0.7,
maxBurnRateThreshold: 30,
longWindow: {
value: 24,
unit: 'h',
},
shortWindow: {
value: 120,
unit: 'm',
},
},
{
id: '4',
actionGroup: 'slo.burnRate.low',
burnRateThreshold: 0.234,
maxBurnRateThreshold: 10,
longWindow: {
value: 72,
@ -200,6 +279,18 @@ export default function ({ getService }: FtrProviderContext) {
expect(executionStatus).to.be('active');
});
it('should set correct information in the alert document', async () => {
const resp = await alertingApi.waitForAlertInIndex({
indexName: RULE_ALERT_INDEX,
ruleId,
});
expect(resp.hits.hits[0]._source).property('kibana.alert.rule.category', 'SLO burn rate');
expect(resp.hits.hits[0]._source).property(
'kibana.alert.reason',
'SUPPRESSED - CRITICAL: The burn rate for the past 1h is 1000 and for the past 5m is 1000. Alert when above 3.36 for both windows'
);
});
it('should find the created rule with correct information about the consumer', async () => {
const match = await alertingApi.findRule(ruleId);
expect(match).not.to.be(undefined);