feat: SDK for Plugins #860

Open
opened 2026-03-28 04:29:19 +00:00 by mfreeman451 · 0 comments
Owner

Imported from GitHub.

Original GitHub issue: #2502
Original author: @mfreeman451
Original URL: https://github.com/carverauto/serviceradar/issues/2502
Original created: 2026-01-25T07:21:14Z


Is your feature request related to a problem?

We've created two seperate new repos for the SDKs:

https://github.com/carverauto/serviceradar-sdk-go
https://github.com/carverauto/serviceradar-sdk-rust

  • Rust SDK
  • #2535
  • SDKs should also create plugin bundle (.wasm, plugin.yaml, config.schema.json, SHA tag, etc)
  • docs.serviceradar.cloud update
  • Improve repo readme (Go)
  • Improve repo readme (Rust)
  • Add examples
  • #2503
  • #2504

The SDK should build bundles for us, basically it would need to create a .zip, but I'm not sure how we would use the SDK to do this without compiling something first.. not exactly sure the best way to do this in a very programmatic way, would be easy to put something in a Makefile or create a script, but the ergonomics of using it/DX seems bad.

This updated PRD incorporates the Alerting and Event Promotion logic.

In ServiceRadar, plugins are more than just "data gatherers"; they are the first line of defense in the Log → Event → Alert → Notification hierarchy. This SDK must allow authors to explicitly signal where a result sits within that promotion chain.


PRD: ServiceRadar Plugin SDK (Updated)

1. Overview

The ServiceRadar Plugin SDK is a developer-facing library that abstracts low-level Wasm Host-Guest communication. It provides an ergonomic way to write custom network checkers, interact with proxied networking, and explicitly drive the ServiceRadar Event Pipeline.

2. Goals

  • Abstract Memory Management: Handle pointers/linear memory for Wasm-Host data exchange.
  • Enforce Schema Fidelity: Ensure data matches serviceradar.plugin_result.v1.
  • Simplify Proxied Networking: Provide familiar interfaces (http.Get, net.Conn) via host functions.
  • Drive Event Promotion: Provide methods for plugins to generate structured Events and request promotion to Alerts based on internal thresholds.

3. Functional Requirements

3.1 Environment & Config

  • Retrieve JSON configuration defined in the plugin's UI schema.json.
  • Go: sdk.GetConfig(&myConfigStruct)
  • Rust: let cfg: MyConfig = sdk::get_config()?;

3.2 The Result Builder (UI & Pipeline)

The SDK must provide a builder pattern for the PluginResult schema:

  • Status: Set the execution state (OK, WARNING, CRITICAL, UNKNOWN).
  • Summary/Details: Set UI-visible strings.
  • Widget Library: AddStatCard, AddTable, AddSparkline.
  • Structured Metrics: AddMetric(name, value, unit, thresholds).

3.3 Safe Logging & Event Submission

  • Standard Logging: Maps to Agent’s logger (Debug, Info, Warn, Error).
  • Event Generation: Explicitly emit a ServiceRadar Event. Unlike a log, an Event is a state-change signal that Core tracks for alerting.
    • Go: sdk.EmitEvent(sdk.SeverityWarning, "High Latency Detected", "latency_threshold")

3.4 Alerting & Promotion Logic

Plugins must be able to influence the promotion of Events to Alerts.

  • Promotion Hint: Signal that an event should bypass standard dampening and become an Alert immediately.
  • Condition Key: Provide a unique "Identity Key" for the event to support de-duplication and "Auto-Clear" logic in Core.
  • Threshold Awareness: The SDK should provide helpers to compare metrics against UI-provided thresholds and auto-set the Plugin Status.

3.5 Proxied Networking (The Bridge)

  • HTTP: Wrap httpRequestPayload with a familiar request/response model.
  • TCP/UDP: Handle-based wrappers implementing native stream interfaces where possible (e.g., io.Reader/Writer).

4. Technical Requirements

4.1 Memory Model

  • Export alloc(size) for the Agent to write data into Wasm memory.
  • Provide dealloc(ptr, size) to prevent memory leaks.

4.2 Promotion Schema (serviceradar.plugin_result.v1)

The SDK must populate the following fields in the result JSON to drive the backend pipeline:

  • events: An array of structured event objects.
  • alert_hint: Boolean; if true, hints to Core that this result requires immediate operator attention.
  • condition_id: A string used to correlate "CRITICAL" events with their subsequent "OK" recovery.

5. Developer Experience (DX)

5.1 Go (TinyGo) Example: Alerting on Latency

package main

import (
    "fmt"
    "github.com/carverauto/serviceradar-sdk-go/sdk"
)

type Config struct {
    Target      string  `json:"target"`
    WarnMS      float64 `json:"warn_ms"`
    CriticalMS  float64 `json:"crit_ms"`
}

