MohammedAH's picture
Update app.py
7586586 verified
import gradio as gr
from transformers import pipeline
import re
def anomalies_detector(logs: str) -> str:
"""
Detect anomalies in software logs using a Hugging Face transformer model.
This function uses a specialized model trained to identify unusual patterns
in system logs, such as:
- Error messages
- Unusual system states
- Security-related events
- Performance anomalies
- Unexpected behavior patterns
Args:
logs (str): The input text containing log entries
Returns:
str: Formatted analysis results with detected anomalies
"""
if not logs or not logs.strip():
return "⚠️ No log data provided. Please enter log entries to analyze."
# Initialize the text classification pipeline
classifier = pipeline(
"text-classification",
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english"
)
# Split logs into lines
log_lines = [line for line in logs.split('\n') if line.strip()]
if not log_lines:
return "⚠️ No valid log entries found."
# Process each line
anomalies = []
total_lines = len(log_lines)
negative_count = 0
for line_num, line in enumerate(log_lines, 1):
try:
# Get classification result
result = classifier(line[:512])[0] # Limit to 512 chars for model
# Consider "NEGATIVE" sentiment as potential anomaly
if result['label'] == 'NEGATIVE' and result['score'] > 0.7:
anomalies.append({
'line': line_num,
'text': line,
'confidence': result['score']
})
negative_count += 1
except Exception as e:
continue
# Format output
output = f"📊 **Analysis Summary**\n"
output += f"{'='*60}\n\n"
output += f"📝 Total log entries analyzed: **{total_lines}**\n"
output += f"🔍 Potential anomalies detected: **{negative_count}**\n"
output += f"✅ Health rate: **{((total_lines - negative_count) / total_lines * 100):.1f}%**\n\n"
if anomalies:
output += f"⚠️ **Detected Anomalies:**\n"
output += f"{'-'*60}\n\n"
for idx, anomaly in enumerate(anomalies, 1):
output += f"**#{idx} | Line {anomaly['line']}** (Confidence: {anomaly['confidence']:.2%})\n"
output += f"```\n{anomaly['text']}\n```\n\n"
else:
output += "✨ **No significant anomalies detected!**\n"
output += "Your logs appear to be healthy.\n"
return output
# Custom CSS for dark navy blue and electric blue theme
custom_css = """
:root {
--electric-blue: #00D4FF;
--bright-blue: #0099FF;
--navy-blue: #001F3F;
--dark-navy: #001129;
--deep-navy: #000814;
--white: #FFFFFF;
--off-white: #F8FCFF;
--light-gray: #E8F4F8;
--cyber-glow: rgba(0, 212, 255, 0.3);
}
/* Main background */
.gradio-container {
background: linear-gradient(135deg, var(--deep-navy) 0%, var(--dark-navy) 50%, var(--navy-blue) 100%) !important;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
position: relative !important;
}
.gradio-container::before {
content: '' !important;
position: absolute !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
background: radial-gradient(circle at 20% 50%, rgba(0, 212, 255, 0.08) 0%, transparent 50%),
radial-gradient(circle at 80% 80%, rgba(0, 153, 255, 0.06) 0%, transparent 50%) !important;
pointer-events: none !important;
}
/* Header styling */
.contain {
background: rgba(255, 255, 255, 0.98) !important;
border-radius: 20px !important;
box-shadow: 0 20px 60px rgba(0, 212, 255, 0.2), 0 0 40px rgba(0, 153, 255, 0.1) !important;
padding: 2rem !important;
margin: 2rem auto !important;
max-width: 1400px !important;
border: 1px solid rgba(0, 212, 255, 0.1) !important;
}
/* Title styling */
h1 {
background: linear-gradient(135deg, var(--bright-blue), var(--electric-blue)) !important;
-webkit-background-clip: text !important;
-webkit-text-fill-color: transparent !important;
background-clip: text !important;
font-weight: 800 !important;
font-size: 2.5rem !important;
margin-bottom: 0.5rem !important;
text-align: center !important;
filter: drop-shadow(0 0 20px rgba(0, 212, 255, 0.3)) !important;
}
/* Description text */
.prose p {
color: var(--navy-blue) !important;
font-size: 1.1rem !important;
text-align: center !important;
margin-bottom: 1.5rem !important;
}
/* Input/Output boxes */
.input-text, .output-text, textarea {
border: 2px solid var(--bright-blue) !important;
border-radius: 12px !important;
background: var(--white) !important;
font-family: 'Fira Code', 'Courier New', monospace !important;
font-size: 0.95rem !important;
transition: all 0.3s ease !important;
box-shadow: 0 2px 10px rgba(0, 153, 255, 0.1) !important;
}
.input-text:focus, textarea:focus {
border-color: var(--electric-blue) !important;
box-shadow: 0 0 0 3px var(--cyber-glow), 0 0 20px rgba(0, 212, 255, 0.2) !important;
outline: none !important;
}
/* Labels */
label {
color: var(--navy-blue) !important;
font-weight: 600 !important;
font-size: 1rem !important;
margin-bottom: 0.5rem !important;
}
/* Submit button */
.submit-button, button[id$="-submit-button"] {
background: linear-gradient(135deg, var(--bright-blue), var(--electric-blue)) !important;
color: var(--white) !important;
border: none !important;
border-radius: 12px !important;
padding: 0.75rem 2rem !important;
font-weight: 600 !important;
font-size: 1rem !important;
cursor: pointer !important;
transition: all 0.3s ease !important;
box-shadow: 0 4px 15px rgba(0, 212, 255, 0.3), 0 0 20px rgba(0, 153, 255, 0.2) !important;
}
.submit-button:hover, button[id$="-submit-button"]:hover {
transform: translateY(-2px) !important;
box-shadow: 0 6px 20px rgba(0, 212, 255, 0.4), 0 0 30px rgba(0, 153, 255, 0.3) !important;
filter: brightness(1.1) !important;
}
/* Clear button */
.clear-button, button.secondary {
background: var(--white) !important;
color: var(--navy-blue) !important;
border: 2px solid var(--bright-blue) !important;
border-radius: 12px !important;
padding: 0.75rem 2rem !important;
font-weight: 600 !important;
transition: all 0.3s ease !important;
}
.clear-button:hover, button.secondary:hover {
background: var(--electric-blue) !important;
color: var(--white) !important;
transform: translateY(-2px) !important;
box-shadow: 0 4px 15px rgba(0, 212, 255, 0.3) !important;
}
/* Output markdown styling */
.markdown-text {
background: var(--off-white) !important;
padding: 1.5rem !important;
border-radius: 12px !important;
border-left: 4px solid var(--electric-blue) !important;
box-shadow: 0 2px 10px rgba(0, 153, 255, 0.1) !important;
}
.markdown-text code {
background: var(--white) !important;
padding: 0.2rem 0.4rem !important;
border-radius: 4px !important;
color: var(--navy-blue) !important;
border: 1px solid var(--bright-blue) !important;
}
.markdown-text pre {
background: var(--white) !important;
border: 2px solid var(--bright-blue) !important;
border-radius: 8px !important;
padding: 1rem !important;
box-shadow: inset 0 2px 8px rgba(0, 153, 255, 0.05) !important;
}
/* Footer */
footer {
background: transparent !important;
color: var(--white) !important;
text-align: center !important;
padding: 2rem !important;
text-shadow: 0 0 10px rgba(0, 212, 255, 0.5) !important;
}
footer a {
color: var(--electric-blue) !important;
text-decoration: underline !important;
}
/* Examples section */
.examples {
background: var(--off-white) !important;
border-radius: 12px !important;
padding: 1rem !important;
border: 2px solid var(--bright-blue) !important;
box-shadow: 0 2px 10px rgba(0, 153, 255, 0.1) !important;
}
/* Scrollbar styling */
::-webkit-scrollbar {
width: 10px !important;
}
::-webkit-scrollbar-track {
background: var(--light-gray) !important;
border-radius: 5px !important;
}
::-webkit-scrollbar-thumb {
background: linear-gradient(180deg, var(--electric-blue), var(--bright-blue)) !important;
border-radius: 5px !important;
box-shadow: 0 0 10px rgba(0, 212, 255, 0.3) !important;
}
::-webkit-scrollbar-thumb:hover {
background: var(--electric-blue) !important;
box-shadow: 0 0 15px rgba(0, 212, 255, 0.5) !important;
}
/* Cyber glow effects */
.submit-button::before, button[id$="-submit-button"]::before {
content: '' !important;
position: absolute !important;
top: -2px !important;
left: -2px !important;
right: -2px !important;
bottom: -2px !important;
background: linear-gradient(45deg, var(--electric-blue), var(--bright-blue)) !important;
border-radius: 12px !important;
z-index: -1 !important;
opacity: 0 !important;
transition: opacity 0.3s ease !important;
filter: blur(10px) !important;
}
.submit-button:hover::before, button[id$="-submit-button"]:hover::before {
opacity: 0.7 !important;
}
"""
# Example logs for demonstration
example_logs = [
"""2024-01-29 10:15:23 INFO User logged in successfully
2024-01-29 10:15:45 INFO Database connection established
2024-01-29 10:16:02 ERROR Failed to connect to payment gateway
2024-01-29 10:16:15 WARN Retry attempt 1 of 3
2024-01-29 10:16:30 ERROR Connection timeout after 30 seconds
2024-01-29 10:16:45 CRITICAL Payment service unavailable""",
"""2024-01-29 14:22:10 INFO Application started successfully
2024-01-29 14:22:15 INFO Loading configuration files
2024-01-29 14:22:18 INFO Server listening on port 8080
2024-01-29 14:22:20 INFO Ready to accept connections""",
"""2024-01-29 16:30:45 INFO User authentication request
2024-01-29 16:30:46 WARN Invalid credentials provided
2024-01-29 16:30:50 WARN Login attempt failed for user: admin
2024-01-29 16:30:55 ERROR Multiple failed login attempts detected
2024-01-29 16:31:00 CRITICAL Potential security breach - IP blocked"""
]
# Create the Gradio interface
demo = gr.Interface(
fn=anomalies_detector,
inputs=gr.Textbox(
label="📋 Log Entries",
placeholder="Paste your software logs here (mobile app, desktop, web server, etc.)\n\nExample:\n2024-01-29 10:15:23 INFO User logged in\n2024-01-29 10:16:02 ERROR Connection failed\n2024-01-29 10:16:15 WARN Retry attempt...",
lines=15,
max_lines=25
),
outputs=gr.Markdown(
label="🔍 Analysis Results"
),
title="🛡️ Sentinel Log Analyzer",
description="**Enterprise-grade anomaly detection for all your software logs.** Supports mobile apps, desktop applications, web servers, and more. Powered by advanced AI to identify errors, security events, and unusual patterns in real-time.",
examples=example_logs,
css=custom_css,
theme=gr.themes.Soft(
primary_hue="blue",
secondary_hue="cyan",
),
allow_flagging="never",
analytics_enabled=False
)
# Launch the application
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
share=True,
show_error=True
)