berangerthomas commited on
Commit
844a902
·
1 Parent(s): 5eb9b10

Alert detection correction

Browse files
Files changed (1) hide show
  1. sections/alerts.py +81 -76
sections/alerts.py CHANGED
@@ -11,6 +11,47 @@ if "parsed_df" not in st.session_state or st.session_state.parsed_df is None:
11
  else:
12
  df = st.session_state.parsed_df
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  # Display overall statistics
15
  st.subheader("Overview of logs")
16
  col1, col2, col3 = st.columns(3)
@@ -21,42 +62,27 @@ else:
21
 
22
  with col2:
23
  # Check if the 'level' column exists, otherwise look for a similar column
24
- level_col = None
25
- possible_level_cols = ["level", "severity", "log_level", "type", "status"]
26
- for col in possible_level_cols:
27
- if col in df.columns:
28
- level_col = col
29
- break
30
-
31
- if level_col:
32
- error_count = df[
33
- df[level_col]
34
- .str.upper()
35
- .isin(["ERROR", "CRITICAL", "FATAL", "FAIL", "I"])
36
- ].shape[0]
 
 
37
  error_percent = (
38
  (error_count / total_entries) * 100 if total_entries > 0 else 0
39
  )
40
  st.metric("Error entries", f"{error_count} ({error_percent:.1f}%)")
41
  else:
42
- # Search in the entire log text if no specific column is found
43
- text_col = (
44
- df.select_dtypes(include=["object"]).columns[0]
45
- if not df.select_dtypes(include=["object"]).empty
46
- else None
47
- )
48
- if text_col:
49
- error_count = df[
50
- df[text_col].str.contains(
51
- "ERROR|CRITICAL|FATAL|FAIL|EXCEPTION", case=False, na=False
52
- )
53
- ].shape[0]
54
- error_percent = (
55
- (error_count / total_entries) * 100 if total_entries > 0 else 0
56
- )
57
- st.metric("Error entries", f"{error_count} ({error_percent:.1f}%)")
58
- else:
59
- st.metric("Error entries", "Not detectable")
60
 
61
  with col3:
62
  # Search for a datetime type column
@@ -88,47 +114,20 @@ else:
88
  # Detection of critical errors
89
  st.subheader("Detected critical errors")
90
 
91
- # Function to identify errors by keywords
92
- def detect_errors(dataframe):
93
- # Search in all textual columns
94
- error_patterns = [
95
- "error",
96
- "critical",
97
- "fatal",
98
- "fail",
99
- "exception",
100
- "crash",
101
- "timeout",
102
- ]
103
-
104
- error_df = pd.DataFrame()
105
- for col in dataframe.select_dtypes(include=["object"]).columns:
106
- mask = dataframe[col].str.contains(
107
- "|".join(error_patterns), case=False, na=False
108
- )
109
- if error_df.empty:
110
- error_df = dataframe[mask].copy()
111
- else:
112
- error_df = pd.concat([error_df, dataframe[mask]]).drop_duplicates()
113
-
114
- return error_df
115
-
116
- error_logs = detect_errors(df)
117
-
118
- if not error_logs.empty:
119
- st.write(f"**{len(error_logs)} critical errors detected**")
120
- st.dataframe(error_logs)
121
 
122
  # Extraction of the most common error types
123
- if len(error_logs) > 5:
124
  st.subheader("Frequent error types")
125
  error_types = {}
126
 
127
  # Browse textual columns to extract error patterns
128
- for col in error_logs.select_dtypes(include=["object"]).columns:
129
  for pattern in ["error", "exception", "fail"]:
130
- pattern_errors = error_logs[
131
- error_logs[col].str.contains(pattern, case=False, na=False)
132
  ]
133
  if not pattern_errors.empty:
134
  # Extract error context (words after the pattern)
@@ -149,28 +148,28 @@ else:
149
  sorted_errors = sorted(
150
  error_types.items(), key=lambda x: x[1], reverse=True
151
  )[:10]
