Skip to content
This repository was archived by the owner on Nov 7, 2022. It is now read-only.

Commit e6eac5a

Browse files
authored
receiver: Add a prototype VM metrics receiver. (#515)
1 parent 58d2c31 commit e6eac5a

File tree

9 files changed

+758
-0
lines changed

9 files changed

+758
-0
lines changed

cmd/ocagent/main.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import (
4343
"github.com/census-instrumentation/opencensus-service/receiver/jaegerreceiver"
4444
"github.com/census-instrumentation/opencensus-service/receiver/opencensusreceiver"
4545
"github.com/census-instrumentation/opencensus-service/receiver/prometheusreceiver"
46+
"github.com/census-instrumentation/opencensus-service/receiver/vmmetricsreceiver"
4647
"github.com/census-instrumentation/opencensus-service/receiver/zipkinreceiver"
4748
"github.com/census-instrumentation/opencensus-service/receiver/zipkinreceiver/zipkinscribereceiver"
4849
)
@@ -172,6 +173,15 @@ func runOCAgent() {
172173
closeFns = append(closeFns, promDoneFn)
173174
}
174175

176+
// If the VMMetrics receiver is enabled, then run it.
177+
if agentConfig.VMMetricsReceiverEnabled() {
178+
vmmDoneFn, err := runVMMetricsReceiver(viperCfg, commonMetricsSink, asyncErrorChan)
179+
if err != nil {
180+
log.Fatal(err)
181+
}
182+
closeFns = append(closeFns, vmmDoneFn)
183+
}
184+
175185
// Always cleanup finally
176186
defer func() {
177187
for _, closeFn := range closeFns {
@@ -342,3 +352,18 @@ func runPrometheusReceiver(v *viper.Viper, next consumer.MetricsConsumer, asyncE
342352
log.Print("Running Prometheus receiver")
343353
return doneFn, nil
344354
}
355+
356+
func runVMMetricsReceiver(v *viper.Viper, next consumer.MetricsConsumer, asyncErrorChan chan<- error) (doneFn func() error, err error) {
357+
vmr, err := vmmetricsreceiver.New(v.Sub("receivers.vmmetrics"), next)
358+
if err != nil {
359+
return nil, err
360+
}
361+
if err := vmr.StartMetricsReception(context.Background(), asyncErrorChan); err != nil {
362+
return nil, err
363+
}
364+
doneFn = func() error {
365+
return vmr.StopMetricsReception(context.Background())
366+
}
367+
log.Print("Running VMMetrics receiver")
368+
return doneFn, nil
369+
}

internal/config/config.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ type Receivers struct {
101101
Zipkin *ReceiverConfig `mapstructure:"zipkin"`
102102
Jaeger *ReceiverConfig `mapstructure:"jaeger"`
103103
Scribe *ScribeReceiverConfig `mapstructure:"zipkin-scribe"`
104+
VMMetrics *ReceiverConfig `mapstructure:"vmmetrics"`
104105

105106
// Prometheus contains the Prometheus configurations.
106107
// Such as:
@@ -374,6 +375,14 @@ func (c *Config) OpenCensusReceiverTLSCredentialsServerOption() (opt opencensusr
374375
return tlsCreds.ToOpenCensusReceiverServerOption()
375376
}
376377

378+
// VMMetricsReceiverEnabled returns true if Config is non-nil.
379+
func (c *Config) VMMetricsReceiverEnabled() bool {
380+
if c == nil {
381+
return false
382+
}
383+
return c.Receivers != nil && c.Receivers.VMMetrics != nil
384+
}
385+
377386
// CheckLogicalConflicts serves to catch logical errors such as
378387
// if the Zipkin receiver port conflicts with that of the exporter,
379388
// lest we'll have a self DOS because spans will be exported "out" from
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
FIXME: This will get re-written and moved.

receiver/vmmetricsreceiver/doc.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2019, OpenCensus Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Package vmmetricsreceiver has the logic for scraping VM metrics
16+
// and then passing them onto a metric consumer instance.
17+
package vmmetricsreceiver
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
receivers:
2+
vmmetrics:
3+
scrape_interval: 10s
4+
5+
zpages:
6+
port: 55679
7+
8+
exporters:
9+
prometheus:
10+
namespace: "vmmetrics_test"
11+
address: "localhost:8888"
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Copyright 2019, OpenCensus Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package vmmetricsreceiver
16+
17+
import (
18+
"context"
19+
"errors"
20+
"fmt"
21+
"runtime"
22+
"sync"
23+
"time"
24+
25+
"github.com/spf13/viper"
26+
27+
"github.com/census-instrumentation/opencensus-service/consumer"
28+
)
29+
30+
var (
31+
errAlreadyStarted = errors.New("already started")
32+
errAlreadyStopped = errors.New("already stopped")
33+
errNilMetricsConsumer = errors.New("expecting a non-nil MetricsConsumer")
34+
)
35+
36+
// Configuration defines the behavior and targets of the VM metrics scrapers.
37+
type Configuration struct {
38+
scrapeInterval time.Duration `mapstructure:"scrape_interval"`
39+
mountPoint string `mapstructure:"mount_point"`
40+
metricPrefix string `mapstructure:"metric_prefix"`
41+
}
42+
43+
// Receiver is the type used to handle metrics from VM metrics.
44+
type Receiver struct {
45+
mu sync.Mutex
46+
47+
vmc *VMMetricsCollector
48+
49+
stopOnce sync.Once
50+
startOnce sync.Once
51+
}
52+
53+
// New creates a new vmmetricsreceiver.Receiver reference.
54+
func New(v *viper.Viper, consumer consumer.MetricsConsumer) (*Receiver, error) {
55+
if consumer == nil {
56+
return nil, errNilMetricsConsumer
57+
}
58+
59+
var cfg Configuration
60+
61+
// Unmarshal our config values (using viper's mapstructure)
62+
err := v.Unmarshal(&cfg)
63+
if err != nil {
64+
return nil, fmt.Errorf("vmmetrics receiver failed to parse config: %s", err)
65+
}
66+
67+
vmc, err := NewVMMetricsCollector(cfg.scrapeInterval, cfg.mountPoint, cfg.metricPrefix, consumer)
68+
if err != nil {
69+
return nil, err
70+
}
71+
72+
vmr := &Receiver{
73+
vmc: vmc,
74+
}
75+
return vmr, nil
76+
}
77+
78+
// StartMetricsReception scrapes VM metrics based on the OS platform.
79+
func (vmr *Receiver) StartMetricsReception(ctx context.Context, asyncErrorChan chan<- error) error {
80+
vmr.mu.Lock()
81+
defer vmr.mu.Unlock()
82+
83+
var err = errAlreadyStarted
84+
vmr.startOnce.Do(func() {
85+
switch runtime.GOOS {
86+
case "linux":
87+
vmr.vmc.StartCollection()
88+
case "darwin", "freebsd", "windows":
89+
// TODO: add support for other platforms.
90+
return
91+
}
92+
93+
err = nil
94+
})
95+
return err
96+
}
97+
98+
// StopMetricsReception stops and cancels the underlying VM metrics scrapers.
99+
func (vmr *Receiver) StopMetricsReception(ctx context.Context) error {
100+
vmr.mu.Lock()
101+
defer vmr.mu.Unlock()
102+
103+
var err = errAlreadyStopped
104+
vmr.stopOnce.Do(func() {
105+
vmr.vmc.StopCollection()
106+
err = nil
107+
})
108+
return err
109+
}

0 commit comments

Comments
 (0)