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 package main
import ( import (
"flag"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
"net/http" "net/http"
"sreExporter/collector" "sync"
"strings"
) )
var ( type ClusterManager struct {
metricsPath string = "https://github.com/strive-after/demo-exporter" sync.Mutex
version string = "v1.0" Zone string
listenAddress string metricMapCounters map[string]string
help bool metricMapGauges map[string]string
disable string //命令行传入的需要关闭的指标 }
disables []string //处理命令行传入的根据,分割为一个切片做处理
)
func init() { // Simulate prepare the data
flag.StringVar(&listenAddress, "addr", ":9100", "addr") func (c *ClusterManager) ReallyExpensiveAssessmentOfTheSystemState() (
flag.BoolVar(&help, "h", false, "help") metrics map[string]float64,
flag.StringVar(&disable, "disable", "", "关闭的指标收集器") ) {
metrics = map[string]float64{
"oom_crashes_total": 42.00,
"ram_usage": 6.023e23,
}
return
} }
// main函数作为总入口 提供web url /metrices以及访问/的时候提供一些基本介绍 // 通过NewClusterManager方法创建结构体及对应的指标信息代码如下所示。
func main() { // NewClusterManager creates the two Descs OOMCountDesc and RAMUsageDesc. Note
flag.Parse() // that the zone is set as a ConstLabel. (It's different in each instance of the
if help { // ClusterManager, but constant over the lifetime of an instance.) Then there is
flag.Usage() // a variable label "host", since we want to partition the collected metrics by
return // 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, ",") }
//手动开关
//通过用户输入的我们做关闭 //首先采集器必须实现prometheus.Collector接口也必须实现Describe和Collect方法。实现接口的代码如下所示。
for scraper, _ := range collector.Scrapers { // Describe simply sends the two Descs in the struct to the channel.
for _, v := range disables { // Prometheus的注册器调用Collect来抓取参数
if v == scraper.Name() { // 将收集的数据传递到Channel中并返回
collector.Scrapers[scraper] = false // 收集的指标信息来自Describe可以并发地执行抓取工作但是必须要保证线程的安全
break
} 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)
} }
//访问/的时候返回一些基础提示 for _, v := range c.metricMapCounters {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { ch <- prometheus.NewDesc(prometheus.BuildFQName(c.Zone, "", v), v, nil, nil)
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)
}
} }
}
//注册自身采集器 // Collect方法是核心它会抓取你需要的所有数据根据需求对其进行分析然后将指标发送回客户端库。
exporter := collector.New(collector.NewMetrics(), enabledScrapers) // 用于传递所有可能指标的定义描述符
prometheus.MustRegister(exporter) // 可以在程序运行期间添加新的描述,收集新的指标信息
// 重复的描述符将被忽略。两个不同的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()) // 用于传递所有可能指标的定义描述符给指标
//监听端口 func (c *ClusterManager) registerConstMetric(ch chan<- prometheus.Metric, metric string, val float64, valType prometheus.ValueType, labelValues ...string) {
if err := http.ListenAndServe(listenAddress, nil); err != nil { descr := prometheus.NewDesc(prometheus.BuildFQName(c.Zone, "", metric), metric, nil, nil)
log.Printf("Error occur when start server %v", err) 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 mod tidy
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 GO111MODULE=on go build -o exporter.bin main.go CGO_ENABLED=0 GOOS=linux GOARCH=arm64 GO111MODULE=on go build -o exporter.bin main.go
docker build -t sre/exporter:arm64 . docker build -t sre/exporter:arm64 .
kubectl rollout restart deployment -n sre ginbase kubectl rollout restart deployment -n kuboard sre-exporter
./exporter ./exporter
``` ```

Loading…
Cancel
Save