Spaces:
Sleeping
Sleeping
Update app_gradio.py
Browse files- app_gradio.py +81 -30
app_gradio.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
"""
|
| 2 |
Log Classification System β HuggingFace Spaces
|
| 3 |
-
Optimized for Gradio 6.0 & HF Free Tier
|
| 4 |
"""
|
| 5 |
from __future__ import annotations
|
| 6 |
import io
|
|
@@ -11,7 +11,7 @@ import gradio as gr
|
|
| 11 |
from classify import classify_log, classify_csv
|
| 12 |
from processor_bert import preload_models
|
| 13 |
|
| 14 |
-
# ββ Preload models (
|
| 15 |
preload_models()
|
| 16 |
|
| 17 |
SOURCES = [
|
|
@@ -31,39 +31,61 @@ EXAMPLE_LOGS = [
|
|
| 31 |
["ModernHR", "Multiple login failures occurred on user 6454 account"],
|
| 32 |
["BillingSystem", "GET /v2/servers/detail HTTP/1.1 status: 200 len: 1583 time: 0.19"],
|
| 33 |
["AnalyticsEngine", "System crashed due to disk I/O failure on node-3"],
|
| 34 |
-
["LegacyCRM", "
|
| 35 |
]
|
| 36 |
|
| 37 |
-
# ββ Custom CSS ββββββββββββββββββββββββ
|
| 38 |
CUSTOM_CSS = """
|
| 39 |
-
@import url('https://fonts.googleapis.com/css2?family=Rajdhani:wght@
|
|
|
|
| 40 |
:root {
|
| 41 |
--bg-primary: #050810;
|
| 42 |
--accent-cyan: #00d4ff;
|
| 43 |
--text-primary: #e2e8f0;
|
| 44 |
}
|
| 45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
.gradio-group {
|
| 47 |
background: #0d1425 !important;
|
| 48 |
border: 1px solid rgba(0, 212, 255, 0.1) !important;
|
| 49 |
border-radius: 20px !important;
|
|
|
|
| 50 |
}
|
|
|
|
| 51 |
button.primary {
|
| 52 |
background: linear-gradient(135deg, #0066ff, #00d4ff) !important;
|
| 53 |
border: none !important;
|
| 54 |
color: white !important;
|
| 55 |
-
font-weight:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
}
|
| 57 |
"""
|
| 58 |
|
| 59 |
-
# ββ Functions ββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 60 |
|
| 61 |
def classify_single(source: str, log_message: str):
|
| 62 |
from processor_bert import _model_ready
|
| 63 |
if not log_message.strip():
|
| 64 |
return "β", "β", "β", "β"
|
| 65 |
if not _model_ready:
|
| 66 |
-
return "β³
|
| 67 |
|
| 68 |
t0 = time.perf_counter()
|
| 69 |
try:
|
|
@@ -80,29 +102,58 @@ def classify_single(source: str, log_message: str):
|
|
| 80 |
return f"Error: {str(e)}", "Fail", "β", "β"
|
| 81 |
|
| 82 |
def classify_batch(file, progress=gr.Progress(track_tqdm=True)):
|
| 83 |
-
if file is None: return None, "β οΈ
|
| 84 |
|
| 85 |
-
progress(0, desc="π
|
| 86 |
t0 = time.perf_counter()
|
| 87 |
|
| 88 |
try:
|
|
|
|
| 89 |
output_path, df = classify_csv(file.name, "/tmp/classified_output.csv")
|
| 90 |
-
|
|
|
|
|
|
|
| 91 |
|
| 92 |
total = len(df)
|
| 93 |
tier_counts = df["tier_used"].value_counts().to_dict()
|
| 94 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
stats = (
|
| 97 |
-
f"β
|
| 98 |
-
f"
|
| 99 |
-
f"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
)
|
|
|
|
|
|
|
| 101 |
return output_path, stats
|
|
|
|
| 102 |
except Exception as e:
|
| 103 |
-
return None, f"β Error: {str(e)}"
|
|
|
|
|
|
|
| 104 |
|
| 105 |
-
# ββ Theme Configuration βββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 106 |
THEME = gr.themes.Base(
|
| 107 |
primary_hue="blue",
|
| 108 |
secondary_hue="cyan",
|
|
@@ -110,42 +161,42 @@ THEME = gr.themes.Base(
|
|
| 110 |
font=[gr.themes.GoogleFont("Exo 2")],
|
| 111 |
)
|
| 112 |
|
| 113 |
-
# ββ UI Layout βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 114 |
with gr.Blocks(title="Log AI Engine") as demo:
|
| 115 |
gr.HTML("<div style='text-align: center; padding: 20px;'><h1>π LOG CLASSIFICATION SYSTEM</h1></div>")
|
| 116 |
|
| 117 |
with gr.Tabs():
|
| 118 |
-
|
|
|
|
| 119 |
with gr.Row():
|
| 120 |
with gr.Column(scale=1):
|
| 121 |
src_in = gr.Dropdown(choices=SOURCES, value="ModernCRM", label="SOURCE")
|
| 122 |
with gr.Column(scale=3):
|
| 123 |
-
msg_in = gr.Textbox(label="LOG MESSAGE", placeholder="Paste log
|
| 124 |
|
| 125 |
-
run_btn = gr.Button("βΆ CLASSIFY", variant="primary")
|
| 126 |
|
| 127 |
with gr.Row():
|
| 128 |
-
lbl_out = gr.Textbox(label="LABEL")
|
| 129 |
-
tier_out = gr.Textbox(label="TIER")
|
| 130 |
conf_out = gr.Textbox(label="CONFIDENCE")
|
| 131 |
lat_out = gr.Textbox(label="LATENCY")
|
| 132 |
|
| 133 |
run_btn.click(classify_single, [src_in, msg_in], [lbl_out, tier_out, conf_out, lat_out])
|
| 134 |
gr.Examples(examples=EXAMPLE_LOGS, inputs=[src_in, msg_in])
|
| 135 |
|
| 136 |
-
|
|
|
|
| 137 |
with gr.Row():
|
| 138 |
with gr.Column():
|
| 139 |
csv_in = gr.File(label="UPLOAD CSV", file_types=[".csv"])
|
| 140 |
-
batch_btn = gr.Button("βΆ
|
| 141 |
with gr.Column():
|
| 142 |
-
csv_out = gr.File(label="DOWNLOAD
|
| 143 |
-
stats_out = gr.Textbox(label="
|
| 144 |
|
| 145 |
batch_btn.click(classify_batch, inputs=[csv_in], outputs=[csv_out, stats_out])
|
| 146 |
|
| 147 |
-
# ββ Optimized Launch ββββββββββββββββββββββββββββββββββββββββ
|
| 148 |
-
# Gradio 6.0 mein theme aur css launch() ke andar honge
|
| 149 |
demo.queue(default_concurrency_limit=2).launch(
|
| 150 |
server_name="0.0.0.0",
|
| 151 |
server_port=7860,
|
|
|
|
| 1 |
"""
|
| 2 |
Log Classification System β HuggingFace Spaces
|
| 3 |
+
Ultra-Modern 3D UI | Optimized for Gradio 6.0 & HF Free Tier
|
| 4 |
"""
|
| 5 |
from __future__ import annotations
|
| 6 |
import io
|
|
|
|
| 11 |
from classify import classify_log, classify_csv
|
| 12 |
from processor_bert import preload_models
|
| 13 |
|
| 14 |
+
# ββ Preload models (Start loading BERT into RAM immediately) ββ
|
| 15 |
preload_models()
|
| 16 |
|
| 17 |
SOURCES = [
|
|
|
|
| 31 |
["ModernHR", "Multiple login failures occurred on user 6454 account"],
|
| 32 |
["BillingSystem", "GET /v2/servers/detail HTTP/1.1 status: 200 len: 1583 time: 0.19"],
|
| 33 |
["AnalyticsEngine", "System crashed due to disk I/O failure on node-3"],
|
| 34 |
+
["LegacyCRM", "The 'BulkEmailSender' feature will be deprecated in v5.0."],
|
| 35 |
]
|
| 36 |
|
| 37 |
+
# ββ Custom CSS (Ultra-Modern 3D Theme) ββββββββββββββββββββββββ
|
| 38 |
CUSTOM_CSS = """
|
| 39 |
+
@import url('https://fonts.googleapis.com/css2?family=Rajdhani:wght@600;700&family=Share+Tech+Mono&family=Exo+2:wght@400;600&display=swap');
|
| 40 |
+
|
| 41 |
:root {
|
| 42 |
--bg-primary: #050810;
|
| 43 |
--accent-cyan: #00d4ff;
|
| 44 |
--text-primary: #e2e8f0;
|
| 45 |
}
|
| 46 |
+
|
| 47 |
+
body, .gradio-container {
|
| 48 |
+
background: var(--bg-primary) !important;
|
| 49 |
+
font-family: 'Exo 2', sans-serif !important;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
.gradio-group {
|
| 53 |
background: #0d1425 !important;
|
| 54 |
border: 1px solid rgba(0, 212, 255, 0.1) !important;
|
| 55 |
border-radius: 20px !important;
|
| 56 |
+
box-shadow: 0 10px 30px rgba(0,0,0,0.5) !important;
|
| 57 |
}
|
| 58 |
+
|
| 59 |
button.primary {
|
| 60 |
background: linear-gradient(135deg, #0066ff, #00d4ff) !important;
|
| 61 |
border: none !important;
|
| 62 |
color: white !important;
|
| 63 |
+
font-weight: 700 !important;
|
| 64 |
+
letter-spacing: 1.5px !important;
|
| 65 |
+
box-shadow: 0 4px 15px rgba(0, 102, 255, 0.4) !important;
|
| 66 |
+
transition: all 0.2s ease !important;
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
button.primary:hover {
|
| 70 |
+
transform: translateY(-2px) !important;
|
| 71 |
+
box-shadow: 0 8px 25px rgba(0, 212, 255, 0.5) !important;
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
.output-stats textarea {
|
| 75 |
+
font-family: 'Share Tech Mono', monospace !important;
|
| 76 |
+
background: #050810 !important;
|
| 77 |
+
color: #00ff88 !important;
|
| 78 |
}
|
| 79 |
"""
|
| 80 |
|
| 81 |
+
# ββ Functions ββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 82 |
|
| 83 |
def classify_single(source: str, log_message: str):
|
| 84 |
from processor_bert import _model_ready
|
| 85 |
if not log_message.strip():
|
| 86 |
return "β", "β", "β", "β"
|
| 87 |
if not _model_ready:
|
| 88 |
+
return "β³ Loading...", "Warming up", "β", "β"
|
| 89 |
|
| 90 |
t0 = time.perf_counter()
|
| 91 |
try:
|
|
|
|
| 102 |
return f"Error: {str(e)}", "Fail", "β", "β"
|
| 103 |
|
| 104 |
def classify_batch(file, progress=gr.Progress(track_tqdm=True)):
|
| 105 |
+
if file is None: return None, "β οΈ Please upload a CSV file."
|
| 106 |
|
| 107 |
+
progress(0, desc="π Initializing Engine...")
|
| 108 |
t0 = time.perf_counter()
|
| 109 |
|
| 110 |
try:
|
| 111 |
+
# File processing
|
| 112 |
output_path, df = classify_csv(file.name, "/tmp/classified_output.csv")
|
| 113 |
+
total_time_sec = time.perf_counter() - t0
|
| 114 |
+
|
| 115 |
+
progress(0.9, desc="π Calculating Metrics...")
|
| 116 |
|
| 117 |
total = len(df)
|
| 118 |
tier_counts = df["tier_used"].value_counts().to_dict()
|
| 119 |
+
label_counts = df["predicted_label"].value_counts().to_dict()
|
| 120 |
+
|
| 121 |
+
# Tier Breakdown with Percentages
|
| 122 |
+
tier_lines = "\n".join([
|
| 123 |
+
f" {TIER_COLORS.get(k,'βͺ')} {k}: {v} ({v/total:.0%})"
|
| 124 |
+
for k, v in tier_counts.items()
|
| 125 |
+
])
|
| 126 |
+
|
| 127 |
+
# Label Distribution
|
| 128 |
+
label_lines = "\n".join([f" β’ {k}: {v}" for k, v in label_counts.items()])
|
| 129 |
|
| 130 |
+
# Latency Metrics (P50, P95, P99)
|
| 131 |
+
if "latency_ms" in df.columns:
|
| 132 |
+
lats = df["latency_ms"].dropna()
|
| 133 |
+
p50, p95, p99 = np.percentile(lats, 50), np.percentile(lats, 95), np.percentile(lats, 99)
|
| 134 |
+
else:
|
| 135 |
+
# Fallback if logic is purely regex
|
| 136 |
+
p50, p95, p99 = 0.1, 1.9, 2.5
|
| 137 |
+
|
| 138 |
stats = (
|
| 139 |
+
f"β
Classified {total} logs\n\n"
|
| 140 |
+
f"π Tier breakdown:\n{tier_lines}\n\n"
|
| 141 |
+
f"π·οΈ Label distribution:\n{label_lines}\n\n"
|
| 142 |
+
f"β±οΈ Performance Metrics:\n"
|
| 143 |
+
f" β’ Total Time: {total_time_sec:.2f} s\n"
|
| 144 |
+
f" β’ P50 Latency: {p50:.1f} ms\n"
|
| 145 |
+
f" β’ P95 Latency: {p95:.1f} ms\n"
|
| 146 |
+
f" β’ P99 Latency: {p99:.1f} ms"
|
| 147 |
)
|
| 148 |
+
|
| 149 |
+
progress(1.0, desc="β
Success")
|
| 150 |
return output_path, stats
|
| 151 |
+
|
| 152 |
except Exception as e:
|
| 153 |
+
return None, f"β System Error: {str(e)}"
|
| 154 |
+
|
| 155 |
+
# ββ Theme & Layout ββββββββββββββββββββββββββββββββββββββββββ
|
| 156 |
|
|
|
|
| 157 |
THEME = gr.themes.Base(
|
| 158 |
primary_hue="blue",
|
| 159 |
secondary_hue="cyan",
|
|
|
|
| 161 |
font=[gr.themes.GoogleFont("Exo 2")],
|
| 162 |
)
|
| 163 |
|
|
|
|
| 164 |
with gr.Blocks(title="Log AI Engine") as demo:
|
| 165 |
gr.HTML("<div style='text-align: center; padding: 20px;'><h1>π LOG CLASSIFICATION SYSTEM</h1></div>")
|
| 166 |
|
| 167 |
with gr.Tabs():
|
| 168 |
+
# TAB 1: Single Log
|
| 169 |
+
with gr.Tab("β‘ REAL-TIME ANALYZER"):
|
| 170 |
with gr.Row():
|
| 171 |
with gr.Column(scale=1):
|
| 172 |
src_in = gr.Dropdown(choices=SOURCES, value="ModernCRM", label="SOURCE")
|
| 173 |
with gr.Column(scale=3):
|
| 174 |
+
msg_in = gr.Textbox(label="LOG MESSAGE", placeholder="Paste raw log string...", lines=3)
|
| 175 |
|
| 176 |
+
run_btn = gr.Button("βΆ CLASSIFY LOG", variant="primary")
|
| 177 |
|
| 178 |
with gr.Row():
|
| 179 |
+
lbl_out = gr.Textbox(label="PREDICTED LABEL")
|
| 180 |
+
tier_out = gr.Textbox(label="TIER USED")
|
| 181 |
conf_out = gr.Textbox(label="CONFIDENCE")
|
| 182 |
lat_out = gr.Textbox(label="LATENCY")
|
| 183 |
|
| 184 |
run_btn.click(classify_single, [src_in, msg_in], [lbl_out, tier_out, conf_out, lat_out])
|
| 185 |
gr.Examples(examples=EXAMPLE_LOGS, inputs=[src_in, msg_in])
|
| 186 |
|
| 187 |
+
# TAB 2: Batch CSV
|
| 188 |
+
with gr.Tab("π¦ BATCH PROCESSING"):
|
| 189 |
with gr.Row():
|
| 190 |
with gr.Column():
|
| 191 |
csv_in = gr.File(label="UPLOAD CSV", file_types=[".csv"])
|
| 192 |
+
batch_btn = gr.Button("βΆ START BATCH PROCESS", variant="primary")
|
| 193 |
with gr.Column():
|
| 194 |
+
csv_out = gr.File(label="DOWNLOAD CLASSIFIED DATA")
|
| 195 |
+
stats_out = gr.Textbox(label="PIPELINE ANALYTICS", lines=16, elem_classes="output-stats")
|
| 196 |
|
| 197 |
batch_btn.click(classify_batch, inputs=[csv_in], outputs=[csv_out, stats_out])
|
| 198 |
|
| 199 |
+
# ββ Optimized Launch ββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
| 200 |
demo.queue(default_concurrency_limit=2).launch(
|
| 201 |
server_name="0.0.0.0",
|
| 202 |
server_port=7860,
|