Skip to content

Commit 9d4452b

Browse files
committed
fix: Update Bugsink patches for v2.0.12+ compatibility
- Refactor patch_template.py to verify modern template architecture instead of patching. - Update patch_views.py to verify dynamic form loading architecture instead of patching. - Modify register_backends.py to reflect new backend registration process for Bugsink v2.x. - Add documentation for new notification backends including Jira Cloud, GitHub Issues, Microsoft Teams, PagerDuty, and Generic Webhook.
1 parent e39dacc commit 9d4452b

File tree

11 files changed

+1032
-1311
lines changed

11 files changed

+1032
-1311
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,10 @@
66
# Environment files
77
.env
88

9+
# Python
10+
__pycache__/
11+
*.py[cod]
12+
*.pyo
13+
*.pyd
14+
*.pyc
15+
*.pdb

docs/NOTIFICATION_BACKENDS.md

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
# Extended Notification Backends for Bugsink
2+
3+
This document describes the additional notification backends contributed to Bugsink, enabling integration with enterprise issue tracking systems, incident management platforms, and generic webhook endpoints.
4+
5+
## Overview
6+
7+
This contribution adds **5 new notification backends** to Bugsink's alert system:
8+
9+
| Backend | Service | Use Case |
10+
|---------|---------|----------|
11+
| `jira_cloud` | Jira Cloud | Automatic bug ticket creation in Atlassian Jira |
12+
| `github_issues` | GitHub Issues | Automatic issue creation in GitHub repositories |
13+
| `microsoft_teams` | Microsoft Teams | Alert notifications via Teams webhooks |
14+
| `pagerduty` | PagerDuty | Incident management and on-call alerting |
15+
| `webhook` | Generic Webhook | Custom integrations via HTTP endpoints |
16+
17+
## Architecture
18+
19+
All backends follow Bugsink's existing backend architecture pattern:
20+
21+
```
22+
alerts/service_backends/
23+
├── __init__.py
24+
├── slack.py # Existing
25+
├── mattermost.py # Existing
26+
├── discord.py # Existing
27+
├── jira_cloud.py # NEW
28+
├── github_issues.py # NEW
29+
├── microsoft_teams.py # NEW
30+
├── pagerduty.py # NEW
31+
└── webhook.py # NEW
32+
```
33+
34+
Each backend provides:
35+
- A `ConfigForm` class (Django Form) for user configuration
36+
- A `Backend` class implementing `send_test_message()` and `send_alert()`
37+
- Async task functions using `@shared_task` for non-blocking message delivery
38+
- Failure tracking integration with `MessagingServiceConfig`
39+
40+
## Backend Details
41+
42+
### 1. Jira Cloud (`jira_cloud`)
43+
44+
Creates bug tickets in Jira Cloud when Bugsink detects issues.
45+
46+
**Configuration Fields:**
47+
- `jira_url` - Jira Cloud URL (e.g., `https://your-domain.atlassian.net`)
48+
- `user_email` - Email associated with the API token
49+
- `api_token` - Jira API token ([create here](https://id.atlassian.com/manage-profile/security/api-tokens))
50+
- `project_key` - Target project key (e.g., `BUG`, `PROJ`)
51+
- `issue_type` - Issue type to create (Bug, Task, Story, etc.)
52+
- `labels` - Comma-separated labels to apply
53+
- `only_new_issues` - Create tickets only for NEW issues (prevents duplicates)
54+
55+
**Features:**
56+
- Uses Atlassian Document Format (ADF) for rich descriptions
57+
- Includes direct links to Bugsink issues
58+
- Supports all standard Jira issue types
59+
- Deduplication option to avoid ticket spam
60+
61+
**Setup:**
62+
63+
1. Go to [Atlassian API Tokens](https://id.atlassian.com/manage-profile/security/api-tokens)
64+
2. Click "Create API token"
65+
3. Give it a label (e.g., "Bugsink Integration")
66+
4. Copy the generated token (you won't see it again)
67+
5. Use your Atlassian account email as the "User Email" in Bugsink
68+
69+
### 2. GitHub Issues (`github_issues`)
70+
71+
Creates issues in GitHub repositories when errors occur.
72+
73+
**Configuration Fields:**
74+
- `repository` - Repository in `owner/repo` format
75+
- `access_token` - GitHub Personal Access Token with `issues:write` scope
76+
- `labels` - Comma-separated labels (e.g., `bug,production`)
77+
- `assignees` - Comma-separated GitHub usernames to assign
78+
- `only_new_issues` - Create issues only for NEW errors
79+
80+
**Features:**
81+
- GitHub-flavored Markdown formatting
82+
- Automatic label and assignee assignment
83+
- Direct links to Bugsink issues
84+
- Works with both classic and fine-grained tokens
85+
86+
**Setup (Classic Token):**
87+
88+
1. Go to [GitHub Personal Access Tokens](https://github.com/settings/tokens)
89+
2. Click "Generate new token (classic)"
90+
3. Select scope: `repo` (for private repos) or `public_repo` (for public repos)
91+
4. Generate and copy the token
92+
93+
**Setup (Fine-grained Token - Recommended):**
94+
95+
1. Go to [GitHub Fine-grained Tokens](https://github.com/settings/tokens?type=beta)
96+
2. Click "Generate new token"
97+
3. Select the target repository
98+
4. Under "Repository permissions", set "Issues" to "Read and write"
99+
5. Generate and copy the token
100+
101+
### 3. Microsoft Teams (`microsoft_teams`)
102+
103+
Sends alerts to Microsoft Teams channels via webhooks.
104+
105+
**Configuration Fields:**
106+
- `webhook_url` - Teams Webhook URL (Workflows or legacy connector)
107+
- `channel_name` - Display name for reference (optional)
108+
- `mention_users` - Comma-separated emails to @mention
109+
- `theme_color` - Hex color for card accent
110+
111+
**Features:**
112+
- Adaptive Cards for rich formatting
113+
- @mention support for team members
114+
- "View in Bugsink" action button
115+
- Supports both new Workflows webhooks and legacy connectors
116+
117+
**Setup Method 1 - Workflows (Recommended):**
118+
119+
1. Open the Teams channel where you want alerts
120+
2. Click the "..." menu > "Workflows"
121+
3. Search for "Post to a channel when a webhook request is received"
122+
4. Configure the workflow and copy the webhook URL
123+
5. URL format: `https://xxx.webhook.office.com/webhookb2/...`
124+
125+
**Setup Method 2 - Legacy Incoming Webhook (deprecated):**
126+
127+
1. Go to Channel Settings > Connectors > Incoming Webhook
128+
2. Configure and copy the webhook URL
129+
3. URL format: `https://outlook.office.com/webhook/...`
130+
131+
> **Warning:** Microsoft is retiring legacy Office 365 Connectors by March 2026. Migrate to Workflows for continued support.
132+
133+
### 4. PagerDuty (`pagerduty`)
134+
135+
Creates incidents in PagerDuty for on-call alerting.
136+
137+
**Configuration Fields:**
138+
- `routing_key` - PagerDuty Events API v2 Integration Key (32 chars)
139+
- `default_severity` - Incident severity (critical, error, warning, info)
140+
- `service_name` - Custom source name (defaults to "Bugsink")
141+
- `include_link` - Include link to Bugsink issue
142+
143+
**Features:**
144+
- Events API v2 integration
145+
- Automatic incident deduplication by issue ID
146+
- Configurable severity levels
147+
- Custom details with full error context
148+
149+
**Setup:**
150+
151+
1. Log in to your PagerDuty account
152+
2. Go to Services > Select your service (or create a new one)
153+
3. Navigate to: Integrations > Add Integration
154+
4. Select "Events API v2"
155+
5. Copy the 32-character Integration Key (also called Routing Key)
156+
157+
### 5. Generic Webhook (`webhook`)
158+
159+
Sends alerts to any HTTP endpoint as JSON payloads.
160+
161+
**Configuration Fields:**
162+
- `webhook_url` - Target HTTP(S) endpoint
163+
- `http_method` - POST, PUT, or PATCH
164+
- `secret_header` - Header name for authentication (optional)
165+
- `secret_value` - Secret value for the header
166+
- `custom_headers` - Additional headers as JSON
167+
- `include_full_payload` - Include all available issue details
168+
169+
**Features:**
170+
- Flexible HTTP method selection
171+
- Custom authentication headers
172+
- Arbitrary custom headers via JSON
173+
- Full or minimal payload options
174+
175+
**Payload Structure:**
176+
```json
177+
{
178+
"event_type": "alert",
179+
"timestamp": "2024-01-15T10:30:00Z",
180+
"source": "bugsink",
181+
"data": {
182+
"issue_id": "123",
183+
"issue_url": "https://bugsink.example.com/issues/issue/123/event/last/",
184+
"summary": "[NEW] ValueError: Invalid input",
185+
"error_type": "ValueError",
186+
"error_message": "Invalid input",
187+
"project": "My Project",
188+
"first_seen": "2024-01-15T10:00:00Z",
189+
"last_seen": "2024-01-15T10:30:00Z",
190+
"event_count": 5,
191+
"alert_type": "NEW",
192+
"alert_reason": "new"
193+
}
194+
}
195+
```
196+
197+
## Implementation Notes
198+
199+
### HTTP Client
200+
201+
The new backends use the `requests` library, consistent with Bugsink's existing backends (slack.py, mattermost.py, discord.py). This ensures:
202+
203+
- Consistency across all notification backends
204+
- Uses the same error handling patterns (`requests.RequestException`)
205+
- Provides consistent timeout handling (30 seconds)
206+
207+
### Error Handling
208+
209+
All backends implement comprehensive error handling:
210+
- HTTP errors are captured with status codes and response bodies
211+
- Connection errors are logged with detailed messages
212+
- Failure information is stored in `MessagingServiceConfig` for UI display
213+
- Success clears previous failure status
214+
215+
### Async Task Execution
216+
217+
All message sending is performed asynchronously using Snappea's `@shared_task` decorator:
218+
- Non-blocking alert delivery
219+
- Automatic retry handling (when configured)
220+
- Proper database transaction management via `immediate_atomic`
221+
222+
### Security Considerations
223+
224+
- API tokens and secrets are stored in the encrypted `config` field
225+
- Webhook URLs support HTTPS
226+
- Password fields use `render_value=True` to allow editing without re-entering
227+
- No sensitive data is logged
228+
229+
## Testing
230+
231+
Each backend provides a `send_test_message()` method that:
232+
1. Sends a clearly marked test message/ticket
233+
2. Uses minimal severity where applicable (e.g., `info` for PagerDuty)
234+
3. Updates failure tracking on error
235+
4. Clears failure status on success
236+
237+
## Files Changed
238+
239+
```
240+
alerts/models.py # Backend registration
241+
alerts/service_backends/jira_cloud.py # NEW: Jira Cloud backend
242+
alerts/service_backends/github_issues.py # NEW: GitHub Issues backend
243+
alerts/service_backends/microsoft_teams.py # NEW: Microsoft Teams backend
244+
alerts/service_backends/pagerduty.py # NEW: PagerDuty backend
245+
alerts/service_backends/webhook.py # NEW: Generic Webhook backend
246+
```
247+
248+
## Compatibility
249+
250+
- **Bugsink Version:** 2.x
251+
- **Python Version:** 3.10+
252+
- **Django Version:** Compatible with Bugsink's Django version
253+
- **No additional dependencies required**
254+
255+
## Contributing
256+
257+
This contribution was developed by [BAUER GROUP](https://bauer-group.com).
258+
259+
---
260+
261+
*For questions or issues, please open a GitHub issue or contact the maintainers.*

src/backends/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ Diese Backends werden beim Docker-Build automatisch in das Bugsink-Image integri
2020

2121
1. **COPY**: Backend-Dateien werden nach `/usr/local/lib/python3.12/site-packages/alerts/service_backends/` kopiert
2222
2. **PATCH**: `register_backends.py` patcht `alerts/models.py` zur Registrierung
23-
3. **CLEANUP**: Das Patch-Skript wird nach der Ausführung entfernt
23+
3. **VERIFY**: `patch_views.py` und `patch_template.py` verifizieren die moderne Bugsink-Architektur (kein Patching nötig für Bugsink 2.0.x+)
24+
4. **CLEANUP**: Die Patch-Skripte werden nach der Ausführung entfernt
25+
26+
**Hinweis:** Bugsink 2.0.x+ hat bereits dynamisches Form-Loading via `get_alert_service_backend_class(kind).get_form_class()`. Die Views und Templates müssen nicht mehr gepatcht werden.
2427

2528
### Bugsink Architektur
2629

30+
- **HTTP Client**: `requests` Library (konsistent mit den bestehenden Bugsink-Backends)
2731
- **Model**: `MessagingServiceConfig` mit individuellen Failure-Tracking-Feldern:
2832
- `last_failure_timestamp`, `last_failure_error_type`, `last_failure_error_message`
2933
- `last_failure_status_code`, `last_failure_response_text`, `last_failure_is_json`

0 commit comments

Comments
 (0)