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(), }, };