Documentation
¶
Overview ¶
Example ¶
This example shows a basic usage of sloth library by exposing sloth SLO generation functionality as a rest HTTP API.
package main
import (
"fmt"
"io"
"net/http"
sloth "github.com/slok/sloth/pkg/lib"
)
func main() {
// Check with `curl -XPOST http://127.0.0.1:8080/sloth/generate -d "$(cat ./examples/getting-started.yml)"`.
gen, err := sloth.NewPrometheusSLOGenerator(sloth.PrometheusSLOGeneratorConfig{
ExtraLabels: map[string]string{"source": "slothlib-example"},
})
if err != nil {
panic(fmt.Errorf("could not create SLO generator: %w", err))
}
mux := http.NewServeMux()
mux.HandleFunc("POST /sloth/generate", func(w http.ResponseWriter, r *http.Request) {
// Get body from request.
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "failed to read request body", http.StatusBadRequest)
return
}
defer r.Body.Close()
// Generate SLOs.
result, err := gen.GenerateFromRaw(r.Context(), body)
if err != nil {
http.Error(w, fmt.Sprintf("could not generate SLOs: %v", err), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
err = gen.WriteResultAsPrometheusStd(r.Context(), *result, w)
if err != nil {
http.Error(w, fmt.Sprintf("could not write result: %v", err), http.StatusInternalServerError)
return
}
})
httpServer := &http.Server{Addr: ":8080", Handler: mux}
fmt.Println("Starting server at :8080")
err = httpServer.ListenAndServe()
if err != nil {
panic(err)
}
}
Output:
Index ¶
- type CallerAgent
- type PrometheusSLOGenerator
- func (p PrometheusSLOGenerator) GenerateFromK8sV1(ctx context.Context, spec kubernetesv1.PrometheusServiceLevel) (*model.PromSLOGroupResult, error)
- func (p PrometheusSLOGenerator) GenerateFromOpenSLOV1Alpha(ctx context.Context, spec openslov1alpha.SLO) (*model.PromSLOGroupResult, error)
- func (p PrometheusSLOGenerator) GenerateFromRaw(ctx context.Context, data []byte) (*model.PromSLOGroupResult, error)
- func (p PrometheusSLOGenerator) GenerateFromSlothV1(ctx context.Context, spec prometheusv1.Spec) (*model.PromSLOGroupResult, error)
- func (p PrometheusSLOGenerator) WriteResultAsK8sObjects(ctx context.Context, k8sTransformerPluginID string, k8sMeta model.K8sMeta, ...) error
- func (p PrometheusSLOGenerator) WriteResultAsK8sPrometheusOperator(ctx context.Context, k8sMeta model.K8sMeta, slo model.PromSLOGroupResult, ...) error
- func (p PrometheusSLOGenerator) WriteResultAsPrometheusStd(ctx context.Context, slo model.PromSLOGroupResult, w io.Writer) error
- type PrometheusSLOGeneratorConfig
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CallerAgent ¶
type CallerAgent string
CallerAgent is the agent calling the library.
const ( // CallerAgentCLI is the caller agent when using sloth as CLI. CallerAgentCLI CallerAgent = "cli" // CallerAgentCLI is the caller agent when using sloth as API. CallerAgentAPI CallerAgent = "api" )
type PrometheusSLOGenerator ¶
type PrometheusSLOGenerator struct {
// contains filtered or unexported fields
}
PrometheusSLOGenerator is a Prometheus SLO rules generator from the Sloth supported SLO definitions.
func NewPrometheusSLOGenerator ¶
func NewPrometheusSLOGenerator(config PrometheusSLOGeneratorConfig) (*PrometheusSLOGenerator, error)
func (PrometheusSLOGenerator) GenerateFromK8sV1 ¶
func (p PrometheusSLOGenerator) GenerateFromK8sV1(ctx context.Context, spec kubernetesv1.PrometheusServiceLevel) (*model.PromSLOGroupResult, error)
GenerateFromK8sV1 generates SLO rules from a Kubernetes Sloth CR SLO definition spec struct.
Example ¶
package main
import (
"context"
"os"
"github.com/slok/sloth/pkg/common/model"
slotk8sv1 "github.com/slok/sloth/pkg/kubernetes/api/sloth/v1"
"github.com/slok/sloth/pkg/lib"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func main() {
sloSpec := slotk8sv1.PrometheusServiceLevel{
ObjectMeta: metav1.ObjectMeta{
Name: "test01",
Labels: map[string]string{
"prometheus": "default",
},
},
Spec: slotk8sv1.PrometheusServiceLevelSpec{
Service: "svc01",
Labels: map[string]string{
"globalk1": "globalv1",
},
SLOs: []slotk8sv1.SLO{
{
Name: "slo01",
Objective: 99.9,
Labels: map[string]string{
"slo01k1": "slo01v1",
},
SLI: slotk8sv1.SLI{Events: &slotk8sv1.SLIEvents{
ErrorQuery: `sum(rate(http_request_duration_seconds_count{job="myservice",code=~"(5..|429)"}[{{.window}}]))`,
TotalQuery: `sum(rate(http_request_duration_seconds_count{job="myservice"}[{{.window}}]))`,
}},
Alerting: slotk8sv1.Alerting{
Name: "myServiceAlert",
Labels: map[string]string{
"alert01k1": "alert01v1",
},
Annotations: map[string]string{
"alert02k1": "alert02v1",
},
PageAlert: slotk8sv1.Alert{},
TicketAlert: slotk8sv1.Alert{},
},
},
},
},
}
ctx := context.Background()
gen, err := lib.NewPrometheusSLOGenerator(lib.PrometheusSLOGeneratorConfig{
ExtraLabels: map[string]string{"source": "slothlib-example"},
})
if err != nil {
panic(err)
}
// Generate SLO and write result.
slo, err := gen.GenerateFromK8sV1(ctx, sloSpec)
if err != nil {
panic(err)
}
kmeta := model.K8sMeta{
Name: "sloth-slo-gen-" + sloSpec.ObjectMeta.Name,
Namespace: sloSpec.ObjectMeta.Namespace,
}
err = gen.WriteResultAsK8sPrometheusOperator(ctx, kmeta, *slo, os.Stdout)
if err != nil {
panic(err)
}
}
Output:
func (PrometheusSLOGenerator) GenerateFromOpenSLOV1Alpha ¶
func (p PrometheusSLOGenerator) GenerateFromOpenSLOV1Alpha(ctx context.Context, spec openslov1alpha.SLO) (*model.PromSLOGroupResult, error)
GenerateFromOpenSLOV1Alpha generates SLO rules from an OpenSLO SLO definition spec struct.
func (PrometheusSLOGenerator) GenerateFromRaw ¶
func (p PrometheusSLOGenerator) GenerateFromRaw(ctx context.Context, data []byte) (*model.PromSLOGroupResult, error)
GenerateFromRaw generates SLO rules from raw data, it will infer what type of SLO spec receives. This method is the most generic one as the user doesn't need to know what type of SLO spec is using. For more custom programmatic usage use the other Go struct API spec generators.
Example ¶
package main
import (
"context"
"os"
"github.com/slok/sloth/pkg/lib"
)
func main() {
sloSpec := []byte(`
---
version: "prometheus/v1"
service: "myservice"
labels:
owner: "myteam"
repo: "myorg/myservice"
tier: "2"
slos:
# We allow failing (5xx and 429) 1 request every 1000 requests (99.9%).
- name: "requests-availability"
objective: 99.9
description: "Common SLO based on availability for HTTP request responses."
labels:
category: availability
sli:
events:
error_query: sum(rate(http_request_duration_seconds_count{job="myservice",code=~"(5..|429)"}[{{.window}}]))
total_query: sum(rate(http_request_duration_seconds_count{job="myservice"}[{{.window}}]))
alerting:
name: "MyServiceHighErrorRate"
labels:
category: "availability"
annotations:
# Overwrite default Sloth SLO alert summmary on ticket and page alerts.
summary: "High error rate on 'myservice' requests responses"
page_alert:
labels:
severity: "pageteam"
routing_key: "myteam"
ticket_alert:
labels:
severity: "slack"
slack_channel: "#alerts-myteam"
`)
ctx := context.Background()
gen, err := lib.NewPrometheusSLOGenerator(lib.PrometheusSLOGeneratorConfig{
ExtraLabels: map[string]string{"source": "slothlib-example"},
})
if err != nil {
panic(err)
}
// Generate SLO and write result.
slo, err := gen.GenerateFromRaw(ctx, sloSpec)
if err != nil {
panic(err)
}
err = gen.WriteResultAsPrometheusStd(ctx, *slo, os.Stdout)
if err != nil {
panic(err)
}
}
Output:
func (PrometheusSLOGenerator) GenerateFromSlothV1 ¶
func (p PrometheusSLOGenerator) GenerateFromSlothV1(ctx context.Context, spec prometheusv1.Spec) (*model.PromSLOGroupResult, error)
GenerateFromSlothV1 generates SLOs from a Sloth Prometheus SLO definition spec struct.
Example ¶
package main
import (
"context"
"os"
"github.com/slok/sloth/pkg/lib"
slothprometheusv1 "github.com/slok/sloth/pkg/prometheus/api/v1"
)
func main() {
sloSpec := slothprometheusv1.Spec{
Service: "myservice",
Labels: map[string]string{
"owner": "myteam",
"repo": "myorg/myservice",
"tier": "2",
},
SLOs: []slothprometheusv1.SLO{
{
Name: "requests-availability",
Objective: 99.9,
Description: "Common SLO based on availability for HTTP request responses.",
SLI: slothprometheusv1.SLI{
Events: &slothprometheusv1.SLIEvents{
ErrorQuery: `sum(rate(http_request_duration_seconds_count{job="myservice",code=~"(5..|429)"}[{{.window}}]))`,
TotalQuery: `sum(rate(http_request_duration_seconds_count{job="myservice"}[{{.window}}]))`,
},
},
Alerting: slothprometheusv1.Alerting{
Name: "MyServiceHighErrorRate",
Labels: map[string]string{"category": "availability"},
Annotations: map[string]string{"summary": "High error rate on 'myservice' requests responses"},
PageAlert: slothprometheusv1.Alert{
Labels: map[string]string{
"severity": "page",
"routing_key": "myteam",
},
},
TicketAlert: slothprometheusv1.Alert{
Labels: map[string]string{
"severity": "slack",
"slack_channel": "#alerts-myteam",
},
},
},
},
},
}
ctx := context.Background()
gen, err := lib.NewPrometheusSLOGenerator(lib.PrometheusSLOGeneratorConfig{
ExtraLabels: map[string]string{"source": "slothlib-example"},
})
if err != nil {
panic(err)
}
// Generate SLO and write result.
slo, err := gen.GenerateFromSlothV1(ctx, sloSpec)
if err != nil {
panic(err)
}
err = gen.WriteResultAsPrometheusStd(ctx, *slo, os.Stdout)
if err != nil {
panic(err)
}
}
Output:
func (PrometheusSLOGenerator) WriteResultAsK8sObjects ¶ added in v0.16.0
func (p PrometheusSLOGenerator) WriteResultAsK8sObjects(ctx context.Context, k8sTransformerPluginID string, k8sMeta model.K8sMeta, slo model.PromSLOGroupResult, w io.Writer) error
WriteResultAsK8sObjects writes the SLO results into the writer as Kubernetes objects using a custom K8s transformer plugin.
func (PrometheusSLOGenerator) WriteResultAsK8sPrometheusOperator ¶
func (p PrometheusSLOGenerator) WriteResultAsK8sPrometheusOperator(ctx context.Context, k8sMeta model.K8sMeta, slo model.PromSLOGroupResult, w io.Writer) error
WriteResultAsK8sPrometheusOperator writes the SLO results into the writer as a Prometheus Operator CRD file. More information in: https://prometheus-operator.dev/docs/api-reference/api/#monitoring.coreos.com/v1.PrometheusRule.
func (PrometheusSLOGenerator) WriteResultAsPrometheusStd ¶
func (p PrometheusSLOGenerator) WriteResultAsPrometheusStd(ctx context.Context, slo model.PromSLOGroupResult, w io.Writer) error
WriteResultAsPrometheusStd writes the SLO results into the writer as a Prometheus standard rules file. More information in:
type PrometheusSLOGeneratorConfig ¶
type PrometheusSLOGeneratorConfig struct {
// WindowsFS is the FS where custom SLO definition period windows exist (When not set default Sloth windows will be used).
WindowsFS fs.FS
// PluginsFS are the FSs where custom SLO and SLI plugins exist.
PluginsFS []fs.FS
// StrictPlugins makes the plugin loader fail when a plugin can't be loaded.
StrictPlugins bool
// DefaultSLOPeriod is the default SLO period to use when not specified in the SLO definition.
DefaultSLOPeriod time.Duration
// DisableDefaultPlugins disables the default SLO plugins, normally used along with custom SLO plugins to fully customize Sloth behavior.
DisableDefaultPlugins bool
// CMDSLOPlugins are SLO plugins defined at app level, in other words, they will be executed on all SLOs unless these override the SLO plugin chain.
CMDSLOPlugins []model.PromSLOPluginMetadata
// ExtraLabels are labels that will be added to all SLOs.
ExtraLabels map[string]string
// CallerAgent is the agent calling the library (The identity or form of calling it).
CallerAgent CallerAgent
// Logger is the logger to use for the library.
Logger log.Logger
}
PrometheusSLOGenerator is the configuration for the Prometheus SLO generator.