Skip to content

feat: add Apache SkyWalking provider#6248

Open
QuinnClaw wants to merge 4 commits intokeephq:mainfrom
QuinnClaw:feat/skywalking-provider
Open

feat: add Apache SkyWalking provider#6248
QuinnClaw wants to merge 4 commits intokeephq:mainfrom
QuinnClaw:feat/skywalking-provider

Conversation

@QuinnClaw
Copy link
Copy Markdown

@QuinnClaw QuinnClaw commented Apr 14, 2026

Closes #5487

New Provider: Apache SkyWalking

Adds a provider for Apache SkyWalking, an open-source APM system for distributed systems, cloud-native architectures, and containers.

Features:

  • Pull alerts from SkyWalking OAP server via GraphQL API
  • Webhook support for real-time alarm notifications from SkyWalking
  • Service topology data retrieval
  • Severity mapping from SkyWalking alarm levels → Keep severity levels
  • Optional authentication (username/password) support

Auth Config:

Parameter Required Description
host Yes SkyWalking OAP server URL
username No Auth username
password No Auth password

Scopes:

  • read_alerts (required) — Read alarms/alerts
  • read_topology (optional) — Read service topology

Files:

  • keep/providers/skywalking_provider/skywalking_provider.py — Provider implementation
  • keep/providers/skywalking_provider/__init__.py — Package init
  • keep/providers/skywalking_provider/README.md — Documentation

Webhook Example:

Included webhook_example() for SkyWalking alarm webhook format.

Severity Mapping:

SkyWalking Keep
critical/fatal CRITICAL
error/high HIGH
warning/warn WARNING
info/notice INFO

Note

Medium Risk
Adds a new external integration that performs outbound GraphQL requests and maps webhook payloads into alerts; main risk is API/query compatibility and error-handling around network/auth failures rather than changes to existing core flows.

Overview
Adds a new skywalking_provider package implementing an Apache SkyWalking integration.

The provider introduces auth/config schema (host + optional basic auth), scope validation via lightweight GraphQL queries, alert ingestion by querying getAlarm (with severity mapping), optional topology retrieval via getGlobalTopology, and a webhook formatter/example for SkyWalking alarm payloads. Includes provider-specific README documentation and setup guidance.

Reviewed by Cursor Bugbot for commit 607f573. Bugbot is set up for automated code reviews on this repo. Configure here.

@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Apr 14, 2026
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 14, 2026

CLA assistant check
All committers have signed the CLA.

@dosubot dosubot bot added Feature A new feature Provider Providers related issues labels Apr 14, 2026
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 607f573. Configure here.

if t.get("key")
}
severity = SkywalkingProvider._map_severity(tags.get("level", "warning"))
service_name = scope_data.get("service", event.get("name", "unknown"))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Webhook _format_alert crashes on string scope field

High Severity

In _format_alert, scope_data = event.get("scope", {}) retrieves the scope field, then scope_data.get("service", ...) is called on it. However, the webhook_example() in the same file shows "scope": "SERVICE" — a string, not a dict. Calling .get() on a string raises an AttributeError, crashing all webhook-based alarm processing. The GraphQL query in _get_alerts returns scope as a structured object, but the webhook format uses a plain string.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 607f573. Configure here.

return data.get("getGlobalTopology", {})
except Exception as e:
logger.error(f"Failed to fetch SkyWalking topology: {e}")
return {}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return type annotation mismatches actual return value

Low Severity

_get_topology is annotated as returning list[dict] but actually returns a dict (from data.get("getGlobalTopology", {})) on success, and {} on error. Any caller iterating over the result expecting a list of dicts would get unexpected behavior — iterating over dict keys instead of dict items.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 607f573. Configure here.

service=service_name,
lastReceived=datetime.datetime.utcnow().isoformat(),
tags=tags,
fingerprint=f"skywalking-{event.get('id', '')}",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Webhook fingerprint missing id0 fallback causes deduplication collapse

High Severity

In _format_alert, the id field correctly falls back to id0 via event.get("id", event.get("id0", "")), but the fingerprint field only checks event.get('id', '') without the same fallback. SkyWalking webhook payloads use id0 (not id), as shown by the webhook_example() in the same file. This means all webhook-sourced alerts get fingerprint "skywalking-", collapsing them into a single deduplicated alert.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 607f573. Configure here.

…x topology return type

- _format_alert: scope can be string (webhook) or dict (GraphQL), handle both
- fingerprint: add id0 fallback matching the id field behavior
- _get_topology: fix return type annotation from list[dict] to dict

Addresses Cursor Bugbot review feedback.
@cursor
Copy link
Copy Markdown

cursor bot commented Apr 14, 2026

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@QuinnClaw
Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@QuinnClaw
Copy link
Copy Markdown
Author

@CLAassistant check

@QuinnClaw
Copy link
Copy Markdown
Author

/check-cla

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature A new feature Provider Providers related issues size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[🔌 Provider]: add skywalking

2 participants