This is an automated email from the ASF dual-hosted git repository.
jin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-hugegraph-ai.git
The following commit(s) were added to refs/heads/main by this push:
new f8500f9 fix(llm): limit the length of log & improve the format (#121)
f8500f9 is described below
commit f8500f9b56ac2423c564659c62fe61bb70525ad0
Author: Dylan <[email protected]>
AuthorDate: Mon Dec 2 18:11:04 2024 +0800
fix(llm): limit the length of log & improve the format (#121)
as title
---------
Co-authored-by: diye-he <[email protected]>
Co-authored-by: imbajin <[email protected]>
---
hugegraph-llm/src/hugegraph_llm/api/admin_api.py | 2 +-
.../src/hugegraph_llm/api/models/rag_requests.py | 1 +
hugegraph-llm/src/hugegraph_llm/api/rag_api.py | 3 +-
.../src/hugegraph_llm/demo/rag_demo/admin_block.py | 48 +++++++++++++---------
.../src/hugegraph_llm/demo/rag_demo/app.py | 16 +++-----
5 files changed, 38 insertions(+), 32 deletions(-)
diff --git a/hugegraph-llm/src/hugegraph_llm/api/admin_api.py
b/hugegraph-llm/src/hugegraph_llm/api/admin_api.py
index f933b71..c7a6524 100644
--- a/hugegraph-llm/src/hugegraph_llm/api/admin_api.py
+++ b/hugegraph-llm/src/hugegraph_llm/api/admin_api.py
@@ -28,7 +28,7 @@ def admin_http_api(router: APIRouter, log_stream):
@router.post("/logs", status_code=status.HTTP_200_OK)
async def log_stream_api(req: LogStreamRequest):
if os.getenv('ADMIN_TOKEN') != req.admin_token:
- raise
generate_response(RAGResponse(status_code=status.HTTP_403_FORBIDDEN,
detail="Invalid admin_token"))
+ raise
generate_response(RAGResponse(status_code=status.HTTP_403_FORBIDDEN,
message="Invalid admin_token"))
else:
log_path = os.path.join("logs", req.log_file)
diff --git a/hugegraph-llm/src/hugegraph_llm/api/models/rag_requests.py
b/hugegraph-llm/src/hugegraph_llm/api/models/rag_requests.py
index dcf19db..9413890 100644
--- a/hugegraph-llm/src/hugegraph_llm/api/models/rag_requests.py
+++ b/hugegraph-llm/src/hugegraph_llm/api/models/rag_requests.py
@@ -77,6 +77,7 @@ class RerankerConfigRequest(BaseModel):
api_key: str
cohere_base_url: Optional[str] = None
+
class LogStreamRequest(BaseModel):
admin_token: Optional[str] = None
log_file: Optional[str] = 'llm-server.log'
diff --git a/hugegraph-llm/src/hugegraph_llm/api/rag_api.py
b/hugegraph-llm/src/hugegraph_llm/api/rag_api.py
index 4db2116..9d1e01a 100644
--- a/hugegraph-llm/src/hugegraph_llm/api/rag_api.py
+++ b/hugegraph-llm/src/hugegraph_llm/api/rag_api.py
@@ -94,14 +94,13 @@ def rag_http_api(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="An
unexpected error occurred."
) from e
-
@router.post("/config/graph", status_code=status.HTTP_201_CREATED)
def graph_config_api(req: GraphConfigRequest):
# Accept status code
res = apply_graph_conf(req.ip, req.port, req.name, req.user, req.pwd,
req.gs, origin_call="http")
return generate_response(RAGResponse(status_code=res, message="Missing
Value"))
- #TODO: restructure the implement of llm to three types, like
"/config/chat_llm"
+ # TODO: restructure the implement of llm to three types, like
"/config/chat_llm"
@router.post("/config/llm", status_code=status.HTTP_201_CREATED)
def llm_config_api(req: LLMConfigRequest):
settings.llm_type = req.llm_type
diff --git a/hugegraph-llm/src/hugegraph_llm/demo/rag_demo/admin_block.py
b/hugegraph-llm/src/hugegraph_llm/demo/rag_demo/admin_block.py
index db34b7e..d8be1fe 100644
--- a/hugegraph-llm/src/hugegraph_llm/demo/rag_demo/admin_block.py
+++ b/hugegraph-llm/src/hugegraph_llm/demo/rag_demo/admin_block.py
@@ -17,6 +17,7 @@
import asyncio
import os
+from collections import deque
import gradio as gr
from gradio import Request
@@ -24,12 +25,15 @@ from gradio import Request
from hugegraph_llm.utils.log import log
-async def log_stream(log_path: str):
+async def log_stream(log_path: str, lines: int = 125):
"""
Stream the content of a log file like `tail -f`.
"""
try:
with open(log_path, 'r') as file:
+ buffer = deque(file, maxlen=lines)
+ for line in buffer:
+ yield line # Yield the initial lines
while True:
line = file.readline()
if line:
@@ -43,37 +47,45 @@ async def log_stream(log_path: str):
# Functions to read each log file
-def read_llm_server_log():
+def read_llm_server_log(lines=250):
+ log_path = "logs/llm-server.log"
try:
- with open("logs/llm-server.log", "r") as f:
- # TODO: avoid read the whole file (read latest N lines instead)
- return f.read()
+ with open(log_path, "r") as f:
+ return ''.join(deque(f, maxlen=lines))
except FileNotFoundError:
+ log.critical(f"Log file not found: {log_path}")
return "LLM Server log file not found."
# Functions to clear each log file
def clear_llm_server_log():
- with open("logs/llm-server.log", "w") as f:
- f.truncate(0) # Clear the contents of the file
- return "LLM Server log cleared."
+ log_path = "logs/llm-server.log"
+ try:
+ with open(log_path, "w") as f:
+ f.truncate(0) # Clear the contents of the file
+ return "LLM Server log cleared."
+ except Exception as e:
+ log.error(f"An error occurred while clearing the log: {str(e)}")
+ return "Failed to clear LLM Server log."
# Function to validate password and control access to logs
def check_password(password, request: Request = None):
client_ip = request.client.host if request else "Unknown IP"
+ admin_token = os.getenv('ADMIN_TOKEN')
- if password == os.getenv('ADMIN_TOKEN'):
+ if password == admin_token:
# Return logs and update visibility
llm_log = read_llm_server_log()
# Log the successful access with the IP address
log.info(f"Logs accessed successfully from IP: {client_ip}")
return (
- llm_log,
- gr.update(visible=True),
- gr.update(visible=True),
- gr.update(visible=True),
- gr.update(visible=False))
+ llm_log,
+ gr.update(visible=True),
+ gr.update(visible=True),
+ gr.update(visible=True),
+ gr.update(visible=False)
+ )
else:
# Log the failed attempt with IP address
log.error(f"Incorrect password attempt from IP: {client_ip}")
@@ -112,14 +124,12 @@ def create_admin_block():
with gr.Column():
# LLM Server log display, refreshes every 1 second
gr.Markdown("### LLM Server Log")
- llm_server_log_output = gr.Textbox(
+ llm_server_log_output = gr.Code(
label="LLM Server Log (llm-server.log)",
lines=20,
- value=read_llm_server_log, # Initial value using the
function
- show_copy_button=True,
- elem_classes="log-container",
+ value=f"```\n{read_llm_server_log()}\n```", # Initial
value using the function
+ elem_classes="code-container-edit",
every=60, # Refresh every 60 second
- autoscroll=True # Enable auto-scroll
)
with gr.Row():
with gr.Column():
diff --git a/hugegraph-llm/src/hugegraph_llm/demo/rag_demo/app.py
b/hugegraph-llm/src/hugegraph_llm/demo/rag_demo/app.py
index f5a067a..5604dbd 100644
--- a/hugegraph-llm/src/hugegraph_llm/demo/rag_demo/app.py
+++ b/hugegraph-llm/src/hugegraph_llm/demo/rag_demo/app.py
@@ -24,9 +24,10 @@ import uvicorn
from fastapi import FastAPI, Depends, APIRouter
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
-from hugegraph_llm.api.rag_api import rag_http_api
from hugegraph_llm.api.admin_api import admin_http_api
+from hugegraph_llm.api.rag_api import rag_http_api
from hugegraph_llm.config import settings, prompt
+from hugegraph_llm.demo.rag_demo.admin_block import create_admin_block,
log_stream
from hugegraph_llm.demo.rag_demo.configs_block import (
create_configs_block,
apply_llm_config,
@@ -37,7 +38,6 @@ from hugegraph_llm.demo.rag_demo.configs_block import (
from hugegraph_llm.demo.rag_demo.other_block import create_other_block
from hugegraph_llm.demo.rag_demo.rag_block import create_rag_block, rag_answer
from hugegraph_llm.demo.rag_demo.vector_graph_block import
create_vector_graph_block
-from hugegraph_llm.demo.rag_demo.admin_block import create_admin_block,
log_stream
from hugegraph_llm.resources.demo.css import CSS
from hugegraph_llm.utils.log import log
@@ -97,7 +97,6 @@ def init_rag_ui() -> gr.Interface:
create_other_block()
with gr.Tab(label="4. Admin Tools ⚙️"):
create_admin_block()
-
def refresh_ui_config_prompt() -> tuple:
settings.from_env()
@@ -115,10 +114,8 @@ def init_rag_ui() -> gr.Interface:
textbox_array_graph_config[3],
textbox_array_graph_config[4],
textbox_array_graph_config[5],
-
textbox_input_schema,
textbox_info_extract_template,
-
textbox_inp,
textbox_answer_prompt_input,
textbox_keywords_extract_prompt_input
@@ -133,21 +130,20 @@ if __name__ == "__main__":
parser.add_argument("--port", type=int, default=8001, help="port")
args = parser.parse_args()
app = FastAPI()
-
+
settings.check_env()
prompt.update_yaml_file()
auth_enabled = os.getenv("ENABLE_LOGIN", "False").lower() == "true"
log.info("(Status) Authentication is %s now.", "enabled" if auth_enabled
else "disabled")
api_auth = APIRouter(dependencies=[Depends(authenticate)] if auth_enabled
else [])
-
+
hugegraph_llm = init_rag_ui()
-
+
rag_http_api(api_auth, rag_answer, apply_graph_config, apply_llm_config,
apply_embedding_config,
apply_reranker_config)
-
admin_http_api(api_auth, log_stream)
-
+
app.include_router(api_auth)
# TODO: support multi-user login when need