https://github.com/infiniflow/ragflow/issues/2503 ### What problem does this PR solve? _Briefly describe what this PR aims to solve. Include background context that will help reviewers understand the purpose of the PR._ ### Type of change - [x] New Feature (non-breaking change which adds functionality) Before: <img width="611" alt="image" src="https://github.com/user-attachments/assets/02a3a1ee-7bfb-4fe0-9b15-11ced69cc8a3"> After: <img width="796" alt="image" src="https://github.com/user-attachments/assets/371136af-8d16-47aa-909b-26609d3ad60e"> <img width="557" alt="image" src="https://github.com/user-attachments/assets/9268362f-2b6a-4ea1-9fe7-659f7292e5e1">tags/v0.12.0
| @@ -18,11 +18,12 @@ import json | |||
| from flask_login import login_required | |||
| from api.db.services.knowledgebase_service import KnowledgebaseService | |||
| from api.settings import DATABASE_TYPE | |||
| from api.utils.api_utils import get_json_result | |||
| from api.versions import get_rag_version | |||
| from rag.settings import SVR_QUEUE_NAME | |||
| from rag.utils.es_conn import ELASTICSEARCH | |||
| from rag.utils.storage_factory import STORAGE_IMPL | |||
| from rag.utils.storage_factory import STORAGE_IMPL, STORAGE_IMPL_TYPE | |||
| from timeit import default_timer as timer | |||
| from rag.utils.redis_conn import REDIS_CONN | |||
| @@ -48,16 +49,16 @@ def status(): | |||
| st = timer() | |||
| try: | |||
| STORAGE_IMPL.health() | |||
| res["minio"] = {"status": "green", "elapsed": "{:.1f}".format((timer() - st)*1000.)} | |||
| res["storage"] = {"storage": STORAGE_IMPL_TYPE.lower(), "status": "green", "elapsed": "{:.1f}".format((timer() - st)*1000.)} | |||
| except Exception as e: | |||
| res["minio"] = {"status": "red", "elapsed": "{:.1f}".format((timer() - st)*1000.), "error": str(e)} | |||
| res["storage"] = {"storage": STORAGE_IMPL_TYPE.lower(), "status": "red", "elapsed": "{:.1f}".format((timer() - st)*1000.), "error": str(e)} | |||
| st = timer() | |||
| try: | |||
| KnowledgebaseService.get_by_id("x") | |||
| res["mysql"] = {"status": "green", "elapsed": "{:.1f}".format((timer() - st)*1000.)} | |||
| res["database"] = {"database": DATABASE_TYPE.lower(), "status": "green", "elapsed": "{:.1f}".format((timer() - st)*1000.)} | |||
| except Exception as e: | |||
| res["mysql"] = {"status": "red", "elapsed": "{:.1f}".format((timer() - st)*1000.), "error": str(e)} | |||
| res["database"] = {"database": DATABASE_TYPE.lower(), "status": "red", "elapsed": "{:.1f}".format((timer() - st)*1000.), "error": str(e)} | |||
| st = timer() | |||
| try: | |||
| @@ -27,4 +27,5 @@ class StorageFactory: | |||
| return cls.storage_mapping[storage]() | |||
| STORAGE_IMPL = StorageFactory.create(Storage[os.getenv('STORAGE_IMPL', 'MINIO')]) | |||
| STORAGE_IMPL_TYPE = os.getenv('STORAGE_IMPL', 'MINIO') | |||
| STORAGE_IMPL = StorageFactory.create(Storage[STORAGE_IMPL_TYPE]) | |||
| @@ -0,0 +1,3 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> | |||
| <svg width="800px" height="800px" viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M117 608.4v178.5c1.5 93.7 155.7 169.5 395 169.5s393.4-75.8 395-169.5V608.4H117z" fill="#1B9BDB" /><path d="M907 607.7c0 99.4-154.8 180-395 180s-395-80.6-395-180 154.8-180 395-180 395 80.5 395 180z" fill="#FFFFFF" /><path d="M117 428.4v158.5c1.5 93.7 155.7 179.5 395 179.5s393.4-85.8 395-179.5V428.4H117z" fill="#1B9BDB" /><path d="M907 427.7c0 99.4-154.8 180-395 180s-395-80.6-395-180 154.8-180 395-180 395 80.5 395 180z" fill="#FFFFFF" /><path d="M117 248.4v158.5c1.5 93.7 155.7 179.5 395 179.5s393.4-85.8 395-179.5V248.4H117z" fill="#1B9BDB" /><path d="M907 247.7c0 99.4-154.8 180-395 180s-395-80.6-395-180 154.8-180 395-180 395 80.5 395 180z" fill="#3ED6FF" /></svg> | |||
| @@ -0,0 +1,6 @@ | |||
| <?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> | |||
| <svg fill="#000000" width="800px" height="800px" viewBox="0 0 36 36" version="1.1" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||
| <title>storage-solid</title> | |||
| <path class="clr-i-solid clr-i-solid-path-1" d="M17.91,18.28c8.08,0,14.66-1.74,15.09-3.94V8.59c-.43,2.2-7,3.94-15.09,3.94A39.4,39.4,0,0,1,6.25,11V9a39.4,39.4,0,0,0,11.66,1.51C26,10.53,32.52,8.79,33,6.61h0C32.8,3.2,23.52,2.28,18,2.28S3,3.21,3,6.71V29.29c0,3.49,9.43,4.43,15,4.43s15-.93,15-4.43V24.09C32.57,26.28,26,28,17.91,28A39.4,39.4,0,0,1,6.25,26.52v-2A39.4,39.4,0,0,0,17.91,26C26,26,32.57,24.28,33,22.09V16.34c-.43,2.2-7,3.94-15.09,3.94A39.4,39.4,0,0,1,6.25,18.77v-2A39.4,39.4,0,0,0,17.91,18.28Z"></path> | |||
| <rect x="0" y="0" width="36" height="36" fill-opacity="0"/> | |||
| </svg> | |||
| @@ -24,8 +24,8 @@ export type TaskExecutorElapsed = Record<string, number[]>; | |||
| export interface ISystemStatus { | |||
| es: Es; | |||
| minio: Minio; | |||
| mysql: Minio; | |||
| storage: Storage; | |||
| database: Database; | |||
| redis: Redis; | |||
| task_executor: { | |||
| error?: string; | |||
| @@ -41,7 +41,13 @@ interface Redis { | |||
| pending: number; | |||
| } | |||
| export interface Minio { | |||
| export interface Storage { | |||
| status: string; | |||
| elapsed: number; | |||
| error: string; | |||
| } | |||
| export interface Database { | |||
| status: string; | |||
| elapsed: number; | |||
| error: string; | |||
| @@ -1,5 +1,6 @@ | |||
| import SvgIcon from '@/components/svg-icon'; | |||
| import { useFetchSystemStatus } from '@/hooks/user-setting-hooks'; | |||
| import { ISystemStatus, Storage } from '@/interfaces/database/userSetting'; | |||
| import { | |||
| ISystemStatus, | |||
| TaskExecutorElapsed, | |||
| @@ -24,12 +25,19 @@ enum Status { | |||
| const TitleMap = { | |||
| es: 'Elasticsearch', | |||
| minio: 'MinIO Object Storage', | |||
| storage: 'Object Storage', | |||
| redis: 'Redis', | |||
| mysql: 'Mysql', | |||
| database: 'Database', | |||
| task_executor: 'Task Executor', | |||
| }; | |||
| const IconMap = { | |||
| es: 'es', | |||
| storage: 'storage', | |||
| redis: 'redis', | |||
| database: 'database', | |||
| }; | |||
| const SystemInfo = () => { | |||
| const { | |||
| systemStatus, | |||
| @@ -56,7 +64,7 @@ const SystemInfo = () => { | |||
| {key === 'task_executor' ? ( | |||
| <img src="/logo.svg" alt="" width={26} /> | |||
| ) : ( | |||
| <SvgIcon name={key} width={26}></SvgIcon> | |||
| <SvgIcon name={IconMap[key as keyof typeof IconMap]} width={26}></SvgIcon> | |||
| )} | |||
| <span className={styles.title}> | |||
| {TitleMap[key as keyof typeof TitleMap]} | |||