Skip to content

Commit

Permalink
Add option for skipping metrics in telemetry plugin (#1417)
Browse files Browse the repository at this point in the history
Signed-off-by: Ondrej Fabry <ofabry@cisco.com>
  • Loading branch information
ondrej-fabry authored Jul 24, 2019
1 parent ed83a66 commit 483f36e
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 157 deletions.
10 changes: 10 additions & 0 deletions plugins/telemetry/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,22 @@ package telemetry

import "time"

const (
// default period between updates
defaultUpdatePeriod = time.Second * 30
// minimum period between updates
minimumUpdatePeriod = time.Second * 1
)

// Config file representation for telemetry plugin
type Config struct {
// Custom polling interval, default value is 30s
PollingInterval time.Duration `json:"polling-interval"`
// Allows to disable plugin
Disabled bool `json:"disabled"`
// Skip collecting some of the metrics:
// runtime, memory, buffers, nodes, interfaces
Skipped []string `json:"skipped"`
}

func defaultConfig() *Config {
Expand Down
310 changes: 160 additions & 150 deletions plugins/telemetry/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,192 +318,202 @@ func (p *Plugin) registerPrometheus() error {
func (p *Plugin) updatePrometheus(ctx context.Context) {
p.tracef("running update")

// Update runtime
runtimeInfo, err := p.handler.GetRuntimeInfo(ctx)
if err != nil {
p.Log.Errorf("GetRuntimeInfo failed: %v", err)
} else {
p.tracef("runtime info: %+v", runtimeInfo)
for _, thread := range runtimeInfo.GetThreads() {
for _, item := range thread.Items {
stats, ok := p.runtimeStats[item.Name]
if !p.skipped[runtimeMetricsNamespace] {
// Update runtime
runtimeInfo, err := p.handler.GetRuntimeInfo(ctx)
if err != nil {
p.Log.Errorf("GetRuntimeInfo failed: %v", err)
} else {
p.tracef("runtime info: %+v", runtimeInfo)
for _, thread := range runtimeInfo.GetThreads() {
for _, item := range thread.Items {
stats, ok := p.runtimeStats[item.Name]
if !ok {
stats = &runtimeStats{
threadID: thread.ID,
threadName: thread.Name,
itemName: item.Name,
metrics: map[string]prometheus.Gauge{},
}

// add gauges with corresponding labels into vectors
for k, vec := range p.runtimeGaugeVecs {
stats.metrics[k], err = vec.GetMetricWith(prometheus.Labels{
runtimeItemLabel: item.Name,
runtimeThreadLabel: thread.Name,
runtimeThreadIDLabel: strconv.Itoa(int(thread.ID)),
})
if err != nil {
p.Log.Error(err)
}
}
}

stats.metrics[runtimeCallsMetric].Set(float64(item.Calls))
stats.metrics[runtimeVectorsMetric].Set(float64(item.Vectors))
stats.metrics[runtimeSuspendsMetric].Set(float64(item.Suspends))
stats.metrics[runtimeClocksMetric].Set(item.Clocks)
stats.metrics[runtimeVectorsPerCallMetric].Set(item.VectorsPerCall)
}
}
}
}

if !p.skipped[buffersMetricsNamespace] {
// Update buffers
buffersInfo, err := p.handler.GetBuffersInfo(ctx)
if err != nil {
p.Log.Errorf("GetBuffersInfo failed: %v", err)
} else {
p.tracef("buffers info: %+v", buffersInfo)
for _, item := range buffersInfo.GetItems() {
stats, ok := p.buffersStats[item.Name]
if !ok {
stats = &runtimeStats{
threadID: thread.ID,
threadName: thread.Name,
itemName: item.Name,
metrics: map[string]prometheus.Gauge{},
stats = &buffersStats{
threadID: item.ThreadID,
itemName: item.Name,
itemIndex: item.Index,
metrics: map[string]prometheus.Gauge{},
}

// add gauges with corresponding labels into vectors
for k, vec := range p.runtimeGaugeVecs {
for k, vec := range p.buffersGaugeVecs {
stats.metrics[k], err = vec.GetMetricWith(prometheus.Labels{
runtimeItemLabel: item.Name,
runtimeThreadLabel: thread.Name,
runtimeThreadIDLabel: strconv.Itoa(int(thread.ID)),
buffersThreadIDLabel: strconv.Itoa(int(item.ThreadID)),
buffersItemLabel: item.Name,
buffersIndexLabel: strconv.Itoa(int(item.Index)),
})
if err != nil {
p.Log.Error(err)
}
}
}

stats.metrics[runtimeCallsMetric].Set(float64(item.Calls))
stats.metrics[runtimeVectorsMetric].Set(float64(item.Vectors))
stats.metrics[runtimeSuspendsMetric].Set(float64(item.Suspends))
stats.metrics[runtimeClocksMetric].Set(item.Clocks)
stats.metrics[runtimeVectorsPerCallMetric].Set(item.VectorsPerCall)
stats.metrics[buffersSizeMetric].Set(float64(item.Size))
stats.metrics[buffersAllocMetric].Set(float64(item.Alloc))
stats.metrics[buffersFreeMetric].Set(float64(item.Free))
stats.metrics[buffersNumAllocMetric].Set(float64(item.NumAlloc))
stats.metrics[buffersNumFreeMetric].Set(float64(item.NumFree))
}
}
}

// Update buffers
buffersInfo, err := p.handler.GetBuffersInfo(ctx)
if err != nil {
p.Log.Errorf("GetBuffersInfo failed: %v", err)
} else {
p.tracef("buffers info: %+v", buffersInfo)
for _, item := range buffersInfo.GetItems() {
stats, ok := p.buffersStats[item.Name]
if !ok {
stats = &buffersStats{
threadID: item.ThreadID,
itemName: item.Name,
itemIndex: item.Index,
metrics: map[string]prometheus.Gauge{},
}

// add gauges with corresponding labels into vectors
for k, vec := range p.buffersGaugeVecs {
stats.metrics[k], err = vec.GetMetricWith(prometheus.Labels{
buffersThreadIDLabel: strconv.Itoa(int(item.ThreadID)),
buffersItemLabel: item.Name,
buffersIndexLabel: strconv.Itoa(int(item.Index)),
})
if err != nil {
p.Log.Error(err)
if !p.skipped[memoryMetricsNamespace] {
// Update memory
memoryInfo, err := p.handler.GetMemory(ctx)
if err != nil {
p.Log.Errorf("GetMemory failed: %v", err)
} else {
p.tracef("memory info: %+v", memoryInfo)
for _, thread := range memoryInfo.GetThreads() {
stats, ok := p.memoryStats[thread.Name]
if !ok {
stats = &memoryStats{
threadName: thread.Name,
threadID: thread.ID,
metrics: map[string]prometheus.Gauge{},
}
}
}

stats.metrics[buffersSizeMetric].Set(float64(item.Size))
stats.metrics[buffersAllocMetric].Set(float64(item.Alloc))
stats.metrics[buffersFreeMetric].Set(float64(item.Free))
stats.metrics[buffersNumAllocMetric].Set(float64(item.NumAlloc))
stats.metrics[buffersNumFreeMetric].Set(float64(item.NumFree))
}
}

// Update memory
memoryInfo, err := p.handler.GetMemory(ctx)
if err != nil {
p.Log.Errorf("GetMemory failed: %v", err)
} else {
p.tracef("memory info: %+v", memoryInfo)
for _, thread := range memoryInfo.GetThreads() {
stats, ok := p.memoryStats[thread.Name]
if !ok {
stats = &memoryStats{
threadName: thread.Name,
threadID: thread.ID,
metrics: map[string]prometheus.Gauge{},
}

// add gauges with corresponding labels into vectors
for k, vec := range p.memoryGaugeVecs {
stats.metrics[k], err = vec.GetMetricWith(prometheus.Labels{
memoryThreadLabel: thread.Name,
memoryThreadIDLabel: strconv.Itoa(int(thread.ID)),
})
if err != nil {
p.Log.Error(err)
// add gauges with corresponding labels into vectors
for k, vec := range p.memoryGaugeVecs {
stats.metrics[k], err = vec.GetMetricWith(prometheus.Labels{
memoryThreadLabel: thread.Name,
memoryThreadIDLabel: strconv.Itoa(int(thread.ID)),
})
if err != nil {
p.Log.Error(err)
}
}
}
}

stats.metrics[memoryObjectsMetric].Set(float64(thread.Objects))
stats.metrics[memoryUsedMetric].Set(float64(thread.Used))
stats.metrics[memoryTotalMetric].Set(float64(thread.Total))
stats.metrics[memoryFreeMetric].Set(float64(thread.Free))
stats.metrics[memoryReclaimedMetric].Set(float64(thread.Reclaimed))
stats.metrics[memoryOverheadMetric].Set(float64(thread.Overhead))
stats.metrics[memorySizeMetric].Set(float64(thread.Size))
stats.metrics[memoryPagesMetric].Set(float64(thread.Pages))
stats.metrics[memoryObjectsMetric].Set(float64(thread.Objects))
stats.metrics[memoryUsedMetric].Set(float64(thread.Used))
stats.metrics[memoryTotalMetric].Set(float64(thread.Total))
stats.metrics[memoryFreeMetric].Set(float64(thread.Free))
stats.metrics[memoryReclaimedMetric].Set(float64(thread.Reclaimed))
stats.metrics[memoryOverheadMetric].Set(float64(thread.Overhead))
stats.metrics[memorySizeMetric].Set(float64(thread.Size))
stats.metrics[memoryPagesMetric].Set(float64(thread.Pages))
}
}
}

// Update node counters
nodeCountersInfo, err := p.handler.GetNodeCounters(ctx)
if err != nil {
p.Log.Errorf("GetNodeCounters failed: %v", err)
} else {
p.tracef("node counters info: %+v", nodeCountersInfo)
for _, item := range nodeCountersInfo.GetCounters() {
stats, ok := p.nodeCounterStats[item.Name]
if !ok {
stats = &nodeCounterStats{
itemName: item.Name,
metrics: map[string]prometheus.Gauge{},
}
if !p.skipped[nodeMetricsNamespace] {
// Update node counters
nodeCountersInfo, err := p.handler.GetNodeCounters(ctx)
if err != nil {
p.Log.Errorf("GetNodeCounters failed: %v", err)
} else {
p.tracef("node counters info: %+v", nodeCountersInfo)
for _, item := range nodeCountersInfo.GetCounters() {
stats, ok := p.nodeCounterStats[item.Name]
if !ok {
stats = &nodeCounterStats{
itemName: item.Name,
metrics: map[string]prometheus.Gauge{},
}

// add gauges with corresponding labels into vectors
for k, vec := range p.nodeCounterGaugeVecs {
stats.metrics[k], err = vec.GetMetricWith(prometheus.Labels{
nodeCounterItemLabel: item.Node,
nodeCounterReasonLabel: item.Name,
})
if err != nil {
p.Log.Error(err)
// add gauges with corresponding labels into vectors
for k, vec := range p.nodeCounterGaugeVecs {
stats.metrics[k], err = vec.GetMetricWith(prometheus.Labels{
nodeCounterItemLabel: item.Node,
nodeCounterReasonLabel: item.Name,
})
if err != nil {
p.Log.Error(err)
}
}
}
}

stats.metrics[nodeCounterCounterMetric].Set(float64(item.Value))
stats.metrics[nodeCounterCounterMetric].Set(float64(item.Value))
}
}
}

// Update interface counters
ifStats, err := p.handler.GetInterfaceStats(ctx)
if err != nil {
p.Log.Errorf("GetInterfaceStats failed: %v", err)
return
} else {
p.tracef("interface stats: %+v", ifStats)
if ifStats == nil {
if !p.skipped[ifMetricsNamespace] {
// Update interface counters
ifStats, err := p.handler.GetInterfaceStats(ctx)
if err != nil {
p.Log.Errorf("GetInterfaceStats failed: %v", err)
return
}
for _, item := range ifStats.Interfaces {
stats, ok := p.ifCounterStats[item.InterfaceName]
if !ok {
stats = &ifCounterStats{
name: item.InterfaceName,
metrics: map[string]prometheus.Gauge{},
}
} else {
p.tracef("interface stats: %+v", ifStats)
if ifStats == nil {
return
}
for _, item := range ifStats.Interfaces {
stats, ok := p.ifCounterStats[item.InterfaceName]
if !ok {
stats = &ifCounterStats{
name: item.InterfaceName,
metrics: map[string]prometheus.Gauge{},
}

// add gauges with corresponding labels into vectors
for k, vec := range p.ifCounterGaugeVecs {
stats.metrics[k], err = vec.GetMetricWith(prometheus.Labels{
ifCounterNameLabel: item.InterfaceName,
ifCounterIndexLabel: fmt.Sprint(item.InterfaceIndex),
})
if err != nil {
p.Log.Error(err)
// add gauges with corresponding labels into vectors
for k, vec := range p.ifCounterGaugeVecs {
stats.metrics[k], err = vec.GetMetricWith(prometheus.Labels{
ifCounterNameLabel: item.InterfaceName,
ifCounterIndexLabel: fmt.Sprint(item.InterfaceIndex),
})
if err != nil {
p.Log.Error(err)
}
}
}
}

stats.metrics[ifCounterRxPackets].Set(float64(item.RxPackets))
stats.metrics[ifCounterRxBytes].Set(float64(item.RxBytes))
stats.metrics[ifCounterRxErrors].Set(float64(item.RxErrors))
stats.metrics[ifCounterTxPackets].Set(float64(item.TxPackets))
stats.metrics[ifCounterTxBytes].Set(float64(item.TxBytes))
stats.metrics[ifCounterTxErrors].Set(float64(item.TxErrors))
stats.metrics[ifCounterDrops].Set(float64(item.Drops))
stats.metrics[ifCounterPunts].Set(float64(item.Punts))
stats.metrics[ifCounterIP4].Set(float64(item.IP4))
stats.metrics[ifCounterIP6].Set(float64(item.IP6))
stats.metrics[ifCounterRxNoBuf].Set(float64(item.RxNoBuf))
stats.metrics[ifCounterRxMiss].Set(float64(item.RxMiss))
stats.metrics[ifCounterRxPackets].Set(float64(item.RxPackets))
stats.metrics[ifCounterRxBytes].Set(float64(item.RxBytes))
stats.metrics[ifCounterRxErrors].Set(float64(item.RxErrors))
stats.metrics[ifCounterTxPackets].Set(float64(item.TxPackets))
stats.metrics[ifCounterTxBytes].Set(float64(item.TxBytes))
stats.metrics[ifCounterTxErrors].Set(float64(item.TxErrors))
stats.metrics[ifCounterDrops].Set(float64(item.Drops))
stats.metrics[ifCounterPunts].Set(float64(item.Punts))
stats.metrics[ifCounterIP4].Set(float64(item.IP4))
stats.metrics[ifCounterIP6].Set(float64(item.IP6))
stats.metrics[ifCounterRxNoBuf].Set(float64(item.RxNoBuf))
stats.metrics[ifCounterRxMiss].Set(float64(item.RxMiss))
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions plugins/telemetry/telemetry.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ polling-interval: 30000000000

# If set to true, telemetry plugin is disabled.
disabled: false

# Skip collecting some of the metrics.
# runtime, memory, buffers, nodes, interfaces
#skipped: [nodes]
Loading

0 comments on commit 483f36e

Please sign in to comment.