1
// Copyright 2018 The CubeFS Authors.
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
7
// http://www.apache.org/licenses/LICENSE-2.0
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
12
// implied. See the License for the specific language governing
13
// permissions and limitations under the License.
27
"github.com/cubefs/cubefs/proto"
28
"github.com/cubefs/cubefs/util/config"
29
"github.com/cubefs/cubefs/util/log"
30
"github.com/gorilla/mux"
31
"github.com/prometheus/client_golang/prometheus"
32
"github.com/prometheus/client_golang/prometheus/promhttp"
33
"github.com/prometheus/client_golang/prometheus/push"
37
PromHandlerPattern = "/metrics" // prometheus handler
38
AppName = "cfs" // app name
39
ConfigKeyExporterEnable = "exporterEnable" // exporter enable
40
ConfigKeyExporterPort = "exporterPort" // exporter port
41
ConfigKeyConsulAddr = "consulAddr" // consul addr
42
ConfigKeyConsulMeta = "consulMeta" // consul meta
43
ConfigKeyIpFilter = "ipFilter" // add ip filter
44
ConfigKeyEnablePid = "enablePid" // enable report partition id
45
ConfigKeyPushAddr = "pushAddr" // enable push data to gateway
46
ChSize = 1024 * 10 // collect chan size
63
enabledPrometheus = false
66
replacer = strings.NewReplacer("-", "_", ".", "_", " ", "_", ",", "_", ":", "_")
67
registry = prometheus.NewRegistry()
70
func metricsName(name string) string {
71
return replacer.Replace(fmt.Sprintf("%s_%s", namespace, name))
74
// Init initializes the exporter.
75
func Init(role string, cfg *config.Config) {
77
if !cfg.GetBoolWithDefault(ConfigKeyExporterEnable, true) {
78
log.LogInfof("%v exporter disabled", role)
82
EnablePid = cfg.GetBoolWithDefault(ConfigKeyEnablePid, false)
83
log.LogInfo("enable report partition id info? ", EnablePid)
85
port := cfg.GetInt64(ConfigKeyExporterPort)
88
log.LogInfof("%v exporter port set random default", port)
92
enabledPrometheus = true
94
pushAddr = cfg.GetString(ConfigKeyPushAddr)
95
log.LogInfof("pushAddr %v ", pushAddr)
100
http.Handle(PromHandlerPattern, promhttp.HandlerFor(prometheus.DefaultGatherer, promhttp.HandlerOpts{
101
Timeout: 60 * time.Second,
104
namespace = AppName + "_" + role
105
addr := fmt.Sprintf(":%d", port)
106
l, err := net.Listen("tcp", addr)
108
log.LogError("exporter tcp listen error: ", err)
112
exporterPort = int64(l.Addr().(*net.TCPAddr).Port)
115
err = http.Serve(l, nil)
117
log.LogError("exporter http serve error: ", err)
124
m := NewGauge("start_time")
125
m.Set(float64(time.Now().Unix() * 1000))
127
log.LogInfof("exporter Start: %v", exporterPort)
130
// Init initializes the exporter.
131
func InitWithRouter(role string, cfg *config.Config, router *mux.Router, exPort string) {
133
if !cfg.GetBoolWithDefault(ConfigKeyExporterEnable, true) {
134
log.LogInfof("%v metrics exporter disabled", role)
137
exporterPort, _ = strconv.ParseInt(exPort, 10, 64)
138
enabledPrometheus = true
139
router.NewRoute().Name("metrics").
140
Methods(http.MethodGet).
141
Path(PromHandlerPattern).
142
Handler(promhttp.HandlerFor(prometheus.DefaultGatherer, promhttp.HandlerOpts{
143
Timeout: 5 * time.Second,
145
namespace = AppName + "_" + role
149
m := NewGauge("start_time")
150
m.Set(float64(time.Now().Unix() * 1000))
152
log.LogInfof("exporter Start: %v %v", exporterPort, m)
155
func RegistConsul(cluster string, role string, cfg *config.Config) {
156
ipFilter := cfg.GetString(ConfigKeyIpFilter)
157
host, err := GetLocalIpAddr(ipFilter)
159
log.LogErrorf("get local ip error, %v", err.Error())
163
rawmnt := cfg.GetString("subdir")
167
mountPoint, _ := filepath.Abs(rawmnt)
168
log.LogInfof("RegistConsul:%v", enablePush)
170
log.LogWarnf("[RegisterConsul] use auto push data strategy, not register consul")
171
autoPush(pushAddr, role, cluster, host, mountPoint)
175
clustername = replacer.Replace(cluster)
176
consulAddr := cfg.GetString(ConfigKeyConsulAddr)
177
consulMeta := cfg.GetString(ConfigKeyConsulMeta)
179
if exporterPort == int64(0) {
180
exporterPort = cfg.GetInt64(ConfigKeyExporterPort)
183
if exporterPort == 0 {
184
log.LogInfo("config export port is 0, use default 17510")
188
if exporterPort != int64(0) && len(consulAddr) > 0 {
189
if ok := strings.HasPrefix(consulAddr, "http"); !ok {
190
consulAddr = "http://" + consulAddr
192
go DoConsulRegisterProc(consulAddr, AppName, role, cluster, consulMeta, host, exporterPort)
196
func autoPush(pushAddr, role, cluster, ip, mountPoint string) {
199
client := &http.Client{
200
Timeout: time.Second * 10,
203
hostname, err := os.Hostname()
205
log.LogWarnf("get host name failed %v", err)
208
pusher := push.New(pushAddr, "cbfs").
212
Grouping("role", role).
213
Grouping("cluster", cluster).
214
Grouping("pid", strconv.Itoa(pid)).
215
Grouping("commit", proto.CommitID).
216
Grouping("app", AppName).
217
Grouping("mountPoint", mountPoint).
218
Grouping("hostName", hostname)
220
log.LogInfof("start push data, ip %s, addr %s, role %s, cluster %s, mountPoint %s, hostName %s",
221
ip, pushAddr, role, cluster, mountPoint, hostname)
223
ticker := time.NewTicker(time.Second * 15)
226
if err := pusher.Push(); err != nil {
227
log.LogWarnf("push monitor data to %s err, %s", pushAddr, err.Error())
234
if !enabledPrometheus {
239
go collectHistogram()