File size: 9,201 Bytes
4e128c5
 
 
 
 
 
6e51123
4e128c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
674cfb0
 
 
 
 
 
 
d2b9004
4e128c5
674cfb0
 
 
 
 
4e128c5
d2b9004
4e128c5
 
d2b9004
674cfb0
 
 
 
 
 
 
 
 
 
 
 
4e128c5
 
 
 
 
 
 
 
 
 
 
 
d2b9004
6e51123
4e128c5
 
 
 
 
6e51123
4e128c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6e51123
4e128c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6e51123
 
4e128c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
import streamlit as st
import requests
import json
from datetime import datetime, timedelta
import pandas as pd
import time
from utils import ZabbixAPI, OllamaAnalysis
from config import ZABBIX_API_URL, OLLAMA_API_URL

# Set page config
st.set_page_config(
    page_title="Zabbix Event Analyzer",
    page_icon="๐Ÿ“Š",
    layout="wide",
    initial_sidebar_state="expanded"
)

# Custom CSS
st.markdown("""
<style>
    .main-header {
        font-size: 2.5rem;
        font-weight: bold;
        color: #1f77b4;
        text-align: center;
        margin-bottom: 1rem;
    }
    .sub-header {
        font-size: 1.2rem;
        color: #666;
        text-align: center;
        margin-bottom: 2rem;
    }
    .analysis-card {
        border: 1px solid #ddd;
        border-radius: 5px;
        padding: 15px;
        margin-bottom: 15px;
        background-color: #f9f9f9;
    }
    .built-with {
        position: fixed;
        bottom: 10px;
        right: 10px;
        font-size: 0.8rem;
        color: #666;
    }
</style>
""", unsafe_allow_html=True)

# Header
st.markdown('<div class="main-header">Zabbix Event Analyzer</div>', unsafe_allow_html=True)
st.markdown('<div class="sub-header">Analyze Zabbix events with AI-powered insights</div>', unsafe_allow_html=True)

# Built with anycoder link
st.markdown('<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">Built with anycoder</a>', unsafe_allow_html=True)

# Initialize session state
if 'zabbix_auth_token' not in st.session_state:
    st.session_state.zabbix_auth_token = None
if 'events_data' not in st.session_state:
    st.session_state.events_data = None
if 'analysis_results' not in st.session_state:
    st.session_state.analysis_results = None

# Sidebar
with st.sidebar:
    st.header("Configuration")

    # Authentication method selection
    auth_method = st.radio(
        "Authentication Method",
        ["Username/Password", "API Token"],
        index=0
    )

    # Zabbix API Configuration - simplified to just connect button
    with st.expander("Zabbix API Settings", expanded=True):
        if auth_method == "Username/Password":
            zabbix_user = st.text_input("Username", value="Admin")
            zabbix_password = st.text_input("Password", type="password")
        else:
            zabbix_token = st.text_input("API Token", type="password")

        if st.button("ะŸะพะดะบะปัŽั‡ะธั‚ัŒัั"):
            with st.spinner("Connecting to Zabbix..."):
                try:
                    zabbix = ZabbixAPI(ZABBIX_API_URL)

                    if auth_method == "Username/Password":
                        auth_token = zabbix.authenticate(zabbix_user, zabbix_password)
                    else:
                        # For API token authentication, we'll validate it by making a simple API call
                        auth_token = zabbix_token
                        # Test the token by making a simple API call
                        test_result = zabbix.test_token_auth(auth_token)
                        if not test_result:
                            st.error("Invalid API token")
                            auth_token = None

                    if auth_token:
                        st.session_state.zabbix_auth_token = auth_token
                        st.success("Successfully connected to Zabbix!")
                    else:
                        st.error("Failed to authenticate with Zabbix")
                except Exception as e:
                    st.error(f"Connection error: {str(e)}")

    # Event Filtering
    with st.expander("Event Filters", expanded=True):
        if st.session_state.zabbix_auth_token:
            # Get host groups
            zabbix = ZabbixAPI(ZABBIX_API_URL)
            host_groups = zabbix.get_host_groups(st.session_state.zabbix_auth_token)
            selected_group = st.selectbox("Host Group", [""] + [g['name'] for g in host_groups])

            # Get hosts based on selected group
            hosts = []
            if selected_group:
                hosts = zabbix.get_hosts_by_group(st.session_state.zabbix_auth_token, selected_group)
            selected_host = st.selectbox("Host", [""] + [h['name'] for h in hosts])

            # Time range
            time_range = st.select_slider(
                "Time Range (hours)",
                options=[1, 6, 12, 24, 48, 72, 168],
                value=24
            )

            # Event severity
            severity_options = {
                "Not classified": -1,
                "Information": 0,
                "Warning": 1,
                "Average": 2,
                "High": 3,
                "Disaster": 4
            }
            selected_severities = st.multiselect(
                "Severity Levels",
                options=list(severity_options.keys()),
                default=["Warning", "Average", "High", "Disaster"]
            )

            if st.button("Fetch Events"):
                with st.spinner("Fetching events from Zabbix..."):
                    try:
                        end_time = int(time.time())
                        start_time = end_time - (time_range * 3600)

                        events = zabbix.get_events(
                            st.session_state.zabbix_auth_token,
                            start_time,
                            end_time,
                            [severity_options[s] for s in selected_severities],
                            selected_host
                        )

                        if events:
                            st.session_state.events_data = events
                            st.success(f"Fetched {len(events)} events")
                        else:
                            st.warning("No events found matching the criteria")
                    except Exception as e:
                        st.error(f"Error fetching events: {str(e)}")
        else:
            st.warning("Please connect to Zabbix first")

    # Ollama Configuration
    with st.expander("Ollama Settings", expanded=True):
        ollama_url = st.text_input("Ollama API URL", value=OLLAMA_API_URL)
        model_name = st.selectbox(
            "Analysis Model",
            ["llama3", "mistral", "gemma", "phi3"],
            index=0
        )

