implement API /metrics (#1357)
This commit is contained in:
parent
13e48c6ca0
commit
2477dc08ec
@ -59,6 +59,7 @@ var (
|
|||||||
allowPorts string
|
allowPorts string
|
||||||
maxPoolCount int64
|
maxPoolCount int64
|
||||||
maxPortsPerClient int64
|
maxPortsPerClient int64
|
||||||
|
enableMetrics bool
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -86,6 +87,7 @@ func init() {
|
|||||||
rootCmd.PersistentFlags().StringVarP(&subDomainHost, "subdomain_host", "", "", "subdomain host")
|
rootCmd.PersistentFlags().StringVarP(&subDomainHost, "subdomain_host", "", "", "subdomain host")
|
||||||
rootCmd.PersistentFlags().StringVarP(&allowPorts, "allow_ports", "", "", "allow ports")
|
rootCmd.PersistentFlags().StringVarP(&allowPorts, "allow_ports", "", "", "allow ports")
|
||||||
rootCmd.PersistentFlags().Int64VarP(&maxPortsPerClient, "max_ports_per_client", "", 0, "max ports per client")
|
rootCmd.PersistentFlags().Int64VarP(&maxPortsPerClient, "max_ports_per_client", "", 0, "max ports per client")
|
||||||
|
rootCmd.PersistentFlags().BoolVarP(&enableMetrics, "enable_metrics", "", false, "enable metrics api for prometheus")
|
||||||
}
|
}
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
@ -173,6 +175,7 @@ func parseServerCommonCfgFromCmd() (cfg config.ServerCommonConf, err error) {
|
|||||||
cfg.LogMaxDays = logMaxDays
|
cfg.LogMaxDays = logMaxDays
|
||||||
cfg.Token = token
|
cfg.Token = token
|
||||||
cfg.SubDomainHost = subDomainHost
|
cfg.SubDomainHost = subDomainHost
|
||||||
|
cfg.EnableMetrics = enableMetrics
|
||||||
if len(allowPorts) > 0 {
|
if len(allowPorts) > 0 {
|
||||||
// e.g. 1000-2000,2001,2002,3000-4000
|
// e.g. 1000-2000,2001,2002,3000-4000
|
||||||
ports, errRet := util.ParseRangeNumbers(allowPorts)
|
ports, errRet := util.ParseRangeNumbers(allowPorts)
|
||||||
|
@ -69,6 +69,9 @@ subdomain_host = frps.com
|
|||||||
# if tcp stream multiplexing is used, default is true
|
# if tcp stream multiplexing is used, default is true
|
||||||
tcp_mux = true
|
tcp_mux = true
|
||||||
|
|
||||||
|
# if true, a /metrics API will be exposed for Prometheus
|
||||||
|
enable_metrics = false
|
||||||
|
|
||||||
# custom 404 page for HTTP requests
|
# custom 404 page for HTTP requests
|
||||||
# custom_404_page = /path/to/404.html
|
# custom_404_page = /path/to/404.html
|
||||||
|
|
||||||
|
1
go.mod
1
go.mod
@ -17,6 +17,7 @@ require (
|
|||||||
github.com/mattn/go-runewidth v0.0.4 // indirect
|
github.com/mattn/go-runewidth v0.0.4 // indirect
|
||||||
github.com/pires/go-proxyproto v0.0.0-20190111085350-4d51b51e3bfc
|
github.com/pires/go-proxyproto v0.0.0-20190111085350-4d51b51e3bfc
|
||||||
github.com/pkg/errors v0.8.0 // indirect
|
github.com/pkg/errors v0.8.0 // indirect
|
||||||
|
github.com/prometheus/client_golang v1.3.0
|
||||||
github.com/rakyll/statik v0.1.1
|
github.com/rakyll/statik v0.1.1
|
||||||
github.com/rodaine/table v1.0.0
|
github.com/rodaine/table v1.0.0
|
||||||
github.com/spf13/cobra v0.0.3
|
github.com/spf13/cobra v0.0.3
|
||||||
|
@ -135,6 +135,8 @@ type ServerCommonConf struct {
|
|||||||
// UserConnTimeout specifies the maximum time to wait for a work
|
// UserConnTimeout specifies the maximum time to wait for a work
|
||||||
// connection. By default, this value is 10.
|
// connection. By default, this value is 10.
|
||||||
UserConnTimeout int64 `json:"user_conn_timeout"`
|
UserConnTimeout int64 `json:"user_conn_timeout"`
|
||||||
|
// if true, a /metrics API will be exposed for Prometheus
|
||||||
|
EnableMetrics bool `json:"enable_metrics"`
|
||||||
// HTTPPlugins specify the server plugins support HTTP protocol.
|
// HTTPPlugins specify the server plugins support HTTP protocol.
|
||||||
HTTPPlugins map[string]plugin.HTTPPluginOptions `json:"http_plugins"`
|
HTTPPlugins map[string]plugin.HTTPPluginOptions `json:"http_plugins"`
|
||||||
}
|
}
|
||||||
@ -170,6 +172,7 @@ func GetDefaultServerConf() ServerCommonConf {
|
|||||||
HeartBeatTimeout: 90,
|
HeartBeatTimeout: 90,
|
||||||
UserConnTimeout: 10,
|
UserConnTimeout: 10,
|
||||||
Custom404Page: "",
|
Custom404Page: "",
|
||||||
|
EnableMetrics: false,
|
||||||
HTTPPlugins: make(map[string]plugin.HTTPPluginOptions),
|
HTTPPlugins: make(map[string]plugin.HTTPPluginOptions),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -369,6 +372,10 @@ func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error
|
|||||||
cfg.Custom404Page = tmpStr
|
cfg.Custom404Page = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tmpStr, ok = conf.Get("common", "enable_metrics"); ok && tmpStr == "true" {
|
||||||
|
cfg.EnableMetrics = true
|
||||||
|
}
|
||||||
|
|
||||||
if tmpStr, ok = conf.Get("common", "heartbeat_timeout"); ok {
|
if tmpStr, ok = conf.Get("common", "heartbeat_timeout"); ok {
|
||||||
v, errRet := strconv.ParseInt(tmpStr, 10, 64)
|
v, errRet := strconv.ParseInt(tmpStr, 10, 64)
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
|
@ -253,6 +253,12 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
svr.statsCollector = stats.NewInternalCollector(statsEnable)
|
svr.statsCollector = stats.NewInternalCollector(statsEnable)
|
||||||
|
|
||||||
|
if cfg.EnableMetrics {
|
||||||
|
ms := stats.NewMetricsServer(svr.statsCollector)
|
||||||
|
go ms.Serve()
|
||||||
|
log.Info("Metrics server listen on %s", "8080")
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
54
server/stats/metrics.go
Normal file
54
server/stats/metrics.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package stats
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MetricsServer is a HTTP server wrapper
|
||||||
|
type MetricsServer struct {
|
||||||
|
collector Collector
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMetricsServer creates a MetricsServer
|
||||||
|
func NewMetricsServer(c Collector) *MetricsServer {
|
||||||
|
return &MetricsServer{
|
||||||
|
collector: c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serve exposes Prometheus metrics data
|
||||||
|
func (s *MetricsServer) Serve() {
|
||||||
|
http.Handle("/metrics", promhttp.Handler())
|
||||||
|
|
||||||
|
timestampCounter := prometheus.NewCounter(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: "frps_info",
|
||||||
|
Name: "timestamp",
|
||||||
|
Help: "unix nanosec timestamp the data is collected",
|
||||||
|
})
|
||||||
|
clientCounts := prometheus.NewCounter(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Namespace: "frps_info",
|
||||||
|
Name: "client_counts",
|
||||||
|
Help: "number of connected clients",
|
||||||
|
})
|
||||||
|
prometheus.MustRegister(timestampCounter)
|
||||||
|
prometheus.MustRegister(clientCounts)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
stats := s.collector.GetServer()
|
||||||
|
timestampCounter.Add(float64(time.Now().UnixNano()))
|
||||||
|
clientCounts.Add(float64(stats.ClientCounts))
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// FIXME load from conf
|
||||||
|
http.ListenAndServe(":8080", nil)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user