Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support prometheus metrics #382

Merged
merged 4 commits into from
Sep 7, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions api/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ package api

import (
"fmt"
"net"
"net/http"

"github.com/alibaba/sentinel-golang/core/config"
"github.com/alibaba/sentinel-golang/core/log/metric"
"github.com/alibaba/sentinel-golang/core/system_metric"
metric_exporter "github.com/alibaba/sentinel-golang/exporter/metric"
"github.com/alibaba/sentinel-golang/util"
"github.com/pkg/errors"
)
Expand Down Expand Up @@ -113,6 +116,23 @@ func initCoreComponents() error {
util.StartTimeTicker()
}

if config.MetricExportHTTPAddr() != "" {
httpAddr := config.MetricExportHTTPAddr()
httpPath := config.MetricExportHTTPPath()

l, err := net.Listen("tcp", httpAddr)
if err != nil {
return fmt.Errorf("init metric exporter http server err: %s", err.Error())
}

http.Handle(httpPath, metric_exporter.HTTPHandler())
go func() {
_ = http.Serve(l, nil)
}()

return nil
}

return nil
}

Expand Down
18 changes: 18 additions & 0 deletions core/circuitbreaker/circuit_breaker.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

"github.com/alibaba/sentinel-golang/core/base"
sbase "github.com/alibaba/sentinel-golang/core/stat/base"
metric_exporter "github.com/alibaba/sentinel-golang/exporter/metric"
"github.com/alibaba/sentinel-golang/logging"
"github.com/alibaba/sentinel-golang/util"
"github.com/pkg/errors"
Expand Down Expand Up @@ -47,6 +48,17 @@ const (
Open
)

var (
stateChangeCounter = metric_exporter.NewCounter(
"circuit_breaker_state_change",
"Circuit breaker state change count",
[]string{"resource", "previous_state", "current_state"})
)

func init() {
metric_exporter.MustRegister(stateChangeCounter)
}

func newState() *State {
var state State
state = Closed
Expand Down Expand Up @@ -152,6 +164,8 @@ func (b *circuitBreakerBase) fromClosedToOpen(snapshot interface{}) bool {
for _, listener := range stateChangeListeners {
listener.OnTransformToOpen(Closed, *b.rule, snapshot)
}

stateChangeCounter.Add(float64(1), b.BoundRule().Resource, "Closed", "Open")
return true
}
return false
Expand Down Expand Up @@ -181,6 +195,8 @@ func (b *circuitBreakerBase) fromOpenToHalfOpen(ctx *base.EntryContext) bool {
return nil
})
}

stateChangeCounter.Add(float64(1), b.BoundRule().Resource, "Open", "HalfOpen")
return true
}
return false
Expand All @@ -194,6 +210,8 @@ func (b *circuitBreakerBase) fromHalfOpenToOpen(snapshot interface{}) bool {
for _, listener := range stateChangeListeners {
listener.OnTransformToOpen(HalfOpen, *b.rule, snapshot)
}

stateChangeCounter.Add(float64(1), b.BoundRule().Resource, "HalfOpen", "Open")
return true
}
return false
Expand Down
8 changes: 8 additions & 0 deletions core/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@ func LogUsePid() bool {
return globalCfg.LogUsePid()
}

func MetricExportHTTPAddr() string {
return globalCfg.MetricExportHTTPAddr()
}

func MetricExportHTTPPath() string {
return globalCfg.MetricExportHTTPPath()
}

func MetricLogFlushIntervalSec() uint32 {
return globalCfg.MetricLogFlushIntervalSec()
}
Expand Down
23 changes: 23 additions & 0 deletions core/config/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ type SentinelConfig struct {
// Type indicates the classification of the service (e.g. web service, API gateway).
Type int32
}
// Exporter represents configuration items related to exporter, like metric exporter.
Exporter ExporterConfig
// Log represents configuration items related to logging.
Log LogConfig
// Stat represents configuration items related to statistics.
Expand All @@ -46,6 +48,19 @@ type SentinelConfig struct {
UseCacheTime bool `yaml:"useCacheTime"`
}

// ExporterConfig represents configuration items related to exporter, like metric exporter.
type ExporterConfig struct {
Metric MetricExporterConfig
}

// MetricExporterConfig represents configuration of metric exporter.
type MetricExporterConfig struct {
// HTTPAddr is the http server listen address, like ":8080".
HTTPAddr string `yaml:"http_addr"`
// HTTPPath is the http request path of access metrics, like "/metrics".
HTTPPath string `yaml:"http_path"`
}