# Main content
if st.session_state.events_data:
    st.header("Event Analysis")

    # Display events
    with st.expander("Raw Events Data", expanded=False):
        events_df = pd.DataFrame(st.session_state.events_data)
        st.dataframe(events_df, use_container_width=True)

    # Analyze events
    if st.button("Analyze Events with Ollama"):
        with st.spinner("Analyzing events with Ollama..."):
            try:
                # Prepare event summaries for analysis
                event_summaries = []
                for event in st.session_state.events_data[:10]:  # Limit to 10 events for demo
                    summary = (
                        f"Event: {event.get('name', 'N/A')}\n"
                        f"Host: {event.get('host', 'N/A')}\n"
                        f"Severity: {event.get('severity', 'N/A')}\n"
                        f"Time: {datetime.fromtimestamp(int(event.get('clock', 0))).strftime('%Y-%m-%d %H:%M:%S')}\n"
                        f"Status: {event.get('value', 'N/A')}\n"
                        f"Description: {event.get('description', 'N/A')}"
                    )
                    event_summaries.append(summary)

                # Combine all events into a single prompt
                prompt = (
                    "Analyze the following Zabbix monitoring events and provide:\n"
                    "1. A summary of the overall system health\n"
                    "2. Identification of any patterns or recurring issues\n"
                    "3. Recommendations for resolution or investigation\n\n"
                    "Events:\n" + "\n\n".join(event_summaries)
                )

                # Get analysis from Ollama
                ollama = OllamaAnalysis(ollama_url)
                analysis = ollama.get_analysis(model_name, prompt)

                if analysis:
                    st.session_state.analysis_results = analysis
                else:
                    st.error("Failed to get analysis from Ollama")

            except Exception as e:
                st.error(f"Analysis error: {str(e)}")

    # Display analysis results
    if st.session_state.analysis_results:
        st.subheader("Analysis Results")

        # Display in a nice card format
        st.markdown(f"""
        <div class="analysis-card">
            <h3>๐Ÿ“Š System Health Summary</h3>
            <p>{st.session_state.analysis_results}</p>
        </div>
        """, unsafe_allow_html=True)

        # Download button for analysis
        st.download_button(
            label="Download Analysis",
            data=st.session_state.analysis_results,
            file_name=f"zabbix_analysis_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt",
            mime="text/plain"
        )
else:
    if st.session_state.zabbix_auth_token:
        st.info("Connect to Zabbix and fetch events to begin analysis")
    else:
        st.info("Please configure and connect to Zabbix to begin")