Documentation
¶
Overview ¶
Package sleuth provides a focused Go client for the Sleuth.io API, covering the most common write-side integrations used for delivery metrics and operational signal ingestion.
This package supports four Sleuth workflows:
- deployment registration,
- manual change registration,
- custom incident impact registration,
- custom metric impact registration.
Sleuth API reference: https://help.sleuth.io/sleuth-api
Problem ¶
Integrating with Sleuth directly from raw HTTP calls involves repeated boilerplate: endpoint formatting, authorization headers, JSON encoding, request validation, retry handling, and response status checks. Recreating this logic in each service increases maintenance cost and makes behavior inconsistent across deployments.
This package centralizes that integration logic behind a typed client and request models.
How It Works ¶
New initializes a Client with base URL, org slug, and API key, then builds the endpoint URL templates used by each API action.
For each send operation:
- The request struct is validated using nurago's validator package and the tag rules declared on fields.
- The payload is JSON-encoded and sent as an authenticated HTTP POST (`Authorization: apikey <key>`).
- The request is executed through a write-oriented HTTP retrier.
- Non-200 responses are returned as errors with status details.
Health checks are implemented using Sleuth's documented behavior in absence of a dedicated ping endpoint: the client performs a controlled registration call and verifies expected 404 semantics and response content.
Key Features ¶
- Typed request models with validation tags for safer API inputs.
- End-to-end helpers: Client.SendDeployRegistration, Client.SendManualChange, Client.SendCustomIncidentImpactRegistration, Client.SendCustomMetricImpactRegistration.
- Built-in authentication and JSON header management.
- Configurable client behavior via options: WithHTTPClient, WithTimeout, WithPingTimeout, WithRetryAttempts, WithRetryDelay.
- Health-check API through Client.HealthCheck for readiness/liveness flows.
Benefits ¶
- Faster and more consistent Sleuth integrations across services.
- Reduced API misuse risk through validated typed payloads.
- Better resilience to transient HTTP failures via retry support.
- Cleaner application code by delegating protocol and endpoint details.
Usage ¶
c, err := sleuth.New("https://app.sleuth.io/api/1", "my-org", apiKey)
if err != nil {
return err
}
if err := c.HealthCheck(ctx); err != nil {
return err
}
err = c.SendDeployRegistration(ctx, &sleuth.DeployRegistrationRequest{
Deployment: "my-service",
Sha: "abcdef1234567890abcdef1234567890abcdef12",
})
if err != nil {
return err
}
This package is ideal for Go services that need a lightweight, production-ready Sleuth API adapter without hand-writing HTTP integration code.
Index ¶
- Variables
- type Client
- func (c *Client) HealthCheck(ctx context.Context) (err error)
- func (c *Client) SendCustomIncidentImpactRegistration(ctx context.Context, request *CustomIncidentImpactRegistrationRequest) error
- func (c *Client) SendCustomMetricImpactRegistration(ctx context.Context, request *CustomMetricImpactRegistrationRequest) error
- func (c *Client) SendDeployRegistration(ctx context.Context, request *DeployRegistrationRequest) error
- func (c *Client) SendManualChange(ctx context.Context, request *ManualChangeRequest) error
- type CustomIncidentImpactRegistrationRequest
- type CustomMetricImpactRegistrationRequest
- type DeployRegistrationRequest
- type HTTPClient
- type IncidentType
- type ManualChangeRequest
- type Option
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidAddress is returned by New when the Sleuth address is missing, // unparseable, or lacks a scheme or host. ErrInvalidAddress = errors.New("sleuth: invalid address") // ErrEmptyOrg is returned by New when the org slug is empty. ErrEmptyOrg = errors.New("sleuth: org is empty") // ErrEmptyAPIKey is returned by New when the API key is empty. ErrEmptyAPIKey = errors.New("sleuth: api key is empty") // ErrInvalidRetryConfig is returned by New when the retry options are invalid. ErrInvalidRetryConfig = errors.New("sleuth: invalid retry configuration") // ErrNilRequest is returned by the Send methods when the request is nil. ErrNilRequest = errors.New("sleuth: request must not be nil") )
Exported sentinel errors returned by this package. Match them with errors.Is.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client sends deployment/change/impact events to the Sleuth API.
func New ¶
New constructs a Sleuth API client with validation, retry defaults, and URL templates for the provided org.
func (*Client) HealthCheck ¶
HealthCheck validates API access by executing a controlled request and verifying Sleuth's expected 404 response pattern.
func (*Client) SendCustomIncidentImpactRegistration ¶
func (c *Client) SendCustomIncidentImpactRegistration(ctx context.Context, request *CustomIncidentImpactRegistrationRequest) error
SendCustomIncidentImpactRegistration submits custom incident impact values used by Sleuth failure-rate and MTTR metrics. The dynamic path segments are percent-escaped so values containing "/", "?", or "#" cannot rewrite the request path or shift the API-key segment.
func (*Client) SendCustomMetricImpactRegistration ¶
func (c *Client) SendCustomMetricImpactRegistration(ctx context.Context, request *CustomMetricImpactRegistrationRequest) error
SendCustomMetricImpactRegistration submits custom metric impact values for Sleuth anomaly detection and deployment health.
func (*Client) SendDeployRegistration ¶
func (c *Client) SendDeployRegistration(ctx context.Context, request *DeployRegistrationRequest) error
SendDeployRegistration registers a deployment event with Sleuth.
func (*Client) SendManualChange ¶
func (c *Client) SendManualChange(ctx context.Context, request *ManualChangeRequest) error
SendManualChange registers a manual change not tracked by source-control-based integrations.
type CustomIncidentImpactRegistrationRequest ¶
type CustomIncidentImpactRegistrationRequest struct {
// Project is the Sleuth project ID as found in the Sleuth URL, following the prefix https://app.sleuth.io/org_slug/.
Project string `json:"-" validate:"required,max=50"`
// Environment is the environment to register the deploy against.
// Found at the end of the URL of the Sleuth org when navigating to the target project
// and selecting the target custom incident impact source: env_slug=ENVIRONMENT_SLUG.
Environment string `json:"-" validate:"required,max=50"`
// ImpactSource is found in the URL of the Sleuth org when navigating to the target project
// and selecting the target custom incident impact source, just before the ?env_slug.
ImpactSource string `json:"-" validate:"required,max=50"`
// Type Valid types are triggered, resolved, and reopened.
Type IncidentType `json:"type" validate:"required,oneof=triggered resolved reopened"`
// ID is the unique (custom) incident identifier.
ID string `json:"id" validate:"omitempty,max=50"`
// Date is the ISO 8601 date and time string when the event occurred.
// Defaults to the current time.
Date string `json:"date,omitempty" validate:"omitempty,datetime=2006-01-02 15:04:05"`
// EndedDate is the ISO 8601 date and time string when the event ended.
// Use it with "type": "triggered" to register past incident event.
EndedDate string `json:"ended_date,omitempty" validate:"omitempty,datetime=2006-01-02 15:04:05"`
// Title is the human-readable title of the incident.
Title string `json:"title,omitempty" validate:"omitempty,max=255"`
// URL to the incident in the external system.
URL string `json:"url,omitempty" validate:"omitempty,url"`
}
CustomIncidentImpactRegistrationRequest defines the request for Custom Incident Impact Registration.
type CustomMetricImpactRegistrationRequest ¶
type CustomMetricImpactRegistrationRequest struct {
// ImpactID is the integer ID that can be found bny navigating in the Custom Metric Impact Source,
// clicking the gearwheel icon in the top-right corner, and selecting "Show register details".
ImpactID int `json:"-" validate:"required"`
// Value is the metric value to be registered.
// Zero is a legitimate metric value (e.g. a zero error rate), so no
// "required" validation is applied (go-playground's required rejects
// zero values); the field is always serialized.
Value float64 `json:"value"`
// Date is the ISO 8601 date and time string at which the metric value should be registered.
// Defaults to the current time.
Date string `json:"date,omitempty" validate:"omitempty,datetime=2006-01-02 15:04:05"`
}
CustomMetricImpactRegistrationRequest defines the request for Custom Metric Impact Registration.
type DeployRegistrationRequest ¶
type DeployRegistrationRequest struct {
// Deployment is the Sleuth deploymnet ID as found in the Sleuth URL, following the prefix https://app.sleuth.io/org_slug/deployments/.
Deployment string `json:"-" validate:"required,max=50"`
// Sha is the Git SHA of the commit to be registered as a deploy.
Sha string `json:"sha" validate:"required,max=40"`
// Environment is the environment to register the deploy against.
// If not provided Sleuth will use the default environment of the Project.
Environment string `json:"environment,omitempty" validate:"omitempty,max=50"`
// Date is the ISO 8601 deployment date and time string.
Date string `json:"date,omitempty" validate:"omitempty,datetime=2006-01-02 15:04:05"`
// Tags is a comma-delimited list of tags.
// Default to tags calculated by matching paths defined in the .sleuth/TAGS file.
Tags []string `json:"tags,omitempty" validate:"omitempty,max=50,dive,max=50,startswith=#"`
// IgnoreIfDuplicate ignores duplicate SHA and do not return an error.
IgnoreIfDuplicate bool `json:"ignore_if_duplicate,omitempty" validate:"omitempty"`
// Email is the email address of the author.
Email string `json:"email,omitempty" validate:"omitempty,email"`
// Links contains key/value pair consisting of the link name and the link itself.
Links map[string]string `json:"links,omitempty" validate:"omitempty,max=50,dive,url"`
}
DeployRegistrationRequest defines the request for Deploy Registration.
type HTTPClient ¶
type HTTPClient interface {
// Do sends an HTTP request and returns an HTTP response.
Do(req *http.Request) (*http.Response, error)
}
HTTPClient is the minimal HTTP transport contract used by Client.
type IncidentType ¶
type IncidentType string
IncidentType defines the valid values for an Incident Type.
const ( // Triggered indicates a new incident. Triggered IncidentType = "triggered" // Resolved indicates the incident has been resolved. Resolved IncidentType = "resolved" // Reopened indicated the incident has been reopened. Reopened IncidentType = "reopened" )
type ManualChangeRequest ¶
type ManualChangeRequest struct {
// Project is the Sleuth project ID as found in the Sleuth URL, following the prefix https://app.sleuth.io/org_slug/.
Project string `json:"-" validate:"required,max=50"`
// Name is the title for the manual change.
Name string `json:"name" validate:"required,max=255"`
// Description for manual changes. Omit if using SHA instead.
Description string `json:"description,omitempty" validate:"omitempty,max=65535"`
// Environment is the environment to register the deploy against.
// If not provided Sleuth will use the default environment of the Project.
Environment string `json:"environment,omitempty" validate:"omitempty,max=50"`
// Tags is a comma-delimited list of tags.
// Default to tags calculated by matching paths defined in the .sleuth/TAGS file.
Tags []string `json:"tags,omitempty" validate:"omitempty,max=50,dive,max=50,startswith=#"`
// Author is the email address of the change author.
Author string `json:"author,omitempty" validate:"omitempty,email"`
// Email is the email address of the user associated with the project receiving the manual change.
Email string `json:"email,omitempty" validate:"omitempty,email"`
}
ManualChangeRequest defines the request for Manual Change.
type Option ¶
type Option func(c *Client)
Option customizes Sleuth client configuration.
func WithHTTPClient ¶
func WithHTTPClient(hc HTTPClient) Option
WithHTTPClient injects a custom HTTP client implementation.
func WithPingTimeout ¶
WithPingTimeout overrides default health-check timeout.
func WithRetryAttempts ¶
WithRetryAttempts overrides retry attempt count for write operations.
func WithRetryDelay ¶
WithRetryDelay sets base delay for retrier backoff configuration.
func WithTimeout ¶
WithTimeout overrides default request timeout.
It is applied only to the default HTTP client that New creates; it has no effect when a custom client is supplied via WithHTTPClient (that client owns its own timeout).