func main() {
    sdk.Execute(func() sdk.Result {
        var cfg Config
        sdk.GetConfig(&cfg)

        resp, err := sdk.HTTP.Get(cfg.Target)
        if err != nil {
            // Log promoted to Event, Event promoted to Alert
            res := sdk.Critical("Host Unreachable: " + err.Error())
            res.RequestImmediateAlert("network_down")
            return res
        }

        res := sdk.NewResult()
        latency := resp.Duration.Seconds() * 1000

        // Logic-driven Event Promotion
        if latency > cfg.CriticalMS {
            res.SetStatus(sdk.StatusCritical)
            res.SetSummary(fmt.Sprintf("Critical Latency: %.2fms", latency))
            // Emit a specific Event for the dashboard
            res.EmitEvent(sdk.SeverityCritical, "Latency exceeded critical threshold", "latency_check")
            res.RequestImmediateAlert("latency_spike") 
        } else if latency > cfg.WarnMS {
            res.SetStatus(sdk.StatusWarning)
            res.EmitEvent(sdk.SeverityWarning, "Latency is high", "latency_check")
        } else {
            res.SetStatus(sdk.StatusOk)
        }

        res.AddStatCard("Latency", fmt.Sprintf("%.2fms", latency), "blue")
        return res
    })
}

6. Security Requirements

  • Validation: Perform pre-flight format checks (URI validation, port ranges).
  • Proxy-Only: No raw syscalls. All I/O must go through the env module imports.

7. Delivery & Distribution

  1. Repositories:
    • serviceradar-sdk-go
    • serviceradar-sdk-rust
  2. Plugin Template: A "Standard Library" repository containing:
    • http_get_checker: Basic status/latency check with thresholds.
    • tcp_port_checker: Verifies specific ports with event logging.
  3. Documentation: Update docs.serviceradar.cloud with a "Alerting and Events" section for plugin authors explaining the dampening and promotion flow.

8. Success Criteria

  • A developer can define a custom threshold in the UI and have the plugin trigger an Alert in ServiceRadar when that threshold is crossed.
  • Events generated by the plugin are correctly correlated (Deduplicated) in the backend.
  • The .wasm binary remains minimal (< 2MB).
  • The UI renders the Event history alongside the plugin metrics.

9. Feature Roadmap Refinement

  • [x] #2503 (Go SDK Implementation): Priority on PluginResult builder and HTTP bridge.
  • [ ] #2504 (Rust SDK Implementation): Priority on serde integration for config mapping.
  • [ ] Event/Alert Mapping: Finalize the contract for how RequestImmediateAlert(key) maps to the Core-Elixir promotion logic.
Imported from GitHub. Original GitHub issue: #2502 Original author: @mfreeman451 Original URL: https://github.com/carverauto/serviceradar/issues/2502 Original created: 2026-01-25T07:21:14Z --- **Is your feature request related to a problem?** We've created two seperate new repos for the SDKs: https://github.com/carverauto/serviceradar-sdk-go https://github.com/carverauto/serviceradar-sdk-rust - [ ] Rust SDK - [x] #2535 - [ ] SDKs should also create plugin bundle (.wasm, plugin.yaml, config.schema.json, SHA tag, etc) - [x] docs.serviceradar.cloud update - [x] Improve repo readme (Go) - [ ] Improve repo readme (Rust) - [ ] Add examples - [x] #2503 - [ ] #2504 The SDK should build bundles for us, basically it would need to create a .zip, but I'm not sure how we would use the SDK to do this without compiling something first.. not exactly sure the best way to do this in a very programmatic way, would be easy to put something in a Makefile or create a script, but the ergonomics of using it/DX seems bad. This updated PRD incorporates the **Alerting and Event Promotion** logic. In ServiceRadar, plugins are more than just "data gatherers"; they are the first line of defense in the **Log → Event → Alert → Notification** hierarchy. This SDK must allow authors to explicitly signal where a result sits within that promotion chain. --- # PRD: ServiceRadar Plugin SDK (Updated) ## 1. Overview The ServiceRadar Plugin SDK is a developer-facing library that abstracts low-level Wasm Host-Guest communication. It provides an ergonomic way to write custom network checkers, interact with proxied networking, and explicitly drive the **ServiceRadar Event Pipeline**. ## 2. Goals * **Abstract Memory Management:** Handle pointers/linear memory for Wasm-Host data exchange. * **Enforce Schema Fidelity:** Ensure data matches `serviceradar.plugin_result.v1`. * **Simplify Proxied Networking:** Provide familiar interfaces (`http.Get`, `net.Conn`) via host functions. * **Drive Event Promotion:** Provide methods for plugins to generate structured Events and request promotion to Alerts based on internal thresholds. --- ## 3. Functional Requirements ### 3.1 Environment & Config * Retrieve JSON configuration defined in the plugin's UI `schema.json`. * **Go:** `sdk.GetConfig(&myConfigStruct)` * **Rust:** `let cfg: MyConfig = sdk::get_config()?;` ### 3.2 The Result Builder (UI & Pipeline) The SDK must provide a builder pattern for the `PluginResult` schema: * **Status:** Set the execution state (`OK`, `WARNING`, `CRITICAL`, `UNKNOWN`). * **Summary/Details:** Set UI-visible strings. * **Widget Library:** `AddStatCard`, `AddTable`, `AddSparkline`. * **Structured Metrics:** `AddMetric(name, value, unit, thresholds)`. ### 3.3 Safe Logging & Event Submission * **Standard Logging:** Maps to Agent’s logger (`Debug`, `Info`, `Warn`, `Error`). * **Event Generation:** Explicitly emit a ServiceRadar **Event**. Unlike a log, an Event is a state-change signal that Core tracks for alerting. * **Go:** `sdk.EmitEvent(sdk.SeverityWarning, "High Latency Detected", "latency_threshold")` ### 3.4 Alerting & Promotion Logic Plugins must be able to influence the promotion of Events to Alerts. * **Promotion Hint:** Signal that an event should bypass standard dampening and become an **Alert** immediately. * **Condition Key:** Provide a unique "Identity Key" for the event to support de-duplication and "Auto-Clear" logic in Core. * **Threshold Awareness:** The SDK should provide helpers to compare metrics against UI-provided thresholds and auto-set the Plugin Status. ### 3.5 Proxied Networking (The Bridge) * **HTTP:** Wrap `httpRequestPayload` with a familiar request/response model. * **TCP/UDP:** Handle-based wrappers implementing native stream interfaces where possible (e.g., `io.Reader/Writer`). --- ## 4. Technical Requirements ### 4.1 Memory Model * Export `alloc(size)` for the Agent to write data into Wasm memory. * Provide `dealloc(ptr, size)` to prevent memory leaks. ### 4.2 Promotion Schema (`serviceradar.plugin_result.v1`) The SDK must populate the following fields in the result JSON to drive the backend pipeline: * `events`: An array of structured event objects. * `alert_hint`: Boolean; if true, hints to Core that this result requires immediate operator attention. * `condition_id`: A string used to correlate "CRITICAL" events with their subsequent "OK" recovery. --- ## 5. Developer Experience (DX) ### 5.1 Go (TinyGo) Example: Alerting on Latency ```go package main import ( "fmt" "github.com/carverauto/serviceradar-sdk-go/sdk" ) type Config struct { Target string `json:"target"` WarnMS float64 `json:"warn_ms"` CriticalMS float64 `json:"crit_ms"` } func main() { sdk.Execute(func() sdk.Result { var cfg Config sdk.GetConfig(&cfg) resp, err := sdk.HTTP.Get(cfg.Target) if err != nil { // Log promoted to Event, Event promoted to Alert res := sdk.Critical("Host Unreachable: " + err.Error()) res.RequestImmediateAlert("network_down") return res } res := sdk.NewResult() latency := resp.Duration.Seconds() * 1000 // Logic-driven Event Promotion if latency > cfg.CriticalMS { res.SetStatus(sdk.StatusCritical) res.SetSummary(fmt.Sprintf("Critical Latency: %.2fms", latency)) // Emit a specific Event for the dashboard res.EmitEvent(sdk.SeverityCritical, "Latency exceeded critical threshold", "latency_check") res.RequestImmediateAlert("latency_spike") } else if latency > cfg.WarnMS { res.SetStatus(sdk.StatusWarning) res.EmitEvent(sdk.SeverityWarning, "Latency is high", "latency_check") } else { res.SetStatus(sdk.StatusOk) } res.AddStatCard("Latency", fmt.Sprintf("%.2fms", latency), "blue") return res }) } ``` --- ## 6. Security Requirements * **Validation:** Perform pre-flight format checks (URI validation, port ranges). * **Proxy-Only:** No raw syscalls. All I/O must go through the `env` module imports. --- ## 7. Delivery & Distribution 1. **Repositories:** * `serviceradar-sdk-go` * `serviceradar-sdk-rust` 2. **Plugin Template:** A "Standard Library" repository containing: * `http_get_checker`: Basic status/latency check with thresholds. * `tcp_port_checker`: Verifies specific ports with event logging. 3. **Documentation:** Update `docs.serviceradar.cloud` with a "Alerting and Events" section for plugin authors explaining the dampening and promotion flow. --- ## 8. Success Criteria * A developer can define a custom threshold in the UI and have the plugin trigger an **Alert** in ServiceRadar when that threshold is crossed. * Events generated by the plugin are correctly correlated (Deduplicated) in the backend. * The `.wasm` binary remains minimal (< 2MB). * The UI renders the Event history alongside the plugin metrics. --- ## 9. Feature Roadmap Refinement * **[x] #2503 (Go SDK Implementation):** Priority on `PluginResult` builder and HTTP bridge. * **[ ] #2504 (Rust SDK Implementation):** Priority on `serde` integration for config mapping. * **[ ] Event/Alert Mapping:** Finalize the contract for how `RequestImmediateAlert(key)` maps to the Core-Elixir promotion logic.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
carverauto/serviceradar#860
No description provided.