kgauvin603 commited on
Commit
657d516
·
verified ·
1 Parent(s): e42c296

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +177 -0
app.py ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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}, "Half Rack": {"max_iops": 700000, "max_throughput": 50}, "Full Rack": {"max_iops": 1400000, "max_throughput": 100}},
19
+ "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}},
20
+ "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}},
21
+ "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}},
22
+ "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}},
23
+ }
24
+
25
+ # --- Utils ---
26
+ def clean_awr_content(content):
27
+ if "<html" in content.lower():
28
+ soup = BeautifulSoup(content, "html.parser")
29
+ return soup.get_text()
30
+ return content
31
+
32
+ # === AGENTS ===
33
+
34
+ class CriticalAnalyzerAgent:
35
+ def analyze(self, content, performance_test_mode, exadata_model, rack_size):
36
+ cleaned_content = clean_awr_content(content)
37
+ if len(cleaned_content) > 128000:
38
+ cleaned_content = cleaned_content[:128000] + "\n\n[TRUNCATED]..."
39
+
40
+ prompt = f"""
41
+ You are an expert Oracle DBA performance analyst specialized in AWR + Exadata.
42
+
43
+ Please perform advanced analysis on the following report:
44
+
45
+ ======== AWR REPORT START ========
46
+ {cleaned_content}
47
+ ======== AWR REPORT END ========
48
+
49
+ Required Output:
50
+ - Performance Summary (with metric values)
51
+ - Detailed Bottlenecks + Risks (quantified)
52
+ - Forecast + Predictions
53
+ - Monitoring Recommendations
54
+ - Exadata Statistics (IO, Flash Cache, Smart Scan)
55
+ - Recommended Next Steps to Bridge Gaps
56
+ """
57
+
58
+ if performance_test_mode and exadata_model and rack_size:
59
+ specs = exadata_specs.get(exadata_model, {}).get(rack_size, {})
60
+ if specs:
61
+ prompt += f"""
62
+
63
+ This was a PERFORMANCE TEST on Oracle Exadata {exadata_model} {rack_size}.
64
+ Theoretical Max:
65
+ - IOPS: {specs['max_iops']}
66
+ - Throughput: {specs['max_throughput']} GB/s
67
+
68
+ Compare observed vs theoretical. Recommend actions to close the performance gap.
69
+ """
70
+
71
+ response = client.chat.completions.create(
72
+ model="gpt-4-turbo",
73
+ messages=[
74
+ {"role": "system", "content": "You are an expert Oracle DBA."},
75
+ {"role": "user", "content": prompt}
76
+ ]
77
+ )
78
+
79
+ return response.choices[0].message.content.strip()
80
+
81
+ class HealthAgent:
82
+ def check_health(self, content):
83
+ cleaned_content = clean_awr_content(content)
84
+ if len(cleaned_content) > 128000:
85
+ cleaned_content = cleaned_content[:128000] + "\n\n[TRUNCATED]..."
86
+
87
+ prompt = f"""
88
+ You are a health diagnostic agent for Oracle AWR reports.
89
+
90
+ Please detect CRITICAL and SEVERE problems. Examples include:
91
+ - Flash device failures or zero hit rates
92
+ - ORA-12170 or interconnect stalls
93
+ - Very high gc buffer busy waits
94
+ - IO stalls / disk saturation
95
+ - Redo log sync slowdowns
96
+
97
+ Categorize issues as:
98
+ - 🚨 Critical
99
+ - ⚠️ Warning
100
+ - ✅ Healthy
101
+
102
+ AWR CONTENT:
103
+ {cleaned_content}
104
+ """
105
+
106
+ response = client.chat.completions.create(
107
+ model="gpt-4-turbo",
108
+ messages=[
109
+ {"role": "system", "content": "You are an Oracle AWR health check agent."},
110
+ {"role": "user", "content": prompt}
111
+ ]
112
+ )
113
+
114
+ return response.choices[0].message.content.strip()
115
+
116
+ class RaterAgent:
117
+ def rate(self, content):
118
+ prompt = f"Rate the following analysis from 1-5 stars and explain:\n\n{content}"
119
+ response = client.chat.completions.create(
120
+ model="gpt-4-turbo",
121
+ messages=[{"role": "user", "content": prompt}]
122
+ )
123
+ return response.choices[0].message.content.strip()
124
+
125
+ # === Main Process ===
126
+ def process_awr(awr_text, threshold, performance_test_mode, exadata_model, rack_size):
127
+ analyzer = CriticalAnalyzerAgent()
128
+ health = HealthAgent()
129
+ rater = RaterAgent()
130
+
131
+ if not awr_text.strip():
132
+ return "No AWR text provided", "", ""
133
+
134
+ analysis = analyzer.analyze(awr_text, performance_test_mode, exadata_model, rack_size)
135
+ health_status = health.check_health(awr_text)
136
+ rating_text = rater.rate(analysis)
137
+
138
+ stars = 0
139
+ match = re.search(r"(\d+)", rating_text)
140
+ if match:
141
+ stars = int(match.group(1))
142
+
143
+ retry_status = "✅ Accepted"
144
+
145
+ if stars < threshold:
146
+ analysis_retry = analyzer.analyze(awr_text, performance_test_mode, exadata_model, rack_size)
147
+ rating_text_retry = rater.rate(analysis_retry)
148
+ retry_status = "✅ Retry Occurred"
149
+ analysis = analysis_retry
150
+ rating_text = rating_text_retry
151
+
152
+ return analysis, health_status, rating_text, retry_status
153
+
154
+ # === Gradio UI ===
155
+ with gr.Blocks() as demo:
156
+ gr.Markdown("# 🧠 Multi-Agent Oracle AWR Analyzer (Production Edition)")
157
+
158
+ awr_text = gr.Textbox(label="Paste AWR Report", lines=30)
159
+ threshold = gr.Slider(0, 5, value=3, step=1, label="Correctness Threshold (Stars)")
160
+ performance_test_mode = gr.Checkbox(label="Performance Test Mode")
161
+ exadata_model = gr.Dropdown(choices=list(exadata_specs.keys()), label="Exadata Model", visible=False)
162
+ rack_size = gr.Dropdown(choices=["Quarter Rack", "Half Rack", "Full Rack"], label="Rack Size", visible=False)
163
+
164
+ def toggle_visibility(mode):
165
+ return gr.update(visible=mode), gr.update(visible=mode)
166
+
167
+ performance_test_mode.change(toggle_visibility, inputs=performance_test_mode, outputs=[exadata_model, rack_size])
168
+
169
+ analyze_btn = gr.Button("Analyze AWR Report")
170
+ output = gr.Textbox(label="AWR Analysis", lines=20)
171
+ health = gr.Textbox(label="Health Agent Findings", lines=5)
172
+ rating = gr.Textbox(label="Rater", lines=3)
173
+ retry_status = gr.Textbox(label="Retry Status")
174
+
175
+ analyze_btn.click(process_awr, inputs=[awr_text, threshold, performance_test_mode, exadata_model, rack_size], outputs=[output, health, rating, retry_status])
176
+
177
+ demo.launch(debug=True)