kgauvin603 commited on
Commit
f0845ba
·
verified ·
1 Parent(s): e91f3e3

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +168 -0
app.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # --- Imports ---
2
+ import os
3
+ import re
4
+ import gradio as gr
5
+ import openai
6
+ from datetime import datetime
7
+ from bs4 import BeautifulSoup
8
+
9
+ # --- API Keys ---
10
+ openai_api_key = os.environ.get("OPENAI_API_KEY")
11
+ if not openai_api_key:
12
+ raise ValueError("OPENAI_API_KEY environment variable is not set.")
13
+
14
+ client = openai.OpenAI(api_key=openai_api_key)
15
+
16
+ # --- Exadata Specs ---
17
+ exadata_specs = {
18
+ "X7": {"Quarter Rack": {"max_iops": 350000, "max_throughput": 25},
19
+ "Half Rack": {"max_iops": 700000, "max_throughput": 50},
20
+ "Full Rack": {"max_iops": 1400000, "max_throughput": 100}},
21
+ "X8": {"Quarter Rack": {"max_iops": 380000, "max_throughput": 28},
22
+ "Half Rack": {"max_iops": 760000, "max_throughput": 56},
23
+ "Full Rack": {"max_iops": 1520000, "max_throughput": 112}},
24
+ "X9": {"Quarter Rack": {"max_iops": 450000, "max_throughput": 30},
25
+ "Half Rack": {"max_iops": 900000, "max_throughput": 60},
26
+ "Full Rack": {"max_iops": 1800000, "max_throughput": 120}},
27
+ "X10": {"Quarter Rack": {"max_iops": 500000, "max_throughput": 35},
28
+ "Half Rack": {"max_iops": 1000000, "max_throughput": 70},
29
+ "Full Rack": {"max_iops": 2000000, "max_throughput": 140}},
30
+ "X11M": {"Quarter Rack": {"max_iops": 600000, "max_throughput": 40},
31
+ "Half Rack": {"max_iops": 1200000, "max_throughput": 80},
32
+ "Full Rack": {"max_iops": 2400000, "max_throughput": 160}},
33
+ }
34
+
35
+ # --- Preprocessor ---
36
+ def clean_awr_content(content):
37
+ if "<html" in content.lower():
38
+ soup = BeautifulSoup(content, "html.parser")
39
+ text = soup.get_text()
40
+ else:
41
+ text = content
42
+ cleaned = "\n".join([line.strip() for line in text.splitlines() if line.strip()])
43
+ return cleaned
44
+
45
+
46
+ # --- Agent Classes ---
47
+
48
+ SYSTEM_PROMPT = """
49
+ You are an expert Oracle Exadata and RAC performance consultant.
50
+ Prioritize CRITICAL SYSTEM HEALTH issues first. Provide DBA-level observations and recommendations.
51
+ """
52
+
53
+ class HealthRiskAgent:
54
+ def __init__(self, model="gpt-4o"):
55
+ self.model = model
56
+
57
+ def analyze(self, data):
58
+ prompt = f"""
59
+ ======== BEGIN DATA ========
60
+ {data}
61
+ ======== END DATA ========
62
+
63
+ Identify CRITICAL SYSTEM HEALTH issues (Flash Cache degraded, Confined Disks, Redo Stress, RAC GC waits, IO Errors).
64
+ If issues found, output "⚠️ CRITICAL ALERTS DETECTED" + Explanation + DBA Actions.
65
+ If clean, output "✅ None Detected".
66
+ """
67
+ response = client.chat.completions.create(
68
+ model=self.model,
69
+ messages=[
70
+ {"role": "system", "content": SYSTEM_PROMPT},
71
+ {"role": "user", "content": prompt}
72
+ ]
73
+ )
74
+ return response.choices[0].message.content.strip()
75
+
76
+
77
+ class PerformanceAnalyzerAgent:
78
+ def __init__(self, model="gpt-4o"):
79
+ self.model = model
80
+
81
+ def analyze(self, data, exadata_model=None, rack_size=None):
82
+ prompt = f"""
83
+ ======== BEGIN DATA ========
84
+ {data}
85
+ ======== END DATA ========
86
+
87
+ Please provide:
88
+ - Performance Summary
89
+ - Detailed Bottleneck Analysis
90
+ - Forecast / Predictions
91
+ - Monitoring Suggestions
92
+ - Exadata Stats Summary
93
+ - Recommended Next Steps
94
+
95
+ If this is a performance test:
96
+ - Compare observed vs theoretical for Exadata
97
+ - Recommend gap-closing actions.
98
+ """
99
+ if exadata_model and rack_size:
100
+ specs = exadata_specs.get(exadata_model, {}).get(rack_size, {})
101
+ if specs:
102
+ prompt += f"""
103
+ Theoretical Max for Oracle Exadata {exadata_model} {rack_size}:
104
+ - Max IOPS: {specs['max_iops']}
105
+ - Max Throughput: {specs['max_throughput']} GB/s
106
+ """
107
+ response = client.chat.completions.create(
108
+ model=self.model,
109
+ messages=[
110
+ {"role": "system", "content": SYSTEM_PROMPT},
111
+ {"role": "user", "content": prompt}
112
+ ]
113
+ )
114
+ return response.choices[0].message.content.strip()
115
+
116
+
117
+ class AWRAgentCoordinator:
118
+ def __init__(self):
119
+ self.health_agent = HealthRiskAgent()
120
+ self.performance_agent = PerformanceAnalyzerAgent()
121
+
122
+ def analyze(self, awr_data, exadata_model=None, rack_size=None):
123
+ # Run both agents
124
+ health_result = self.health_agent.analyze(awr_data)
125
+ perf_result = self.performance_agent.analyze(awr_data, exadata_model, rack_size)
126
+
127
+ return health_result, perf_result
128
+
129
+
130
+ # --- Gradio UI ---
131
+ agent = AWRAgentCoordinator()
132
+
133
+ with gr.Blocks() as demo:
134
+ gr.Markdown("# 📊 Exadata + RAC AWR Analyzer (Multi-Agent View)")
135
+
136
+ awr_text = gr.Textbox(label="Paste AWR Report (HTML or TXT)", lines=30, placeholder="Paste AWR report here...")
137
+ performance_test_mode = gr.Checkbox(label="Performance Test Mode")
138
+ exadata_model = gr.Dropdown(choices=["X7", "X8", "X9", "X10", "X11M"], label="Exadata Model", visible=False)
139
+ rack_size = gr.Dropdown(choices=["Quarter Rack", "Half Rack", "Full Rack"], label="Rack Size", visible=False)
140
+
141
+ def toggle_visibility(mode):
142
+ return gr.update(visible=mode), gr.update(visible=mode)
143
+
144
+ performance_test_mode.change(toggle_visibility, inputs=performance_test_mode, outputs=[exadata_model, rack_size])
145
+
146
+ analyze_btn = gr.Button("Analyze AWR Report")
147
+
148
+ with gr.Row():
149
+ health_output = gr.Textbox(label="Health Risk Agent (Critical Alerts + Actions)", lines=20)
150
+ performance_output = gr.Textbox(label="Performance Analyzer Agent (Full Analysis)", lines=20)
151
+
152
+ def run_analysis(awr_text, performance_test_mode, exadata_model, rack_size):
153
+ if not awr_text.strip():
154
+ return "❗ Please paste the AWR report first.", ""
155
+
156
+ cleaned = clean_awr_content(awr_text)
157
+
158
+ if performance_test_mode:
159
+ health, perf = agent.analyze(cleaned, exadata_model, rack_size)
160
+ else:
161
+ health, perf = agent.analyze(cleaned)
162
+
163
+ return health, perf
164
+
165
+ analyze_btn.click(run_analysis, inputs=[awr_text, performance_test_mode, exadata_model, rack_size],
166
+ outputs=[health_output, performance_output])
167
+
168
+ demo.launch(debug=True)