Spaces:
Sleeping
Sleeping
File size: 6,020 Bytes
f0845ba |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# --- 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)
|