// LogConfig represent the configuration of logging in Sentinel.
type LogConfig struct {
// Logger indicates that using logger to replace default logging.
Expand Down Expand Up @@ -190,6 +205,14 @@ func (entity *Entity) LogUsePid() bool {
return entity.Sentinel.Log.UsePid
}

func (entity *Entity) MetricExportHTTPAddr() string {
return entity.Sentinel.Exporter.Metric.HTTPAddr
}

func (entity *Entity) MetricExportHTTPPath() string {
return entity.Sentinel.Exporter.Metric.HTTPPath
}

func (entity *Entity) MetricLogFlushIntervalSec() uint32 {
return entity.Sentinel.Log.Metric.FlushIntervalSec
}
Expand Down
17 changes: 15 additions & 2 deletions core/flow/traffic_shaping.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,20 @@ package flow

import (
"github.com/alibaba/sentinel-golang/core/base"
"github.com/alibaba/sentinel-golang/metrics"
metric_exporter "github.com/alibaba/sentinel-golang/exporter/metric"
)

var (
resourceFlowThresholdGauge = metric_exporter.NewGauge(
"resource_flow_threshold",
"Resource flow threshold",
[]string{"resource"})
)

func init() {
metric_exporter.MustRegister(resourceFlowThresholdGauge)
}

// TrafficShapingCalculator calculates the actual traffic shaping threshold
// based on the threshold of rule and the traffic shaping strategy.
type TrafficShapingCalculator interface {
Expand Down Expand Up @@ -74,6 +85,8 @@ func (t *TrafficShapingController) FlowCalculator() TrafficShapingCalculator {

func (t *TrafficShapingController) PerformChecking(resStat base.StatNode, batchCount uint32, flag int32) *base.TokenResult {
allowedTokens := t.flowCalculator.CalculateAllowedTokens(batchCount, flag)
metrics.SetResourceFlowThreshold(t.rule.Resource, allowedTokens)

resourceFlowThresholdGauge.Set(float64(allowedTokens), t.rule.Resource)

return t.flowChecker.DoCheck(resStat, batchCount, allowedTokens)
}
41 changes: 41 additions & 0 deletions core/stat/stat_slot.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package stat

import (
"github.com/alibaba/sentinel-golang/core/base"
metric_exporter "github.com/alibaba/sentinel-golang/exporter/metric"
"github.com/alibaba/sentinel-golang/util"
)

Expand All @@ -26,8 +27,38 @@ const (

var (
DefaultSlot = &Slot{}

passCounter = metric_exporter.NewCounter(
"pass",
"Total pass count",
[]string{"resource"})
blockCounter = metric_exporter.NewCounter(
"block",
"Total block count",
[]string{"resource", "block_type"})
completeCounter = metric_exporter.NewCounter(
"complete",
"Total complete count",
[]string{"resource"})
errorCounter = metric_exporter.NewCounter(
"error",
"Total error count",
[]string{"resource"})
rtHistogram = metric_exporter.NewHistogram(
"rt",
"Rt histogram",
[]float64{1.0, 5.0, 10.0, 50.0, 100.0, 500.0, 1000, 5000},
[]string{"resource"})
)

func init() {
metric_exporter.MustRegister(passCounter)
metric_exporter.MustRegister(blockCounter)
metric_exporter.MustRegister(completeCounter)
metric_exporter.MustRegister(errorCounter)
metric_exporter.MustRegister(rtHistogram)
}

type Slot struct {
}

Expand All @@ -44,13 +75,17 @@ func (s *Slot) OnEntryPassed(ctx *base.EntryContext) {
if ctx.Resource.FlowType() == base.Inbound {
s.recordPassFor(InboundNode(), ctx.Input.BatchCount)
}

passCounter.Add(float64(ctx.Input.BatchCount), ctx.Resource.Name())
}

func (s *Slot) OnEntryBlocked(ctx *base.EntryContext, blockError *base.BlockError) {
s.recordBlockFor(ctx.StatNode, ctx.Input.BatchCount)
if ctx.Resource.FlowType() == base.Inbound {
s.recordBlockFor(InboundNode(), ctx.Input.BatchCount)
}

blockCounter.Add(float64(ctx.Input.BatchCount), ctx.Resource.Name(), blockError.BlockType().String())
}

func (s *Slot) OnCompleted(ctx *base.EntryContext) {
Expand All @@ -60,6 +95,12 @@ func (s *Slot) OnCompleted(ctx *base.EntryContext) {
if ctx.Resource.FlowType() == base.Inbound {
s.recordCompleteFor(InboundNode(), ctx.Input.BatchCount, rt, ctx.Err())
}

completeCounter.Add(float64(ctx.Input.BatchCount), ctx.Resource.Name())
if ctx.Err() != nil {
errorCounter.Add(float64(ctx.Input.BatchCount), ctx.Resource.Name())
}
rtHistogram.Observe(float64(rt), ctx.Resource.Name())
}

func (s *Slot) recordPassFor(sn base.StatNode, count uint32) {
Expand Down
22 changes: 19 additions & 3 deletions core/system_metric/sys_metric_stat.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import (
"sync/atomic"
"time"

metric_exporter "github.com/alibaba/sentinel-golang/exporter/metric"
"github.com/alibaba/sentinel-golang/logging"
"github.com/alibaba/sentinel-golang/metrics"
"github.com/alibaba/sentinel-golang/util"
"github.com/shirou/gopsutil/v3/load"
"github.com/shirou/gopsutil/v3/mem"
Expand Down Expand Up @@ -49,6 +49,15 @@ var (
TotalMemorySize = getTotalMemorySize()

ssStopChan = make(chan struct{})

cpuRatioGauge = metric_exporter.NewGauge(
"cpu_ratio",
"Process cpu ratio",
[]string{})
processMemoryGauge = metric_exporter.NewGauge(
"process_memory_bytes",
"Process memory in bytes",
[]string{})
)

func init() {
Expand All @@ -64,6 +73,9 @@ func init() {
currentProcessOnce.Do(func() {
currentProcess.Store(p)
})

metric_exporter.MustRegister(cpuRatioGauge)
metric_exporter.MustRegister(processMemoryGauge)
}

// getMemoryStat returns the current machine's memory statistic
Expand Down Expand Up @@ -105,7 +117,9 @@ func retrieveAndUpdateMemoryStat() {
logging.Error(err, "Fail to retrieve and update cpu statistic")
return
}
metrics.SetProcessMemorySize(memoryUsedBytes)

processMemoryGauge.Set(float64(memoryUsedBytes))

currentMemoryUsage.Store(memoryUsedBytes)
}

Expand Down Expand Up @@ -161,7 +175,9 @@ func retrieveAndUpdateCpuStat() {
logging.Error(err, "Fail to retrieve and update cpu statistic")
return
}
metrics.SetCPURatio(cpuPercent)

cpuRatioGauge.Set(cpuPercent)

currentCpuUsage.Store(cpuPercent)
}

Expand Down
Loading