Spaces:
Sleeping
Sleeping
# --- Imports --- | |
import os | |
import re | |
import gradio as gr | |
import openai | |
from datetime import datetime | |
from bs4 import BeautifulSoup | |
# --- API Keys --- | |
openai_api_key = os.environ.get("OPENAI_API_KEY") | |
if not openai_api_key: | |
raise ValueError("OPENAI_API_KEY environment variable is not set.") | |
client = openai.OpenAI(api_key=openai_api_key) | |
# --- Exadata Specs --- | |
exadata_specs = { | |
"X7": {"Quarter Rack": {"max_iops": 350000, "max_throughput": 25}, | |
"Half Rack": {"max_iops": 700000, "max_throughput": 50}, | |
"Full Rack": {"max_iops": 1400000, "max_throughput": 100}}, | |
"X8": {"Quarter Rack": {"max_iops": 380000, "max_throughput": 28}, | |
"Half Rack": {"max_iops": 760000, "max_throughput": 56}, | |
"Full Rack": {"max_iops": 1520000, "max_throughput": 112}}, | |
"X9": {"Quarter Rack": {"max_iops": 450000, "max_throughput": 30}, | |
"Half Rack": {"max_iops": 900000, "max_throughput": 60}, | |
"Full Rack": {"max_iops": 1800000, "max_throughput": 120}}, | |
"X10": {"Quarter Rack": {"max_iops": 500000, "max_throughput": 35}, | |
"Half Rack": {"max_iops": 1000000, "max_throughput": 70}, | |
"Full Rack": {"max_iops": 2000000, "max_throughput": 140}}, | |
"X11M": {"Quarter Rack": {"max_iops": 600000, "max_throughput": 40}, | |
"Half Rack": {"max_iops": 1200000, "max_throughput": 80}, | |
"Full Rack": {"max_iops": 2400000, "max_throughput": 160}}, | |
} | |
# --- Preprocessor --- | |
def clean_awr_content(content): | |
if "<html" in content.lower(): | |
soup = BeautifulSoup(content, "html.parser") | |
text = soup.get_text() | |
else: | |
text = content | |
cleaned = "\n".join([line.strip() for line in text.splitlines() if line.strip()]) | |
return cleaned | |
# --- Agent Classes --- | |
SYSTEM_PROMPT = """ | |
You are an expert Oracle Exadata and RAC performance consultant. | |
Prioritize CRITICAL SYSTEM HEALTH issues first. Provide DBA-level observations and recommendations. | |
""" | |
class HealthRiskAgent: | |
def __init__(self, model="gpt-4o"): | |
self.model = model | |
def analyze(self, data): | |
prompt = f""" | |
======== BEGIN DATA ======== | |
{data} | |
======== END DATA ======== | |
Identify CRITICAL SYSTEM HEALTH issues (Flash Cache degraded, Confined Disks, Redo Stress, RAC GC waits, IO Errors). | |
If issues found, output "⚠️ CRITICAL ALERTS DETECTED" + Explanation + DBA Actions. | |
If clean, output "✅ None Detected". | |
""" | |
response = client.chat.completions.create( | |
model=self.model, | |
messages=[ | |
{"role": "system", "content": SYSTEM_PROMPT}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return response.choices[0].message.content.strip() | |
class PerformanceAnalyzerAgent: | |
def __init__(self, model="gpt-4o"): | |
self.model = model | |
def analyze(self, data, exadata_model=None, rack_size=None): | |
prompt = f""" | |
======== BEGIN DATA ======== | |
{data} | |
======== END DATA ======== | |
Please provide: | |
- Performance Summary | |
- Detailed Bottleneck Analysis | |
- Forecast / Predictions | |
- Monitoring Suggestions | |
- Exadata Stats Summary | |
- Recommended Next Steps | |
If this is a performance test: | |
- Compare observed vs theoretical for Exadata | |
- Recommend gap-closing actions. | |
""" | |
if exadata_model and rack_size: | |
specs = exadata_specs.get(exadata_model, {}).get(rack_size, {}) | |
if specs: | |
prompt += f""" | |
Theoretical Max for Oracle Exadata {exadata_model} {rack_size}: | |
- Max IOPS: {specs['max_iops']} | |
- Max Throughput: {specs['max_throughput']} GB/s | |
""" | |
response = client.chat.completions.create( | |
model=self.model, | |
messages=[ | |
{"role": "system", "content": SYSTEM_PROMPT}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return response.choices[0].message.content.strip() | |
class AWRAgentCoordinator: | |
def __init__(self): | |
self.health_agent = HealthRiskAgent() | |
self.performance_agent = PerformanceAnalyzerAgent() | |
def analyze(self, awr_data, exadata_model=None, rack_size=None): | |
# Run both agents | |
health_result = self.health_agent.analyze(awr_data) | |
perf_result = self.performance_agent.analyze(awr_data, exadata_model, rack_size) | |
return health_result, perf_result | |
# --- Gradio UI --- | |
agent = AWRAgentCoordinator() | |
with gr.Blocks() as demo: | |
gr.Markdown("# 📊 Exadata + RAC AWR Analyzer (Multi-Agent View)") | |
awr_text = gr.Textbox(label="Paste AWR Report (HTML or TXT)", lines=30, placeholder="Paste AWR report here...") | |
performance_test_mode = gr.Checkbox(label="Performance Test Mode") | |
exadata_model = gr.Dropdown(choices=["X7", "X8", "X9", "X10", "X11M"], label="Exadata Model", visible=False) | |
rack_size = gr.Dropdown(choices=["Quarter Rack", "Half Rack", "Full Rack"], label="Rack Size", visible=False) | |
def toggle_visibility(mode): | |
return gr.update(visible=mode), gr.update(visible=mode) | |
performance_test_mode.change(toggle_visibility, inputs=performance_test_mode, outputs=[exadata_model, rack_size]) | |
analyze_btn = gr.Button("Analyze AWR Report") | |
with gr.Row(): | |
health_output = gr.Textbox(label="Health Risk Agent (Critical Alerts + Actions)", lines=20) | |
performance_output = gr.Textbox(label="Performance Analyzer Agent (Full Analysis)", lines=20) | |
def run_analysis(awr_text, performance_test_mode, exadata_model, rack_size): | |
if not awr_text.strip(): | |
return "❗ Please paste the AWR report first.", "" | |
cleaned = clean_awr_content(awr_text) | |
if performance_test_mode: | |
health, perf = agent.analyze(cleaned, exadata_model, rack_size) | |
else: | |
health, perf = agent.analyze(cleaned) | |
return health, perf | |
analyze_btn.click(run_analysis, inputs=[awr_text, performance_test_mode, exadata_model, rack_size], | |
outputs=[health_output, performance_output]) | |
demo.launch(debug=True) | |