maryangel101 commited on
Commit
9bb08df
Β·
1 Parent(s): f7ac6a3

Add complete anomaly detection workflow with proper error handling

Browse files
.github/scripts/anomaly_detector.py CHANGED
@@ -2,6 +2,7 @@ import os
2
  import requests
3
  import sys
4
  import json
 
5
 
6
  def download_workflow_logs(run_id, token):
7
  """Download logs from a specific workflow run"""
@@ -21,13 +22,29 @@ def download_workflow_logs(run_id, token):
21
  return response.text
22
  else:
23
  print(f"Failed to download logs: {response.status_code}")
 
24
  return None
25
 
26
  def analyze_logs_with_model(log_content, model_url):
27
  """Send logs to the model API for analysis"""
28
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  response = requests.post(
30
- f"{model_url}/predict",
31
  json={
32
  "log_content": log_content,
33
  "include_explanation": True
@@ -38,11 +55,21 @@ def analyze_logs_with_model(log_content, model_url):
38
  if response.status_code == 200:
39
  return response.json()
40
  else:
41
- print(f"Model API error: {response.status_code}")
 
42
  return None
43
 
44
- except requests.RequestException as e:
45
- print(f"Failed to call model API: {e}")
 
 
 
 
 
 
 
 
 
46
  return None
47
 
48
  def main():
@@ -51,34 +78,43 @@ def main():
51
  workflow_run_id = os.environ.get('WORKFLOW_RUN_ID')
52
  model_api_url = os.environ.get('MODEL_API_URL')
53
 
 
 
 
 
 
54
  if not all([github_token, workflow_run_id, model_api_url]):
55
- print("Missing required environment variables")
56
  sys.exit(1)
57
 
58
- print(f"Analyzing workflow run: {workflow_run_id}")
59
 
60
  # Download logs
 
61
  logs = download_workflow_logs(workflow_run_id, github_token)
62
  if not logs:
63
- print("Failed to download logs")
64
  sys.exit(1)
65
 
 
 
66
  # Analyze with model
 
67
  result = analyze_logs_with_model(logs, model_api_url)
68
  if not result:
69
- print("Failed to analyze logs with model")
70
  sys.exit(1)
71
 
72
- print(f"Analysis result: {json.dumps(result, indent=2)}")
73
 
74
  # Check if anomaly detected
75
  if result.get('is_anomaly', False):
76
  print("🚨 ANOMALY DETECTED!")
77
- print(f"Confidence: {result.get('confidence', 0):.2%}")
78
- print(f"Anomaly Probability: {result.get('anomaly_probability', 0):.2%}")
79
 
80
  if result.get('explanation'):
81
- print("Explanation:", result['explanation'])
82
 
83
  # Exit with error code to mark step as failed
84
  sys.exit(1)
 
2
  import requests
3
  import sys
4
  import json
5
+ from urllib.parse import urljoin
6
 
7
  def download_workflow_logs(run_id, token):
8
  """Download logs from a specific workflow run"""
 
22
  return response.text
23
  else:
24
  print(f"Failed to download logs: {response.status_code}")
25
+ print(f"Response: {response.text}")
26
  return None
27
 
28
  def analyze_logs_with_model(log_content, model_url):
29
  """Send logs to the model API for analysis"""
30
  try:
31
+ # Validate and construct the full URL
32
+ if not model_url:
33
+ print("❌ MODEL_API_URL is empty")
34
+ return None
35
+
36
+ # Ensure the URL has a scheme
37
+ if not model_url.startswith(('http://', 'https://')):
38
+ print(f"❌ MODEL_API_URL is missing scheme: {model_url}")
39
+ print("πŸ’‘ Please set MODEL_API_URL to a valid URL starting with http:// or https://")
40
+ return None
41
+
42
+ # Construct the full prediction endpoint URL
43
+ prediction_url = urljoin(model_url.rstrip('/') + '/', 'predict')
44
+ print(f"πŸ”— Calling model API: {prediction_url}")
45
+
46
  response = requests.post(
47
+ prediction_url,
48
  json={
49
  "log_content": log_content,
50
  "include_explanation": True
 
55
  if response.status_code == 200:
56
  return response.json()
57
  else:
58
+ print(f"❌ Model API error: {response.status_code}")
59
+ print(f"Response: {response.text}")
60
  return None
61
 
62
+ except requests.exceptions.Timeout:
63
+ print("❌ Model API request timed out (30 seconds)")
64
+ return None
65
+ except requests.exceptions.ConnectionError:
66
+ print("❌ Failed to connect to Model API - check the URL")
67
+ return None
68
+ except requests.exceptions.RequestException as e:
69
+ print(f"❌ Failed to call model API: {e}")
70
+ return None
71
+ except Exception as e:
72
+ print(f"❌ Unexpected error: {e}")
73
  return None
74
 
75
  def main():
 
78
  workflow_run_id = os.environ.get('WORKFLOW_RUN_ID')
79
  model_api_url = os.environ.get('MODEL_API_URL')
80
 
81
+ print("πŸ” Environment variables check:")
82
+ print(f" GITHUB_TOKEN: {'βœ…' if github_token else '❌'}")
83
+ print(f" WORKFLOW_RUN_ID: {'βœ…' if workflow_run_id else '❌'} -> {workflow_run_id}")
84
+ print(f" MODEL_API_URL: {'βœ…' if model_api_url else '❌'} -> {model_api_url}")
85
+
86
  if not all([github_token, workflow_run_id, model_api_url]):
87
+ print("❌ Missing required environment variables")
88
  sys.exit(1)
89
 
90
+ print(f"πŸ“Š Analyzing workflow run: {workflow_run_id}")
91
 
92
  # Download logs
93
+ print("⬇️ Downloading workflow logs...")
94
  logs = download_workflow_logs(workflow_run_id, github_token)
95
  if not logs:
96
+ print("❌ Failed to download logs")
97
  sys.exit(1)
98
 
99
+ print(f"πŸ“„ Logs downloaded ({len(logs)} characters)")
100
+
101
  # Analyze with model
102
+ print("πŸ€– Sending logs to model API...")
103
  result = analyze_logs_with_model(logs, model_api_url)
104
  if not result:
105
+ print("❌ Failed to analyze logs with model")
106
  sys.exit(1)
107
 
108
+ print(f"πŸ“‹ Analysis result: {json.dumps(result, indent=2)}")
109
 
110
  # Check if anomaly detected
111
  if result.get('is_anomaly', False):
112
  print("🚨 ANOMALY DETECTED!")
113
+ print(f" Confidence: {result.get('confidence', 0):.2%}")
114
+ print(f" Anomaly Probability: {result.get('anomaly_probability', 0):.2%}")
115
 
116
  if result.get('explanation'):
117
+ print(" Explanation:", json.dumps(result['explanation'], indent=2))
118
 
119
  # Exit with error code to mark step as failed
120
  sys.exit(1)
.github/workflows/anomaly-check.yml CHANGED
@@ -1,6 +1,5 @@
1
  name: Anomaly Detection Check
2
 
3
-
4
  permissions:
5
  issues: write
6
  contents: read
@@ -16,7 +15,6 @@ jobs:
16
  runs-on: ubuntu-latest
17
  if: ${{ github.event.workflow_run.conclusion != 'cancelled' }}
18
 
19
-
20
  env:
21
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
22
  WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }}
 
1
  name: Anomaly Detection Check
2
 
 
3
  permissions:
4
  issues: write
5
  contents: read
 
15
  runs-on: ubuntu-latest
16
  if: ${{ github.event.workflow_run.conclusion != 'cancelled' }}
17
 
 
18
  env:
19
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
20
  WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }}