Writing spec collectors
What are spec collectors?
Spec collectors are Go functions that:
- Run automatically on a periodic schedule (default: 60 seconds).
- Gather information.
- Return structured data for querying via dotted notation.
Unlike tasks which are executed on demand, spec collectors run continuously in the background.
Function signature
All spec collectors must follow this exact signature:
func CollectorName(ctx context.Context) (ReturnType, error)
Requirements
- Context Parameter: For cancellation and timeout handling.
- Return Type: Any serializable Go type (struct, map, slice, primitives), same as tasks.
- Error Return: Standard Go error handling.
Basic example
package main
import (
"context"
"runtime"
"os"
"github.com/jackadi-io/jackadi/sdk"
)
type SystemInfo struct {
OS string `json:"os"`
Architecture string `json:"architecture"`
CPUCores int `json:"cpu_cores"`
Hostname string `json:"hostname"`
}
func SystemInfoCollector(ctx context.Context) (SystemInfo, error) {
hostname, err := os.Hostname()
if err != nil {
hostname = "unknown"
}
return SystemInfo{
OS: runtime.GOOS,
Architecture: runtime.GOARCH,
CPUCores: runtime.NumCPU(),
Hostname: hostname,
}, nil
}
func main() {
plugin := sdk.New("system-info")
plugin.MustRegisterSpecCollector("basic", SystemInfoCollector)
sdk.MustServe(plugin)
}
Registration and usage
Multiple collectors
func main() {
plugin := sdk.New("infrastructure")
// Register multiple collectors
plugin.MustRegisterSpecCollector("system", SystemInfoCollector)
plugin.MustRegisterSpecCollector("network", NetworkCollector)
plugin.MustRegisterSpecCollector("docker", DockerStatsCollector)
sdk.MustServe(plugin)
}
Accessing collected data
# List available specs
jack run agent1 specs:list
# Get all spec data
jack run agent1 specs:all
# Get specific data using dotted notation
jack run agent1 specs:get infrastructure.system.cpu_cores
jack run agent1 specs:get infrastructure.network.interfaces[0].ip_address
Targeting with specs
# Target based on OS
jack run -q "specs.infrastructure.system.os==linux" linux-task:run
Best practices
- Performance: Keep collectors fast and lightweight.
- Error Handling: Handle errors gracefully without affecting agent stability.
- Caching: Cache expensive operations with appropriate TTL.
- Structure: Design data for easy querying with dotted notation.
- Naming: Use consistent, descriptive naming conventions.
- Security: Avoid collecting sensitive information.
- Context: Always respect context cancellation and timeouts.