diff --git a/opencti-platform/opencti-front/lang/front/de.json b/opencti-platform/opencti-front/lang/front/de.json
index 6456ef123f42..8ed621c796c1 100644
--- a/opencti-platform/opencti-front/lang/front/de.json
+++ b/opencti-platform/opencti-front/lang/front/de.json
@@ -695,6 +695,7 @@
"Close disconnection process?": "Verbindungsabbruch?",
"Close registration process?": "Den Registrierungsprozess abschließen?",
"Close unregistration process?": "Den Abmeldevorgang abschließen?",
+ "Closed": "Geschlossen",
"Cloud": "Wolke",
"Cloud Control Plane": "Cloud Control Plane",
"club": "Informelle Gruppe",
@@ -1618,7 +1619,9 @@
"Do you want to unlink this task ?": "Möchten Sie die Verknüpfung dieser Aufgabe aufheben?",
"Do you want to unlink this task template ?": "Möchten Sie die Verknüpfung dieser Aufgabenvorlage aufheben?",
"Do you want to unlink this task?": "Möchten Sie die Verknüpfung dieser Aufgabe aufheben?",
+ "Document count": "Anzahl der Dokumente",
"documentation": "dokumentation",
+ "Documents": "Dokumente",
"does not exist in the main knowledge base": "nicht in der Hauptwissensbasis vorhanden ist",
"Domain": "Bereich",
"Domain names": "Domänennamen",
@@ -2575,6 +2578,11 @@
"Incorporating your message…": "Einbindung Ihrer Nachricht…",
"Increasing": "Steigend",
"independent": "unabhängig",
+ "Index health": "Indexgesundheit",
+ "Index metrics": "Indexmetriken",
+ "Index name": "Index Name",
+ "Index size": "Indexgröße",
+ "Index status": "Index-Status",
"Indexed files": "Indizierte Dateien",
"Indexing": "Indizierung",
"Indexing manager start": "Indizierungsmanager Start",
diff --git a/opencti-platform/opencti-front/lang/front/en.json b/opencti-platform/opencti-front/lang/front/en.json
index 82ee7bfaa1b9..541fda580148 100644
--- a/opencti-platform/opencti-front/lang/front/en.json
+++ b/opencti-platform/opencti-front/lang/front/en.json
@@ -695,6 +695,7 @@
"Close disconnection process?": "Close disconnection process?",
"Close registration process?": "Close registration process?",
"Close unregistration process?": "Close unregistration process?",
+ "Closed": "Closed",
"Cloud": "Cloud",
"Cloud Control Plane": "Cloud Control Plane",
"club": "Informal group",
@@ -1618,7 +1619,9 @@
"Do you want to unlink this task ?": "Do you want to unlink this task ?",
"Do you want to unlink this task template ?": "Do you want to unlink this task template ?",
"Do you want to unlink this task?": "Do you want to unlink this task?",
+ "Document count": "Document count",
"documentation": "documentation",
+ "Documents": "Documents",
"does not exist in the main knowledge base": "does not exist in the main knowledge base",
"Domain": "Domain",
"Domain names": "Domain names",
@@ -2575,6 +2578,11 @@
"Incorporating your message…": "Incorporating your message…",
"Increasing": "Increasing",
"independent": "independent",
+ "Index health": "Index health",
+ "Index metrics": "Index metrics",
+ "Index name": "Index name",
+ "Index size": "Index size",
+ "Index status": "Index status",
"Indexed files": "Indexed files",
"Indexing": "Indexing",
"Indexing manager start": "Indexing manager start",
diff --git a/opencti-platform/opencti-front/lang/front/es.json b/opencti-platform/opencti-front/lang/front/es.json
index fdc3db47522a..371f7151132d 100644
--- a/opencti-platform/opencti-front/lang/front/es.json
+++ b/opencti-platform/opencti-front/lang/front/es.json
@@ -695,6 +695,7 @@
"Close disconnection process?": "¿Cerrar el proceso de desconexión?",
"Close registration process?": "Cerrar el proceso de registro",
"Close unregistration process?": "¿Cerrar el proceso de desregistro?",
+ "Closed": "Cerrado",
"Cloud": "Nube",
"Cloud Control Plane": "Plano de control de nube",
"club": "Grupo informal",
@@ -1618,7 +1619,9 @@
"Do you want to unlink this task ?": "¿Desea desvincular esta tarea?",
"Do you want to unlink this task template ?": "¿Desea desvincular esta plantilla de tarea?",
"Do you want to unlink this task?": "¿Quieres desvincular esta tarea?",
+ "Document count": "Recuento de documentos",
"documentation": "documentación",
+ "Documents": "Documentos",
"does not exist in the main knowledge base": "no existe en la base de conocimiento principal",
"Domain": "Nombre de dominio",
"Domain names": "Nombres de dominio",
@@ -2575,6 +2578,11 @@
"Incorporating your message…": "Incorporando tu mensaje…",
"Increasing": "Aumentando",
"independent": "Independiente",
+ "Index health": "Índice de salud",
+ "Index metrics": "Métricas del índice",
+ "Index name": "Índice nombre",
+ "Index size": "Tamaño del índice",
+ "Index status": "Estado del índice",
"Indexed files": "Ficheros indexados",
"Indexing": "Indexación",
"Indexing manager start": "Inicio del gestor de indexación",
diff --git a/opencti-platform/opencti-front/lang/front/fr.json b/opencti-platform/opencti-front/lang/front/fr.json
index 9922f5673617..b0084b7f7205 100644
--- a/opencti-platform/opencti-front/lang/front/fr.json
+++ b/opencti-platform/opencti-front/lang/front/fr.json
@@ -695,6 +695,7 @@
"Close disconnection process?": "Fermer le processus de déconnexion ?",
"Close registration process?": "Fermer le processus d'enregistrement ?",
"Close unregistration process?": "Fermer le processus de désenregistrement ?",
+ "Closed": "Fermés",
"Cloud": "Nuage",
"Cloud Control Plane": "Plan de contrôle Cloud",
"club": "Groupe informel",
@@ -1618,7 +1619,9 @@
"Do you want to unlink this task ?": "Voulez-vous dissocier cette tâche ?",
"Do you want to unlink this task template ?": "Voulez-vous dissocier ce modèle de tâche ?",
"Do you want to unlink this task?": "Voulez-vous dissocier cette tâche ?",
+ "Document count": "Nombre de documents",
"documentation": "documentation",
+ "Documents": "Documents",
"does not exist in the main knowledge base": "n'existe pas dans la base de connaissances principale",
"Domain": "Nom de domaine",
"Domain names": "Noms de domaine",
@@ -2575,6 +2578,11 @@
"Incorporating your message…": "Intégration de votre message…",
"Increasing": "En hausse",
"independent": "indépendant",
+ "Index health": "Indice santé",
+ "Index metrics": "Indicateurs de l'indice",
+ "Index name": "Nom de l’index",
+ "Index size": "Taille de l’index",
+ "Index status": "Index Status",
"Indexed files": "Fichiers indexés",
"Indexing": "Indexation",
"Indexing manager start": "Démarrage du moteur d'indexation",
diff --git a/opencti-platform/opencti-front/lang/front/it.json b/opencti-platform/opencti-front/lang/front/it.json
index fbb4c8409053..8c511e6a7b66 100644
--- a/opencti-platform/opencti-front/lang/front/it.json
+++ b/opencti-platform/opencti-front/lang/front/it.json
@@ -695,6 +695,7 @@
"Close disconnection process?": "Chiudere la procedura di disconnessione?",
"Close registration process?": "Chiudere il processo di registrazione?",
"Close unregistration process?": "Chiudere il processo di disregistrazione?",
+ "Closed": "Chiuso",
"Cloud": "Nuvola",
"Cloud Control Plane": "Piano di controllo cloud",
"club": "Club",
@@ -1618,7 +1619,9 @@
"Do you want to unlink this task ?": "Vuoi scollegare questo task ?",
"Do you want to unlink this task template ?": "Vuoi scollegare questo template di task ?",
"Do you want to unlink this task?": "Vuoi scollegare questo task?",
+ "Document count": "Conteggio documenti",
"documentation": "documentazione",
+ "Documents": "Documenti",
"does not exist in the main knowledge base": "non esiste nella base di conoscenza principale",
"Domain": "Dominio",
"Domain names": "Nomi di dominio",
@@ -2575,6 +2578,11 @@
"Incorporating your message…": "Inserimento del messaggio…",
"Increasing": "Crescente",
"independent": "indipendente",
+ "Index health": "Indice salute",
+ "Index metrics": "Indice metriche",
+ "Index name": "Nome indice",
+ "Index size": "Dimensioni dell'indice",
+ "Index status": "Stato indice",
"Indexed files": "File indicizzati",
"Indexing": "Indicizzazione",
"Indexing manager start": "Avvio del gestore dell'indicizzazione",
diff --git a/opencti-platform/opencti-front/lang/front/ja.json b/opencti-platform/opencti-front/lang/front/ja.json
index 3c24758d64b8..f09308c93227 100644
--- a/opencti-platform/opencti-front/lang/front/ja.json
+++ b/opencti-platform/opencti-front/lang/front/ja.json
@@ -695,6 +695,7 @@
"Close disconnection process?": "切断プロセスを終了しますか?",
"Close registration process?": "登録プロセスを終了しますか?",
"Close unregistration process?": "登録を解除しますか?",
+ "Closed": "閉じた",
"Cloud": "クラウド",
"Cloud Control Plane": "クラウドコントロールプレーン",
"club": "インフォーマルグループ",
@@ -1618,7 +1619,9 @@
"Do you want to unlink this task ?": "このタスクのリンクを解除しますか?",
"Do you want to unlink this task template ?": "このタスクテンプレートのリンクを解除しますか?",
"Do you want to unlink this task?": "このタスクのリンクを解除しますか?",
+ "Document count": "文書リストカウント",
"documentation": "ドキュメンテーション",
+ "Documents": "ドキュメント",
"does not exist in the main knowledge base": "メイン知識ベースに存在しない",
"Domain": "ドメイン",
"Domain names": "ドメイン名",
@@ -2575,6 +2578,11 @@
"Incorporating your message…": "メッセージを組み込んでいます…",
"Increasing": "増加",
"independent": "無所属",
+ "Index health": "インデックスの健全性",
+ "Index metrics": "インデックスメトリクス",
+ "Index name": "インデックス名",
+ "Index size": "インデックスサイズ",
+ "Index status": "インデックスの状態",
"Indexed files": "索引的文件",
"Indexing": "インデックス作成",
"Indexing manager start": "インデックスマネージャ開始",
diff --git a/opencti-platform/opencti-front/lang/front/ko.json b/opencti-platform/opencti-front/lang/front/ko.json
index 56186620ae2d..5e982f85c492 100644
--- a/opencti-platform/opencti-front/lang/front/ko.json
+++ b/opencti-platform/opencti-front/lang/front/ko.json
@@ -695,6 +695,7 @@
"Close disconnection process?": "연결 해제 과정을 종료하시겠습니까?",
"Close registration process?": "등록 절차를 닫으시겠습니까?",
"Close unregistration process?": "등록 취소 프로세스를 닫으시겠습니까?",
+ "Closed": "닫힘",
"Cloud": "클라우드",
"Cloud Control Plane": "클라우드 제어 평면",
"club": "비공식 그룹",
@@ -1618,7 +1619,9 @@
"Do you want to unlink this task ?": "이 작업의 연결을 해제하시겠습니까?",
"Do you want to unlink this task template ?": "이 작업 템플릿의 연결을 해제하시겠습니까?",
"Do you want to unlink this task?": "이 작업의 연결을 해제하시겠습니까?",
+ "Document count": "문서 수",
"documentation": "문서",
+ "Documents": "문서",
"does not exist in the main knowledge base": "기본 지식창고에 존재하지 않음",
"Domain": "도메인",
"Domain names": "도메인 이름",
@@ -2575,6 +2578,11 @@
"Incorporating your message…": "메시지를 반영 중…",
"Increasing": "증가",
"independent": "독립적",
+ "Index health": "색인 상태",
+ "Index metrics": "색인 메트릭",
+ "Index name": "색인 이름",
+ "Index size": "인덱스 크기",
+ "Index status": "인덱스 상태",
"Indexed files": "인덱싱된 파일",
"Indexing": "인덱싱",
"Indexing manager start": "인덱싱 관리자 시작",
diff --git a/opencti-platform/opencti-front/lang/front/ru.json b/opencti-platform/opencti-front/lang/front/ru.json
index 79b98d6c202c..46b2b432bda4 100644
--- a/opencti-platform/opencti-front/lang/front/ru.json
+++ b/opencti-platform/opencti-front/lang/front/ru.json
@@ -695,6 +695,7 @@
"Close disconnection process?": "Закрыть процесс отключения?",
"Close registration process?": "Закрыть процесс регистрации?",
"Close unregistration process?": "Закрыть процесс снятия с регистрации?",
+ "Closed": "Закрыт",
"Cloud": "Облако",
"Cloud Control Plane": "Плоскость управления облаками",
"club": "клуб",
@@ -1618,7 +1619,9 @@
"Do you want to unlink this task ?": "Вы хотите отвязать эту задачу?",
"Do you want to unlink this task template ?": "Вы хотите отвязать этот шаблон задачи?",
"Do you want to unlink this task?": "Вы хотите отвязать эту задачу?",
+ "Document count": "Подсчет количества документов",
"documentation": "документация",
+ "Documents": "документации",
"does not exist in the main knowledge base": "не существует в основной базе знаний",
"Domain": "Домен",
"Domain names": "Доменные имена",
@@ -2575,6 +2578,11 @@
"Incorporating your message…": "Включение вашего сообщения…",
"Increasing": "Увеличение",
"independent": "независимый",
+ "Index health": "Индекс работоспособности",
+ "Index metrics": "Метрики индекса",
+ "Index name": "Имя индекса",
+ "Index size": "Размер индекса",
+ "Index status": "Статус индекса",
"Indexed files": "Индексированные файлы",
"Indexing": "Индексирование",
"Indexing manager start": "Запуск менеджера индексирования",
diff --git a/opencti-platform/opencti-front/lang/front/zh.json b/opencti-platform/opencti-front/lang/front/zh.json
index f92dff994ee7..7e4e02e32972 100644
--- a/opencti-platform/opencti-front/lang/front/zh.json
+++ b/opencti-platform/opencti-front/lang/front/zh.json
@@ -695,6 +695,7 @@
"Close disconnection process?": "关闭断开连接过程?",
"Close registration process?": "关闭注册程序?",
"Close unregistration process?": "关闭取消注册程序?",
+ "Closed": "闭门",
"Cloud": "云",
"Cloud Control Plane": "云控制平面",
"club": "俱乐部",
@@ -1618,7 +1619,9 @@
"Do you want to unlink this task ?": "您要取消链接此任务吗?",
"Do you want to unlink this task template ?": "要取消链接此任务模板吗?",
"Do you want to unlink this task?": "您想取消这项任务的链接吗?",
+ "Document count": "文档相对计数",
"documentation": "文档",
+ "Documents": "文档",
"does not exist in the main knowledge base": "在主知识库中不存在",
"Domain": "域",
"Domain names": "域名",
@@ -2575,6 +2578,11 @@
"Incorporating your message…": "正在整合您的消息……",
"Increasing": "增加",
"independent": "独立研究员",
+ "Index health": "索引健康状况",
+ "Index metrics": "索引指标",
+ "Index name": "索引名称",
+ "Index size": "索引大小",
+ "Index status": "索引状态",
"Indexed files": "索引文件",
"Indexing": "索引",
"Indexing manager start": "索引管理器启动",
diff --git a/opencti-platform/opencti-front/src/private/components/nav/useNavMenu.tsx b/opencti-platform/opencti-front/src/private/components/nav/useNavMenu.tsx
index 1efa8edd23a1..5aa3862dba2d 100644
--- a/opencti-platform/opencti-front/src/private/components/nav/useNavMenu.tsx
+++ b/opencti-platform/opencti-front/src/private/components/nav/useNavMenu.tsx
@@ -392,6 +392,7 @@ const useNavMenu = (): NavGroup[] => {
{ granted: isGrantedToTaxonomies, link: '/dashboard/settings/vocabularies', label: t_i18n('Taxonomies') },
{ granted: isGrantedToAudit, link: '/dashboard/settings/activity', label: t_i18n('Activity') },
{ granted: isGrantedToFileIndexing, link: '/dashboard/settings/file_indexing', label: t_i18n('File indexing') },
+ { granted: isGrantedToManage, link: '/dashboard/settings/indexmetrics', label: t_i18n('Index metrics') },
{ granted: isGrantedToExperience, link: '/dashboard/settings/experience', label: t_i18n('Filigran Experience') },
],
},
diff --git a/opencti-platform/opencti-front/src/private/components/settings/Root.tsx b/opencti-platform/opencti-front/src/private/components/settings/Root.tsx
index 8478a9cd8bbe..e7a38fabbf74 100644
--- a/opencti-platform/opencti-front/src/private/components/settings/Root.tsx
+++ b/opencti-platform/opencti-front/src/private/components/settings/Root.tsx
@@ -30,6 +30,7 @@ const RootAccesses = lazy(() => import('./accesses/Root'));
const RootActivity = lazy(() => import('./activity/Root'));
const RootCustomization = lazy(() => import('./customization/Root'));
const RootVocabularies = lazy(() => import('./vocabularies/Root'));
+const IndexMetrics = lazy(() => import('./index_metrics/IndexMetrics'));
const ExperienceUnauthorizedRedirect = ({ fallbackUrl }: { fallbackUrl: string }) => {
const location = useLocation();
@@ -123,6 +124,17 @@ const Root = () => {
)}
/>
+ }
+ >
+
+
+ )}
+ />
diff --git a/opencti-platform/opencti-front/src/private/components/settings/index_metrics/IndexMetrics.tsx b/opencti-platform/opencti-front/src/private/components/settings/index_metrics/IndexMetrics.tsx
new file mode 100644
index 000000000000..40f6d70b3aa4
--- /dev/null
+++ b/opencti-platform/opencti-front/src/private/components/settings/index_metrics/IndexMetrics.tsx
@@ -0,0 +1,37 @@
+import React, { Suspense } from 'react';
+import Breadcrumbs from '../../../../components/Breadcrumbs';
+import { useFormatter } from '../../../../components/i18n';
+import Loader, { LoaderVariant } from '../../../../components/Loader';
+import useConnectedDocumentModifier from '../../../../utils/hooks/useConnectedDocumentModifier';
+import IndexMetricsSummary from './IndexMetricsSummary';
+import IndexMetricsTable from './IndexMetricsTable';
+
+const IndexMetricsComponent = () => {
+ const { t_i18n } = useFormatter();
+
+ return (
+
+
+
+
+
+ );
+};
+
+const IndexMetrics = () => {
+ const { t_i18n } = useFormatter();
+ const { setTitle } = useConnectedDocumentModifier();
+ setTitle(t_i18n('Index metrics'));
+
+ return (
+ }>
+
+
+ );
+};
+
+export default IndexMetrics;
diff --git a/opencti-platform/opencti-front/src/private/components/settings/index_metrics/IndexMetricsSummary.tsx b/opencti-platform/opencti-front/src/private/components/settings/index_metrics/IndexMetricsSummary.tsx
new file mode 100644
index 000000000000..5be9d5425fbe
--- /dev/null
+++ b/opencti-platform/opencti-front/src/private/components/settings/index_metrics/IndexMetricsSummary.tsx
@@ -0,0 +1,67 @@
+import React from 'react';
+import useQueryLoading from '../../../../utils/hooks/useQueryLoading';
+import { graphql, PreloadedQuery, usePreloadedQuery } from 'react-relay';
+import { useFormatter } from '../../../../components/i18n';
+import Card from '@common/card/Card';
+import Loader, { LoaderVariant } from '../../../../components/Loader';
+import { IndexMetricsSummaryStatsQuery } from './__generated__/IndexMetricsSummaryStatsQuery.graphql';
+import { Box, Grid2 as Grid, Typography } from '@mui/material';
+
+interface IndexMetricsSummaryComponentProps {
+ queryRef: PreloadedQuery;
+};
+
+const indexMetricsSummaryStatsQuery = graphql`
+ query IndexMetricsSummaryStatsQuery {
+ elasticSearchMetrics {
+ docs {
+ count
+ total_size_in_bytes
+ }
+ }
+ }
+`;
+const IndexMetricsSummaryComponent = ({ queryRef }: IndexMetricsSummaryComponentProps) => {
+ const { t_i18n, b } = useFormatter();
+ const data = usePreloadedQuery(indexMetricsSummaryStatsQuery, queryRef);
+ const toNumber = (value: unknown): number | null => {
+ if (value == null) return null;
+ const parsed = Number(value);
+ return Number.isFinite(parsed) ? parsed : null;
+ };
+ const docsCount = toNumber(data.elasticSearchMetrics?.docs?.count);
+ const clusterSize = toNumber(data.elasticSearchMetrics?.docs?.total_size_in_bytes);
+
+ return (
+
+
+
+
+ {t_i18n('Documents')}:
+ {docsCount}
+
+
+ {t_i18n('Size')}:
+ {b(clusterSize)}
+
+
+
+
+
+ );
+};
+
+const IndexMetricsSummary = () => {
+ const queryRef = useQueryLoading(indexMetricsSummaryStatsQuery, {});
+ return (
+ <>
+ {queryRef && (
+ }>
+
+
+ )}
+ >
+ );
+};
+
+export default IndexMetricsSummary;
diff --git a/opencti-platform/opencti-front/src/private/components/settings/index_metrics/IndexMetricsTable.tsx b/opencti-platform/opencti-front/src/private/components/settings/index_metrics/IndexMetricsTable.tsx
new file mode 100644
index 000000000000..338555b97371
--- /dev/null
+++ b/opencti-platform/opencti-front/src/private/components/settings/index_metrics/IndexMetricsTable.tsx
@@ -0,0 +1,123 @@
+import React from 'react';
+import { graphql, useLazyLoadQuery } from 'react-relay';
+import { useFormatter } from '../../../../components/i18n';
+import Loader, { LoaderVariant } from '../../../../components/Loader';
+import { IndexMetricsTableQuery } from './__generated__/IndexMetricsTableQuery.graphql';
+import { Box, Typography } from '@mui/material';
+import { DataTableProps } from '../../../../components/dataGrid/dataTableTypes';
+import DataTableWithoutFragment from 'src/components/dataGrid/DataTableWithoutFragment';
+import ItemBoolean from '../../../../components/ItemBoolean';
+import { ErrorOutlined, WarningOutlined } from '@mui/icons-material';
+
+export const LOCAL_STORAGE_KEY_INDEX_METRICS = 'index-metrics';
+
+const indexMetricsTableQuery = graphql`
+ query IndexMetricsTableQuery {
+ dataIndexMetrics {
+ indexes{
+ name,
+ uuid,
+ health,
+ status,
+ primaries {
+ docs {
+ count
+ total_size_in_bytes
+ }
+ }
+ }
+ }
+ }
+`;
+const IndexMetricsTableComponent = () => {
+ const { t_i18n, b } = useFormatter();
+ const data = useLazyLoadQuery(indexMetricsTableQuery, {});
+ const indexes = data.dataIndexMetrics?.indexes ? data.dataIndexMetrics.indexes.filter((i) => !i?.name?.includes('.internal')) : [];
+
+ const healthIcon = (health: string | undefined) => {
+ if (health === 'red') {
+ return ;
+ }
+ if (health === 'yellow') {
+ return ;
+ }
+ };
+
+ const dataColumns: DataTableProps['dataColumns'] = {
+ name: {
+ label: t_i18n('Index name'),
+ isSortable: false,
+ percentWidth: 50,
+ },
+ health: {
+ label: t_i18n('Index health'),
+ isSortable: false,
+ percentWidth: 15,
+ render: ({ health }: { health?: string }) => (
+
+ {
+ healthIcon(health)
+ }
+ {health}
+
+ ),
+ },
+ status: {
+ label: t_i18n('Index status'),
+ isSortable: false,
+ percentWidth: 10,
+ render: ({ status }: { status?: string }) => (
+
+ ),
+ },
+ documents: {
+ label: t_i18n('Document count'),
+ percentWidth: 15,
+ render: ({ documents }: { documents?: number }) => (
+ {documents}
+ ),
+ },
+ size: {
+ label: t_i18n('Index size'),
+ isSortable: false,
+ percentWidth: 10,
+ render: ({ size }: { size?: string }) => (
+ {size}
+ ),
+ },
+ };
+
+ return (
+ {
+ return {
+ name: i?.name,
+ health: i?.health,
+ status: i?.status,
+ documents: i?.primaries?.docs?.count,
+ size: b(i?.primaries?.docs?.total_size_in_bytes),
+ };
+ })}
+ storageKey={LOCAL_STORAGE_KEY_INDEX_METRICS}
+ globalCount={indexes.length}
+ disableToolBar
+ disableNavigation
+ disableLineSelection
+ isLocalStorageEnabled={false}
+ />
+ );
+};
+
+const IndexMetricsTable = () => {
+ return (
+ }>
+
+
+ );
+};
+
+export default IndexMetricsTable;
diff --git a/opencti-platform/opencti-front/src/schema/relay.schema.graphql b/opencti-platform/opencti-front/src/schema/relay.schema.graphql
index 3edda2c6b229..bbcdc5398be8 100644
--- a/opencti-platform/opencti-front/src/schema/relay.schema.graphql
+++ b/opencti-platform/opencti-front/src/schema/relay.schema.graphql
@@ -363,6 +363,7 @@ type GetMetrics {
type DocsMetrics {
count: String
+ total_size_in_bytes: Float
}
type ElasticSearchMetrics {
@@ -372,6 +373,23 @@ type ElasticSearchMetrics {
indexing: IndexingMetrics
}
+type DataIndexMetrics {
+ indexes: [DataIndex]
+}
+
+type DataIndex {
+ name: String
+ uuid: String
+ health: String
+ status: String
+ primaries: IndexStats
+ total: IndexStats
+}
+
+type IndexStats {
+ docs: DocsMetrics
+}
+
enum StatsOperation {
count
sum
@@ -9246,6 +9264,7 @@ type Query {
about: AppInfo
rabbitMQMetrics(prefix: String): RabbitMQMetrics
elasticSearchMetrics: ElasticSearchMetrics
+ dataIndexMetrics: DataIndexMetrics
logs(first: Int, after: ID, orderBy: LogsOrdering, orderMode: OrderingMode, filters: FilterGroup, search: String): LogConnection
log(id: ID!): Log
audits(first: Int, after: ID, types: [String!], orderBy: LogsOrdering, orderMode: OrderingMode, filters: FilterGroup, search: String): LogConnection
diff --git a/opencti-platform/opencti-graphql/config/schema/opencti.graphql b/opencti-platform/opencti-graphql/config/schema/opencti.graphql
index e0c94f1a27c0..67a6a3d72393 100644
--- a/opencti-platform/opencti-graphql/config/schema/opencti.graphql
+++ b/opencti-platform/opencti-graphql/config/schema/opencti.graphql
@@ -349,6 +349,7 @@ type GetMetrics {
}
type DocsMetrics {
count: String
+ total_size_in_bytes: Float
}
type ElasticSearchMetrics {
docs: DocsMetrics
@@ -356,6 +357,20 @@ type ElasticSearchMetrics {
get: GetMetrics
indexing: IndexingMetrics
}
+type DataIndexMetrics {
+ indexes:[DataIndex]
+}
+type DataIndex {
+ name: String
+ uuid: String
+ health: String
+ status: String
+ primaries: IndexStats,
+ total: IndexStats,
+}
+type IndexStats {
+ docs: DocsMetrics
+}
enum StatsOperation {
count
sum
@@ -14494,6 +14509,7 @@ type Query {
about: AppInfo @auth
rabbitMQMetrics(prefix: String): RabbitMQMetrics @auth(for: [MODULES])
elasticSearchMetrics: ElasticSearchMetrics @auth(for: [MODULES])
+ dataIndexMetrics: DataIndexMetrics @auth(for: [MODULES])
logs(
first: Int
after: ID
diff --git a/opencti-platform/opencti-graphql/src/database/engine.ts b/opencti-platform/opencti-graphql/src/database/engine.ts
index 2a6c968f18a3..c9facf036f7a 100644
--- a/opencti-platform/opencti-graphql/src/database/engine.ts
+++ b/opencti-platform/opencti-graphql/src/database/engine.ts
@@ -4968,6 +4968,33 @@ export const elUpdateElement = async (context: AuthContext, user: AuthUser, inst
return Promise.all([replacePromise, connectionPromise]);
};
+export const getIndexStats = () => {
+ const statsOperation = async () => {
+ const indexStats = [];
+ let engineIndicesStats;
+ if (engine instanceof ElkClient) {
+ engineIndicesStats = await engine.indices.stats();
+ } else {
+ engineIndicesStats = await engine.indices.stats();
+ }
+ const rawStats = oebp(engineIndicesStats).indices;
+ // convert object to array of index stats
+ for (const key of Object.keys(rawStats)) {
+ const index = rawStats[key];
+ indexStats.push(
+ { name: key,
+ uuid: index.uuid,
+ health: index.health,
+ status: index.status,
+ primaries: index.primaries,
+ total: index.total,
+ });
+ }
+ return { indexes: indexStats };
+ };
+ return retryElOperations(statsOperation);
+};
+
export const getStats = (indices = READ_PLATFORM_INDICES) => {
const statsOperation = async () => {
if (engine instanceof ElkClient) {
diff --git a/opencti-platform/opencti-graphql/src/domain/searchMetrics.js b/opencti-platform/opencti-graphql/src/domain/searchMetrics.js
index ff52113c1b0c..4837afb32984 100644
--- a/opencti-platform/opencti-graphql/src/domain/searchMetrics.js
+++ b/opencti-platform/opencti-graphql/src/domain/searchMetrics.js
@@ -1,6 +1,10 @@
-import { getStats } from '../database/engine';
+import { getStats, getIndexStats } from '../database/engine';
// eslint-disable-next-line
export const getMetrics = async () => {
return getStats();
};
+
+export const getIndexMetrics = async () => {
+ return getIndexStats();
+};
diff --git a/opencti-platform/opencti-graphql/src/generated/graphql.ts b/opencti-platform/opencti-graphql/src/generated/graphql.ts
index 8beaa3bc28ac..98cf1ff513b1 100644
--- a/opencti-platform/opencti-graphql/src/generated/graphql.ts
+++ b/opencti-platform/opencti-graphql/src/generated/graphql.ts
@@ -6908,6 +6908,21 @@ export enum DataComponentsOrdering {
XOpenctiWorkflowId = 'x_opencti_workflow_id'
}
+export type DataIndex = {
+ __typename?: 'DataIndex';
+ health?: Maybe;
+ name?: Maybe;
+ primaries?: Maybe;
+ status?: Maybe;
+ total?: Maybe;
+ uuid?: Maybe;
+};
+
+export type DataIndexMetrics = {
+ __typename?: 'DataIndexMetrics';
+ indexes?: Maybe>>;
+};
+
export type DataSanityDryRunOutput = {
__typename?: 'DataSanityDryRunOutput';
estimated_impact: Array;
@@ -7750,6 +7765,7 @@ export type Distribution = {
export type DocsMetrics = {
__typename?: 'DocsMetrics';
count?: Maybe;
+ total_size_in_bytes?: Maybe;
};
export type DomainName = BasicObject & StixCoreObject & StixCyberObservable & StixObject & {
@@ -12858,6 +12874,11 @@ export enum InconsistencyCleaningType {
RefDuplicateClean = 'REF_DUPLICATE_CLEAN'
}
+export type IndexStats = {
+ __typename?: 'IndexStats';
+ docs?: Maybe;
+};
+
export type IndexedFile = {
__typename?: 'IndexedFile';
entity?: Maybe;
@@ -24794,6 +24815,7 @@ export type Query = {
customViewsSettings: CustomViewsSettings;
dataComponent?: Maybe;
dataComponents?: Maybe;
+ dataIndexMetrics?: Maybe;
dataSanityExecutions: Array;
dataSanityOperationDryRun: DataSanityDryRunOutput;
dataSanityOperations: Array;
@@ -40728,6 +40750,8 @@ export type ResolversTypes = ResolversObject<{
DataComponentConnection: ResolverTypeWrapper & { edges?: Maybe>> }>;
DataComponentEdge: ResolverTypeWrapper & { node: ResolversTypes['DataComponent'] }>;
DataComponentsOrdering: DataComponentsOrdering;
+ DataIndex: ResolverTypeWrapper;
+ DataIndexMetrics: ResolverTypeWrapper;
DataSanityDryRunOutput: ResolverTypeWrapper;
DataSanityExecution: ResolverTypeWrapper;
DataSanityImpactedElement: ResolverTypeWrapper;
@@ -40946,6 +40970,7 @@ export type ResolversTypes = ResolversObject<{
IncidentEditMutations: ResolverTypeWrapper & { contextClean?: Maybe, contextPatch?: Maybe, fieldPatch?: Maybe, relationAdd?: Maybe, relationDelete?: Maybe }>;
IncidentsOrdering: IncidentsOrdering;
InconsistencyCleaningType: InconsistencyCleaningType;
+ IndexStats: ResolverTypeWrapper;
IndexedFile: ResolverTypeWrapper & { entity?: Maybe }>;
IndexedFileConnection: ResolverTypeWrapper & { edges?: Maybe>> }>;
IndexedFileEdge: ResolverTypeWrapper & { node: ResolversTypes['IndexedFile'] }>;
@@ -41883,6 +41908,8 @@ export type ResolversParentTypes = ResolversObject<{
DataComponentAddInput: DataComponentAddInput;
DataComponentConnection: Omit & { edges?: Maybe>> };
DataComponentEdge: Omit & { node: ResolversParentTypes['DataComponent'] };
+ DataIndex: DataIndex;
+ DataIndexMetrics: DataIndexMetrics;
DataSanityDryRunOutput: DataSanityDryRunOutput;
DataSanityExecution: DataSanityExecution;
DataSanityImpactedElement: DataSanityImpactedElement;
@@ -42068,6 +42095,7 @@ export type ResolversParentTypes = ResolversObject<{
IncidentConnection: Omit & { edges?: Maybe>> };
IncidentEdge: Omit & { node: ResolversParentTypes['Incident'] };
IncidentEditMutations: Omit & { contextClean?: Maybe, contextPatch?: Maybe, fieldPatch?: Maybe, relationAdd?: Maybe, relationDelete?: Maybe };
+ IndexStats: IndexStats;
IndexedFile: Omit & { entity?: Maybe };
IndexedFileConnection: Omit & { edges?: Maybe>> };
IndexedFileEdge: Omit & { node: ResolversParentTypes['IndexedFile'] };
@@ -44970,6 +44998,19 @@ export type DataComponentEdgeResolvers;
}>;
+export type DataIndexResolvers = ResolversObject<{
+ health?: Resolver, ParentType, ContextType>;
+ name?: Resolver, ParentType, ContextType>;
+ primaries?: Resolver, ParentType, ContextType>;
+ status?: Resolver, ParentType, ContextType>;
+ total?: Resolver, ParentType, ContextType>;
+ uuid?: Resolver, ParentType, ContextType>;
+}>;
+
+export type DataIndexMetricsResolvers = ResolversObject<{
+ indexes?: Resolver>>, ParentType, ContextType>;
+}>;
+
export type DataSanityDryRunOutputResolvers = ResolversObject<{
estimated_impact?: Resolver, ParentType, ContextType>;
}>;
@@ -45340,6 +45381,7 @@ export type DistributionResolvers = ResolversObject<{
count?: Resolver, ParentType, ContextType>;
+ total_size_in_bytes?: Resolver, ParentType, ContextType>;
}>;
export type DomainNameResolvers = ResolversObject<{
@@ -46928,6 +46970,10 @@ export type IncidentEditMutationsResolvers, ParentType, ContextType, RequireFields>;
}>;
+export type IndexStatsResolvers = ResolversObject<{
+ docs?: Resolver, ParentType, ContextType>;
+}>;
+
export type IndexedFileResolvers = ResolversObject<{
entity?: Resolver, ParentType, ContextType>;
file_id?: Resolver;
@@ -50638,6 +50684,7 @@ export type QueryResolvers>;
dataComponent?: Resolver, ParentType, ContextType, RequireFields>;
dataComponents?: Resolver, ParentType, ContextType, Partial>;
+ dataIndexMetrics?: Resolver, ParentType, ContextType>;
dataSanityExecutions?: Resolver, ParentType, ContextType>;
dataSanityOperationDryRun?: Resolver>;
dataSanityOperations?: Resolver, ParentType, ContextType>;
@@ -54941,6 +54988,8 @@ export type Resolvers = ResolversObject<{
DataComponent?: DataComponentResolvers;
DataComponentConnection?: DataComponentConnectionResolvers;
DataComponentEdge?: DataComponentEdgeResolvers;
+ DataIndex?: DataIndexResolvers;
+ DataIndexMetrics?: DataIndexMetricsResolvers;
DataSanityDryRunOutput?: DataSanityDryRunOutputResolvers;
DataSanityExecution?: DataSanityExecutionResolvers;
DataSanityImpactedElement?: DataSanityImpactedElementResolvers;
@@ -55073,6 +55122,7 @@ export type Resolvers = ResolversObject<{
IncidentConnection?: IncidentConnectionResolvers;
IncidentEdge?: IncidentEdgeResolvers;
IncidentEditMutations?: IncidentEditMutationsResolvers;
+ IndexStats?: IndexStatsResolvers;
IndexedFile?: IndexedFileResolvers;
IndexedFileConnection?: IndexedFileConnectionResolvers;
IndexedFileEdge?: IndexedFileEdgeResolvers;
diff --git a/opencti-platform/opencti-graphql/src/resolvers/elasticSearchMetrics.js b/opencti-platform/opencti-graphql/src/resolvers/elasticSearchMetrics.js
index 00abaeb1e490..1118ed94e075 100644
--- a/opencti-platform/opencti-graphql/src/resolvers/elasticSearchMetrics.js
+++ b/opencti-platform/opencti-graphql/src/resolvers/elasticSearchMetrics.js
@@ -1,8 +1,9 @@
-import { getMetrics } from '../domain/searchMetrics';
+import { getMetrics, getIndexMetrics } from '../domain/searchMetrics';
const elasticSearchMetricsResolvers = {
Query: {
elasticSearchMetrics: () => getMetrics(),
+ dataIndexMetrics: () => getIndexMetrics(),
},
};