152
- error_df = pd.DataFrame(
153
  sorted_errors, columns=["Error type", "Occurrences"]
154
  )
155
- st.dataframe(error_df)
156
 
157
  # Visualization of errors
158
  if timestamp_col:
159
  st.subheader("Temporal distribution of errors")
160
 
161
  # Convert to datetime if necessary
162
- if not pd.api.types.is_datetime64_any_dtype(error_logs[timestamp_col]):
163
  try:
164
- error_logs[timestamp_col] = pd.to_datetime(
165
- error_logs[timestamp_col]
166
  )
167
  except:
168
  pass
169
 
170
- if pd.api.types.is_datetime64_any_dtype(error_logs[timestamp_col]):
171
  # Group by time period
172
  error_count = (
173
- error_logs.groupby(pd.Grouper(key=timestamp_col, freq="1H"))
174
  .size()
175
  .reset_index()
176
  )
@@ -293,7 +292,7 @@ else:
293
  st.error(f"Unable to analyze the temporal distribution of logs: {e}")
294
 
295
  # Detection of suspicious event sequences
296
- if timestamp_col and level_col:
297
  st.subheader("Unusual event sequences")
298
  try:
299
  # Search for consecutive error sequences
@@ -302,7 +301,13 @@ else:
302
 
303
  current_sequence = []
304
  for i, row in df_sorted.iterrows():
305
- if str(row[level_col]).upper() in ["ERROR", "CRITICAL", "FATAL"]:
 
 
 
 
 
 
306
  current_sequence.append(i)
307
  else:
308
  if len(current_sequence) >= 3: # At least 3 consecutive errors
@@ -334,7 +339,7 @@ else:
334
  # Recommendations
335
  st.subheader("Recommendations")
336
 
337
- if not error_logs.empty:
338
  st.warning(
339
  "⚠️ Critical errors have been detected. Review the entries in red for more details."
340
  )
@@ -356,5 +361,5 @@ else:
356
  "⚠️ Sequences of consecutive errors have been detected, which may indicate systemic issues."
357
  )
358
 
359
- if error_logs.empty and ("anomaly_points" not in locals() or anomaly_points.empty):
360
  st.success("✅ No major issues detected in the analyzed logs.")
 
11
  else:
12
  df = st.session_state.parsed_df
13
 
14
+ error_patterns = [
15
+ "error",
16
+ "critical",
17
+ "fatal",
18
+ "fail",
19
+ "exception",
20
+ "crash",
21
+ "timeout",
22
+ ]
23
+
24
+ possible_level_cols = [
25
+ "level",
26
+ "severity",
27
+ "log_level",
28
+ "type",
29
+ "status",
30
+ "content",
31
+ "message",
32
+ ]
33
+
34
+ # Function to identify errors by keywords
35
+ def detect_errors(dataframe, cols_to_search=None):
36
+ if cols_to_search is None:
37
+ # Search in all textual columns
38
+ cols_to_search = dataframe.select_dtypes(include=["object"]).columns
39
+
40
+ # Create a mask for rows containing errors
41
+ error_mask = pd.Series(False, index=dataframe.index)
42
+
43
+ for col in cols_to_search:
44
+ if col in dataframe.columns: # Make sure the column exists
45
+ col_mask = (
46
+ dataframe[col]
47
+ .astype(str)
48
+ .str.contains("|".join(error_patterns), case=False, na=False)
49
+ )
50
+ error_mask = error_mask | col_mask
51
+
52
+ # Return only the rows with errors
53
+ return dataframe[error_mask].copy()
54
+
55
  # Display overall statistics
56
  st.subheader("Overview of logs")
57
  col1, col2, col3 = st.columns(3)
 
62
 
63
  with col2:
64
  # Check if the 'level' column exists, otherwise look for a similar column
