use cpu info

master
sre 3 years ago
parent ef09916b55
commit 9d6cd0c0a6

@ -0,0 +1,77 @@
package main
import (
"flag"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
"net/http"
"sreExporter/collector"
"strings"
)
var (
metricsPath string = "https://github.com/strive-after/demo-exporter"
version string = "v1.0"
listenAddress string
help bool
disable string //命令行传入的需要关闭的指标
disables []string //处理命令行传入的根据,分割为一个切片做处理
)
func init() {
flag.StringVar(&listenAddress, "addr", ":9100", "addr")
flag.BoolVar(&help, "h", false, "help")
flag.StringVar(&disable, "disable", "", "关闭的指标收集器")
}
// main函数作为总入口 提供web url /metrices以及访问/的时候提供一些基本介绍
func main() {
flag.Parse()
if help {
flag.Usage()
return
}
disables = strings.Split(disable, ",")
//手动开关
//通过用户输入的我们做关闭
for scraper, _ := range collector.Scrapers {
for _, v := range disables {
if v == scraper.Name() {
collector.Scrapers[scraper] = false
break
}
}
}
//访问/的时候返回一些基础提示
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`<html>
<head><title>` + collector.Name() + `</title></head>
<body>
<h1><a style="text-decoration:none" href=''>` + collector.Name() + `</a></h1>
<p><a href='` + metricsPath + `'>Metrics</a></p>
<h2>Build</h2>
<pre>` + version + `</pre>
</body>
</html>`))
})
//根据开关来判断指标的是否需要收集 这里只有代码里面的判断 用户手动开关还未做
enabledScrapers := []collector.Scraper{}
for scraper, enabled := range collector.Scrapers {
if enabled {
log.Info("Scraper enabled ", scraper.Name())
enabledScrapers = append(enabledScrapers, scraper)
}
}
//注册自身采集器
exporter := collector.New(collector.NewMetrics(), enabledScrapers)
prometheus.MustRegister(exporter)
http.Handle("/metrics", promhttp.Handler())
//监听端口
if err := http.ListenAndServe(listenAddress, nil); err != nil {
log.Printf("Error occur when start server %v", err)
}
}

