Documentation
¶
Overview ¶
Package itoc360 is the Go client for the ITOC360 Events API.
ITOC360 is an incident management and on-call platform. This package sends events to an ITOC360 source, which then runs them through the tenant's escalation policies, on-call schedules and notification channels.
Authentication ¶
Every request is authenticated with a source token. A source is created in the ITOC360 web application; each one carries its own token and is bound to a single provider type. The token is sent as an RFC 6750 bearer token.
client, err := itoc360.NewClient(os.Getenv("ITOC360_TOKEN"))
if err != nil {
return err
}
Sending alerts ¶
Client.SendAlert takes a provider-independent Alert and expands it into the Prometheus Alertmanager webhook payload. It works with any source whose provider speaks that format: prometheus, mimir, cortex, loki, signoz and grafana.
_, err = client.SendAlert(ctx, itoc360.Alert{
Fingerprint: "db-primary-disk-full",
Summary: "Disk usage on db-primary is at 95%",
Severity: itoc360.SeverityCritical,
Status: itoc360.StatusFiring,
})
Fingerprint is the deduplication key. ITOC360 groups every event carrying the same fingerprint into one alert, so send the same value for the firing and the resolved event, and a different value for an unrelated alert.
Sending other payloads ¶
A source configured for a different provider — Datadog, Zabbix, Dynatrace and so on — expects that vendor's own payload. Client.SendRaw sends any value that marshals to JSON, leaving the shape entirely to the caller.
_, err = client.SendRaw(ctx, map[string]any{"alert_id": "42"})
Index ¶
Examples ¶
Constants ¶
const ( // DefaultBaseURL is the ITOC360 API endpoint used unless WithBaseURL says // otherwise. DefaultBaseURL = "https://api.itoc360.app" // Version is the version of this SDK. It is the fallback for the // User-Agent header when the build carries no module version, which is // the case while developing on this module itself. Version = "0.1.0" )
Variables ¶
var ErrMissingToken = errors.New("itoc360: source token is required")
ErrMissingToken is returned by NewClient when the source token is empty.
Functions ¶
This section is empty.
Types ¶
type APIError ¶
type APIError struct {
// StatusCode is the HTTP status returned by ITOC360.
StatusCode int
// Message is the server-supplied explanation.
Message string
}
APIError is returned when ITOC360 responds with a non-2xx status.
Message carries the server's own explanation when the response body is the documented {"error": "..."} object, and a short generic description otherwise. Neither the source token nor any request header is ever included.
Example ¶
Tell the failure modes apart when a send is rejected.
package main
import (
"context"
"errors"
"log"
"os"
"github.com/itoc360/itoc360-go"
)
func main() {
client, err := itoc360.NewClient(os.Getenv("ITOC360_TOKEN"))
if err != nil {
log.Fatal(err)
}
_, err = client.SendAlert(context.Background(), itoc360.Alert{
Fingerprint: "db-primary-disk-full",
Summary: "Disk usage on db-primary is at 95%",
})
var apiErr *itoc360.APIError
switch {
case err == nil:
return
case errors.As(err, &apiErr) && apiErr.Unauthorized():
log.Fatal("ITOC360_TOKEN is not a valid source token")
case errors.As(err, &apiErr) && apiErr.SubscriptionInactive():
log.Fatal("the ITOC360 subscription for this organization is not active")
case errors.As(err, &apiErr) && apiErr.Retryable():
log.Printf("ITOC360 is unavailable, will retry: %v", apiErr)
default:
log.Printf("sending alert: %v", err)
}
}
Output:
func (*APIError) Retryable ¶
Retryable reports whether the request is worth sending again unchanged. Server-side failures, rate limiting and a timed-out request are; a rejected payload is not.
func (*APIError) SubscriptionInactive ¶
SubscriptionInactive reports whether the tenant's ITOC360 subscription has lapsed. ITOC360 answers 402 in that case and drops the event.
func (*APIError) Unauthorized ¶
Unauthorized reports whether the token was missing or not recognised.
ITOC360 answers 401 when no token is presented and 404 when the token matches no source, so both are treated as credential failures. Telling that 404 apart from a genuinely missing resource means reading the server's wording; should ITOC360 rephrase it, this method stops recognising the case but StatusCode and Message still describe what happened.
type Alert ¶
type Alert struct {
// Fingerprint identifies the alert across its lifetime and is required.
//
// ITOC360 deduplicates on this value: an event whose fingerprint matches
// an open alert updates that alert instead of raising a new one. Derive it
// from what makes the condition unique — the host, the check and the
// object it watches, say — and keep it stable between the firing and the
// resolved event.
Fingerprint string
// Summary is the one-line description shown as the alert's title in
// ITOC360 and in the notifications it sends. It is required.
Summary string
// Description is optional longer text shown alongside the summary.
Description string
// Severity sets the alert's priority. Defaults to SeverityWarning.
Severity Severity
// Status says whether the alert is firing or resolved. Defaults to
// StatusFiring.
Status Status
// Labels are arbitrary key-value pairs describing the alert, such as the
// instance or the service it concerns. Escalation rules can match on them.
//
// A "severity" key is added from the Severity field; an explicit entry
// here does not override it.
Labels map[string]string
// Annotations are additional key-value pairs carried with the alert.
// "summary" and "description" are filled in from the fields above.
Annotations map[string]string
// StartsAt is when the condition began. Defaults to the current time.
StartsAt time.Time
// EndsAt is when the condition cleared. It is sent only for resolved
// alerts, where it defaults to the current time.
EndsAt time.Time
// GeneratorURL optionally links back to whatever raised the alert — a
// dashboard, a run, a log query.
GeneratorURL string
// Receiver names the sender in the stored payload. Defaults to
// "itoc360-go".
Receiver string
}
Alert is a single alert to send to ITOC360.
Fingerprint and Summary are required. Status defaults to StatusFiring, Severity to SeverityWarning and StartsAt to the current time.
func (Alert) Validate ¶
Validate reports whether the alert can be sent. Client.SendAlert calls it before every request, so calling it directly is only useful to check user input early.
Example ¶
Check user input before a send. SendAlert runs the same check itself, so this is only worth doing to report the problem earlier.
package main
import (
"errors"
"log"
"github.com/itoc360/itoc360-go"
)
func main() {
alert := itoc360.Alert{Summary: "Disk usage on db-primary is at 95%"}
var verr *itoc360.ValidationError
if err := alert.Validate(); errors.As(err, &verr) {
log.Printf("alert field %s is not usable: %s", verr.Field, verr.Message)
}
}
Output:
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client sends events to a single ITOC360 source. It is safe for concurrent use by multiple goroutines.
func NewClient ¶
NewClient returns a Client that authenticates with the given ITOC360 source token. It returns ErrMissingToken if the token is empty.
The token is created alongside a source in the ITOC360 web application and determines which tenant the events belong to and which payload format the endpoint expects. Read it from the environment or a secret store; never commit it.
Example ¶
Create a client from a source token held in the environment.
package main
import (
"log"
"os"
"github.com/itoc360/itoc360-go"
)
func main() {
client, err := itoc360.NewClient(os.Getenv("ITOC360_TOKEN"))
if err != nil {
log.Fatal(err)
}
_ = client
}
Output:
Example (Options) ¶
Configure the client for a self-hosted deployment and a tighter timeout.
package main
import (
"log"
"net/http"
"os"
"time"
"github.com/itoc360/itoc360-go"
)
func main() {
client, err := itoc360.NewClient(
os.Getenv("ITOC360_TOKEN"),
itoc360.WithBaseURL("https://itoc360.internal.example"),
itoc360.WithHTTPClient(&http.Client{Timeout: 10 * time.Second}),
itoc360.WithUserAgent("acme-pager/2.1"),
)
if err != nil {
log.Fatal(err)
}
_ = client
}
Output:
func (*Client) SendAlert ¶
SendAlert sends an alert to ITOC360.
The alert is expanded into the Prometheus Alertmanager webhook payload, so the source must be configured for a provider that speaks it: prometheus, mimir, cortex, loki, signoz or grafana. For any other provider, build that vendor's payload and use SendRaw.
A ValidationError is returned, without contacting ITOC360, when the alert is missing a fingerprint or a summary.
Example ¶
Raise an alert. The fingerprint is what ITOC360 deduplicates on, so derive it from the condition rather than generating one per run.
package main
import (
"context"
"log"
"os"
"github.com/itoc360/itoc360-go"
)
func main() {
client, err := itoc360.NewClient(os.Getenv("ITOC360_TOKEN"))
if err != nil {
log.Fatal(err)
}
event, err := client.SendAlert(context.Background(), itoc360.Alert{
Fingerprint: "db-primary-disk-full",
Summary: "Disk usage on db-primary is at 95%",
Description: "The data volume has less than 5% free space left.",
Severity: itoc360.SeverityCritical,
Status: itoc360.StatusFiring,
Labels: map[string]string{
"instance": "db-01",
"service": "payments",
},
})
if err != nil {
log.Fatal(err)
}
log.Printf("raised alert %s (%s)", event.ID, event.Type)
}
Output:
Example (Resolve) ¶
Close an alert by sending the same fingerprint with StatusResolved.
package main
import (
"context"
"log"
"os"
"github.com/itoc360/itoc360-go"
)
func main() {
client, err := itoc360.NewClient(os.Getenv("ITOC360_TOKEN"))
if err != nil {
log.Fatal(err)
}
_, err = client.SendAlert(context.Background(), itoc360.Alert{
Fingerprint: "db-primary-disk-full",
Summary: "Disk usage on db-primary is back to normal",
Status: itoc360.StatusResolved,
})
if err != nil {
log.Fatal(err)
}
}
Output:
func (*Client) SendRaw ¶
SendRaw sends payload to ITOC360 as the event body, marshalled as JSON.
It applies no shape of its own, so it works with every provider ITOC360 supports: pass the payload that provider documents. Use SendAlert instead when the source speaks the Alertmanager format.
Example ¶
Send a vendor payload to a source configured for a provider other than the Alertmanager family — here, Datadog.
package main
import (
"context"
"log"
"os"
"github.com/itoc360/itoc360-go"
)
func main() {
client, err := itoc360.NewClient(os.Getenv("ITOC360_TOKEN"))
if err != nil {
log.Fatal(err)
}
_, err = client.SendRaw(context.Background(), map[string]any{
"alert_id": "42",
"alert_transition": "Triggered",
"alert_title": "CPU high on web-03",
"alert_type": "error",
})
if err != nil {
log.Fatal(err)
}
}
Output:
type EventResponse ¶
type EventResponse struct {
// ID is the identifier of the stored event.
ID string `json:"id"`
// TenantID is the organization the source belongs to.
TenantID string `json:"tenant_id"`
// ProviderID is the provider the source is configured for.
ProviderID int64 `json:"provider_id"`
// SourceID is the source the token resolved to.
SourceID string `json:"source_id"`
// Type is "ALERT" for a firing event and "RESOLVE" for a resolved one.
Type string `json:"type"`
// Fingerprint is the deduplication key ITOC360 derived from the payload.
Fingerprint string `json:"fingerprint"`
// Payload is the body as ITOC360 stored it.
Payload json.RawMessage `json:"payload"`
// CreatedAt is when the event was recorded.
CreatedAt time.Time `json:"created_at"`
}
EventResponse is the event ITOC360 recorded, returned on success.
type Option ¶
type Option func(*Client)
Option configures a Client. Options are applied by NewClient in the order they are given.
func WithBaseURL ¶
WithBaseURL points the client at a different ITOC360 deployment. Use it for self-hosted installations and for tests. A trailing slash is ignored.
func WithHTTPClient ¶
WithHTTPClient supplies the http.Client used for requests, which is where timeouts, proxies, transports and instrumentation belong. The default client has a 30 second timeout.
func WithUserAgent ¶
WithUserAgent replaces the User-Agent header. The default identifies this SDK and its version; prefer appending to it over replacing it.
type Severity ¶
type Severity string
Severity is the urgency of an alert. ITOC360 maps it to the alert's priority: critical to CRITICAL, error to HIGH, warning to MEDIUM and info to LOW.
type ValidationError ¶
type ValidationError struct {
// Field is the name of the offending Alert field.
Field string
// Message explains what is wrong with it.
Message string
}
ValidationError is returned when an Alert cannot be sent as written. The request is rejected locally and never reaches ITOC360.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string