Spaces:
Sleeping
Sleeping
Updated the App page
Browse files
main.py
CHANGED
|
@@ -31,7 +31,11 @@ logging.Formatter.converter = lambda *args: datetime.fromtimestamp(args[-1], tz=
|
|
| 31 |
logging.basicConfig(
|
| 32 |
level=logging.INFO,
|
| 33 |
format='[%(asctime)s] %(levelname)s: %(message)s',
|
| 34 |
-
datefmt='%I:%M:%S %p'
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
)
|
| 36 |
logger = logging.getLogger(__name__)
|
| 37 |
|
|
@@ -896,6 +900,7 @@ async def root(request: Request):
|
|
| 896 |
<div class="tabs">
|
| 897 |
<button class="tab-btn active" onclick="switchTab('health')">π₯ Health</button>
|
| 898 |
<button class="tab-btn" onclick="switchTab('assistant')">π€ Assistant</button>
|
|
|
|
| 899 |
</div>
|
| 900 |
|
| 901 |
<div id="health" class="tab-content active">
|
|
@@ -950,6 +955,92 @@ async def root(request: Request):
|
|
| 950 |
"""
|
| 951 |
|
| 952 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 953 |
@app.get("/assistant")
|
| 954 |
async def internal_assistant():
|
| 955 |
load_dotenv(override=True)
|
|
|
|
| 31 |
logging.basicConfig(
|
| 32 |
level=logging.INFO,
|
| 33 |
format='[%(asctime)s] %(levelname)s: %(message)s',
|
| 34 |
+
datefmt='%I:%M:%S %p',
|
| 35 |
+
handlers=[
|
| 36 |
+
logging.FileHandler("app.log"),
|
| 37 |
+
logging.StreamHandler()
|
| 38 |
+
]
|
| 39 |
)
|
| 40 |
logger = logging.getLogger(__name__)
|
| 41 |
|
|
|
|
| 900 |
<div class="tabs">
|
| 901 |
<button class="tab-btn active" onclick="switchTab('health')">π₯ Health</button>
|
| 902 |
<button class="tab-btn" onclick="switchTab('assistant')">π€ Assistant</button>
|
| 903 |
+
<a href="/logs" target="_blank" class="tab-btn" style="text-decoration: none; display: inline-block;">π View Logs</a>
|
| 904 |
</div>
|
| 905 |
|
| 906 |
<div id="health" class="tab-content active">
|
|
|
|
| 955 |
"""
|
| 956 |
|
| 957 |
|
| 958 |
+
@app.get("/logs", response_class=HTMLResponse)
|
| 959 |
+
async def view_logs():
|
| 960 |
+
"""Returns the application logs."""
|
| 961 |
+
try:
|
| 962 |
+
with open("app.log", "r") as f:
|
| 963 |
+
lines = f.readlines()
|
| 964 |
+
# Show last 1000 lines
|
| 965 |
+
log_content = "".join(lines[-1000:])
|
| 966 |
+
# Escape HTML to prevent injection if logs contain < >
|
| 967 |
+
log_content = log_content.replace("&", "&").replace("<", "<").replace(">", ">")
|
| 968 |
+
except Exception as e:
|
| 969 |
+
log_content = f"Error reading logs: {e}"
|
| 970 |
+
|
| 971 |
+
return f"""
|
| 972 |
+
<!DOCTYPE html>
|
| 973 |
+
<html lang="en">
|
| 974 |
+
<head>
|
| 975 |
+
<meta charset="UTF-8">
|
| 976 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 977 |
+
<title>Application Logs</title>
|
| 978 |
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
|
| 979 |
+
<style>
|
| 980 |
+
body {{
|
| 981 |
+
font-family: 'Inter', sans-serif;
|
| 982 |
+
background: #0f172a;
|
| 983 |
+
color: #f8fafc;
|
| 984 |
+
margin: 0;
|
| 985 |
+
padding: 20px;
|
| 986 |
+
}}
|
| 987 |
+
.header {{
|
| 988 |
+
display: flex;
|
| 989 |
+
justify-content: space-between;
|
| 990 |
+
align-items: center;
|
| 991 |
+
margin-bottom: 20px;
|
| 992 |
+
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
| 993 |
+
padding-bottom: 10px;
|
| 994 |
+
}}
|
| 995 |
+
.header h1 {{
|
| 996 |
+
margin: 0;
|
| 997 |
+
font-size: 1.5rem;
|
| 998 |
+
color: #60a5fa;
|
| 999 |
+
}}
|
| 1000 |
+
.btn-back {{
|
| 1001 |
+
background: rgba(255, 255, 255, 0.1);
|
| 1002 |
+
color: white;
|
| 1003 |
+
text-decoration: none;
|
| 1004 |
+
padding: 8px 16px;
|
| 1005 |
+
border-radius: 6px;
|
| 1006 |
+
font-weight: 600;
|
| 1007 |
+
transition: background 0.3s;
|
| 1008 |
+
}}
|
| 1009 |
+
.btn-back:hover {{
|
| 1010 |
+
background: rgba(255, 255, 255, 0.2);
|
| 1011 |
+
}}
|
| 1012 |
+
.log-container {{
|
| 1013 |
+
background: #0d1117;
|
| 1014 |
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
| 1015 |
+
padding: 15px;
|
| 1016 |
+
border-radius: 8px;
|
| 1017 |
+
font-family: 'Consolas', 'Monaco', monospace;
|
| 1018 |
+
font-size: 0.9rem;
|
| 1019 |
+
line-height: 1.5;
|
| 1020 |
+
white-space: pre-wrap;
|
| 1021 |
+
word-wrap: break-word;
|
| 1022 |
+
color: #a5d6ff;
|
| 1023 |
+
max-height: 80vh;
|
| 1024 |
+
overflow-y: auto;
|
| 1025 |
+
}}
|
| 1026 |
+
</style>
|
| 1027 |
+
</head>
|
| 1028 |
+
<body>
|
| 1029 |
+
<div class="header">
|
| 1030 |
+
<h1>π Application Logs (Last 1000 lines)</h1>
|
| 1031 |
+
<a href="/" class="btn-back">← Back to Dashboard</a>
|
| 1032 |
+
</div>
|
| 1033 |
+
<div class="log-container" id="log-container">{{log_content}}</div>
|
| 1034 |
+
<script>
|
| 1035 |
+
// Auto-scroll to bottom of the logs
|
| 1036 |
+
var logContainer = document.getElementById("log-container");
|
| 1037 |
+
logContainer.scrollTop = logContainer.scrollHeight;
|
| 1038 |
+
</script>
|
| 1039 |
+
</body>
|
| 1040 |
+
</html>
|
| 1041 |
+
""".replace("{{log_content}}", log_content)
|
| 1042 |
+
|
| 1043 |
+
|
| 1044 |
@app.get("/assistant")
|
| 1045 |
async def internal_assistant():
|
| 1046 |
load_dotenv(override=True)
|