@ -1,77 +1,97 @@
package main
import (
"flag"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
"net/http"
"sreExporter/collector"
"strings"
"sync"
)
var (
metricsPath string = "https://github.com/strive-after/demo-exporter"
version string = "v1.0"
listenAddress string
help bool
disable string //命令行传入的需要关闭的指标
disables []string //处理命令行传入的根据,分割为一个切片做处理
)
type ClusterManager struct {
sync.Mutex
Zone string
metricMapCounters map[string]string
metricMapGauges map[string]string
}
func init() {
flag.StringVar(&listenAddress, "addr", ":9100", "addr")
flag.BoolVar(&help, "h", false, "help")
flag.StringVar(&disable, "disable", "", "关闭的指标收集器")
// Simulate prepare the data
func (c *ClusterManager) ReallyExpensiveAssessmentOfTheSystemState() (
metrics map[string]float64,
) {
metrics = map[string]float64{
"oom_crashes_total": 42.00,
"ram_usage": 6.023e23,
}
return
}
// main函数作为总入口 提供web url /metrices以及访问/的时候提供一些基本介绍
func main() {
flag.Parse()
if help {
flag.Usage()
return
// 通过NewClusterManager方法创建结构体及对应的指标信息代码如下所示。
// NewClusterManager creates the two Descs OOMCountDesc and RAMUsageDesc. Note
// that the zone is set as a ConstLabel. (It's different in each instance of the
// ClusterManager, but constant over the lifetime of an instance.) Then there is
// a variable label "host", since we want to partition the collected metrics by
// host. Since all Descs created in this way are consistent across instances,
// with a guaranteed distinction by the "zone" label, we can register different
// ClusterManager instances with the same registry.
func NewClusterManager(zone string) *ClusterManager {
return &ClusterManager{
Zone: zone,
metricMapGauges: map[string]string{
"ram_usage": "ram_usage_bytes",
},
metricMapCounters: map[string]string{
"oom_crashes": "oom_crashes_total",
},
}
disables = strings.Split(disable, ",")
//手动开关
//通过用户输入的我们做关闭
for scraper, _ := range collector.Scrapers {
for _, v := range disables {
if v == scraper.Name() {
collector.Scrapers[scraper] = false
break
}
}
}
//首先采集器必须实现prometheus.Collector接口也必须实现Describe和Collect方法。实现接口的代码如下所示。
// Describe simply sends the two Descs in the struct to the channel.
// Prometheus的注册器调用Collect来抓取参数
// 将收集的数据传递到Channel中并返回
// 收集的指标信息来自Describe可以并发地执行抓取工作但是必须要保证线程的安全
func (c *ClusterManager) Describe(ch chan<- *prometheus.Desc) {
// prometheus.NewDesc(prometheus.BuildFQName(namespace, "", metricName), docString, labels, nil)
for _, v := range c.metricMapGauges {
ch <- prometheus.NewDesc(prometheus.BuildFQName(c.Zone, "", v), v, nil, nil)
}
//访问/的时候返回一些基础提示
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`<html>
<head><title>` + collector.Name() + `</title></head>
<body>
<h1><a style="text-decoration:none" href=''>` + collector.Name() + `</a></h1>
<p><a href='` + metricsPath + `'>Metrics</a></p>
<h2>Build</h2>
<pre>` + version + `</pre>
</body>
</html>`))
})
//根据开关来判断指标的是否需要收集 这里只有代码里面的判断 用户手动开关还未做
enabledScrapers := []collector.Scraper{}
for scraper, enabled := range collector.Scrapers {
if enabled {
log.Info("Scraper enabled ", scraper.Name())
enabledScrapers = append(enabledScrapers, scraper)
}
for _, v := range c.metricMapCounters {
ch <- prometheus.NewDesc(prometheus.BuildFQName(c.Zone, "", v), v, nil, nil)
}
}
//注册自身采集器
exporter := collector.New(collector.NewMetrics(), enabledScrapers)
prometheus.MustRegister(exporter)
// Collect方法是核心它会抓取你需要的所有数据根据需求对其进行分析然后将指标发送回客户端库。
// 用于传递所有可能指标的定义描述符
// 可以在程序运行期间添加新的描述,收集新的指标信息
// 重复的描述符将被忽略。两个不同的Collector不要设置相同的描述符
func (c *ClusterManager) Collect(ch chan<- prometheus.Metric) {
c.Lock()
defer c.Unlock()
m := c.ReallyExpensiveAssessmentOfTheSystemState()
for k, v := range m {
t := prometheus.GaugeValue
if c.metricMapCounters[k] != "" {
t = prometheus.CounterValue
}
c.registerConstMetric(ch, k, v, t)
}
}
http.Handle("/metrics", promhttp.Handler())
//监听端口
if err := http.ListenAndServe(listenAddress, nil); err != nil {
log.Printf("Error occur when start server %v", err)
// 用于传递所有可能指标的定义描述符给指标
func (c *ClusterManager) registerConstMetric(ch chan<- prometheus.Metric, metric string, val float64, valType prometheus.ValueType, labelValues ...string) {
descr := prometheus.NewDesc(prometheus.BuildFQName(c.Zone, "", metric), metric, nil, nil)
if m, err := prometheus.NewConstMetric(descr, valType, val, labelValues...); err == nil {
ch <- m
}
}
func main() {
workerCA := NewClusterManager("xiaodian")
reg := prometheus.NewPedanticRegistry()
reg.MustRegister(workerCA)
//当promhttp.Handler()被执行时所有metric被序列化输出。题外话其实输出的格式既可以是plain text也可以是protocol Buffers。
http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))
http.ListenAndServe("9100", nil)
}

@ -16,7 +16,7 @@ cd sreExporter
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 GO111MODULE=on go mod tidy
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 GO111MODULE=on go build -o exporter.bin main.go
docker build -t sre/exporter:arm64 .
kubectl rollout restart deployment -n sre ginbase
kubectl rollout restart deployment -n kuboard sre-exporter
./exporter
```

Loading…
Cancel
Save