65
+ level_cols = None
66
+ level_cols = [
67
+ col
68
+ for col in df.columns
69
+ if any(
70
+ possible_col.lower() == col.lower()
71
+ for possible_col in possible_level_cols
72
+ )
73
+ ]
74
+
75
+ if level_cols:
76
+ # Create a boolean mask for rows containing errors in any relevant column
77
+ error_df = detect_errors(df, level_cols)
78
+ error_count = len(error_df)
79
+
80
  error_percent = (
81
  (error_count / total_entries) * 100 if total_entries > 0 else 0
82
  )
83
  st.metric("Error entries", f"{error_count} ({error_percent:.1f}%)")
84
  else:
85
+ st.metric("Error entries", "Not detectable")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
  with col3:
88
  # Search for a datetime type column
 
114
  # Detection of critical errors
115
  st.subheader("Detected critical errors")
116
 
117
+ if not error_df.empty:
118
+ st.write(f"**{len(error_df)} critical errors detected**")
119
+ st.dataframe(error_df)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
  # Extraction of the most common error types
122
+ if len(error_df) > 5:
123
  st.subheader("Frequent error types")
124
  error_types = {}
125
 
126
  # Browse textual columns to extract error patterns
127
+ for col in error_df.select_dtypes(include=["object"]).columns:
128
  for pattern in ["error", "exception", "fail"]:
129
+ pattern_errors = error_df[
130
+ error_df[col].str.contains(pattern, case=False, na=False)
131
  ]
132
  if not pattern_errors.empty:
133
  # Extract error context (words after the pattern)
 
148
  sorted_errors = sorted(
149
  error_types.items(), key=lambda x: x[1], reverse=True
150
  )[:10]
151
+ error_types_df = pd.DataFrame(
152
  sorted_errors, columns=["Error type", "Occurrences"]
153
  )
154
+ st.dataframe(error_types_df)
155
 
156
  # Visualization of errors
157
  if timestamp_col:
158
  st.subheader("Temporal distribution of errors")
159
 
160
  # Convert to datetime if necessary
161
+ if not pd.api.types.is_datetime64_any_dtype(error_df[timestamp_col]):
162
  try:
163
+ error_df[timestamp_col] = pd.to_datetime(
164
+ error_df[timestamp_col]
165
  )
166
  except:
167
  pass
168
 
169
+ if pd.api.types.is_datetime64_any_dtype(error_df[timestamp_col]):
170
  # Group by time period
171
  error_count = (
172
+ error_df.groupby(pd.Grouper(key=timestamp_col, freq="1h"))
173
  .size()
174
  .reset_index()
175
  )
 
292
  st.error(f"Unable to analyze the temporal distribution of logs: {e}")
293
 
294
  # Detection of suspicious event sequences
295
+ if timestamp_col and level_cols:
296
  st.subheader("Unusual event sequences")
297
  try:
298
  # Search for consecutive error sequences
 
301
 
302
  current_sequence = []
303
  for i, row in df_sorted.iterrows():
304
+ # Check if any of the columns contain error levels
305
+ is_error = False
306
+ for col in level_cols:
307
+ if str(row[col]).upper() in ["ERROR", "CRITICAL", "FATAL"]:
308
+ is_error = True
309
+ break
310
+ if is_error:
311
  current_sequence.append(i)
312
  else:
313
  if len(current_sequence) >= 3: # At least 3 consecutive errors
 
339
  # Recommendations
340
  st.subheader("Recommendations")
341
 
342
+ if not error_df.empty:
343
  st.warning(
344
  "⚠️ Critical errors have been detected. Review the entries in red for more details."
345
  )
 
361
  "⚠️ Sequences of consecutive errors have been detected, which may indicate systemic issues."
362
  )
363
 
364
+ if error_df.empty and ("anomaly_points" not in locals() or anomaly_points.empty):
365
  st.success("✅ No major issues detected in the analyzed logs.")