mirror of https://github.com/fatedier/frp
update for metric
parent
634e048d0c
commit
8b2cde3a30
|
@ -42,13 +42,14 @@ func RunDashboardServer(addr string, port int64) (err error) {
|
||||||
router.GET("/api/proxy/udp", apiProxyUdp)
|
router.GET("/api/proxy/udp", apiProxyUdp)
|
||||||
router.GET("/api/proxy/http", apiProxyHttp)
|
router.GET("/api/proxy/http", apiProxyHttp)
|
||||||
router.GET("/api/proxy/https", apiProxyHttps)
|
router.GET("/api/proxy/https", apiProxyHttps)
|
||||||
router.GET("/api/proxy/flow/:name", apiProxyFlow)
|
router.GET("/api/proxy/traffic/:name", apiProxyTraffic)
|
||||||
|
|
||||||
// view, see dashboard_view.go
|
// view
|
||||||
//router.GET("/favicon.ico", http.FileServer(assets.FileSystem))
|
|
||||||
router.Handler("GET", "/favicon.ico", http.FileServer(assets.FileSystem))
|
router.Handler("GET", "/favicon.ico", http.FileServer(assets.FileSystem))
|
||||||
router.Handler("GET", "/static", http.StripPrefix("/static/", http.FileServer(assets.FileSystem)))
|
router.Handler("GET", "/static/*filepath", http.StripPrefix("/static/", http.FileServer(assets.FileSystem)))
|
||||||
//router.GET("/", use(viewDashboard, basicAuth))
|
router.HandlerFunc("GET", "/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
http.Redirect(w, r, "/static/", http.StatusMovedPermanently)
|
||||||
|
})
|
||||||
|
|
||||||
address := fmt.Sprintf("%s:%d", addr, port)
|
address := fmt.Sprintf("%s:%d", addr, port)
|
||||||
server := &http.Server{
|
server := &http.Server{
|
||||||
|
|
|
@ -41,8 +41,8 @@ type ServerInfoResp struct {
|
||||||
MaxPoolCount int64 `json:"max_pool_count"`
|
MaxPoolCount int64 `json:"max_pool_count"`
|
||||||
HeartBeatTimeout int64 `json:"heart_beat_timeout"`
|
HeartBeatTimeout int64 `json:"heart_beat_timeout"`
|
||||||
|
|
||||||
TotalFlowIn int64 `json:"total_flow_in"`
|
TotalTrafficIn int64 `json:"total_traffic_in"`
|
||||||
TotalFlowOut int64 `json:"total_flow_out"`
|
TotalTrafficOut int64 `json:"total_traffic_out"`
|
||||||
CurConns int64 `json:"cur_conns"`
|
CurConns int64 `json:"cur_conns"`
|
||||||
ClientCounts int64 `json:"client_counts"`
|
ClientCounts int64 `json:"client_counts"`
|
||||||
ProxyTypeCounts map[string]int64 `json:"proxy_type_count"`
|
ProxyTypeCounts map[string]int64 `json:"proxy_type_count"`
|
||||||
|
@ -68,8 +68,8 @@ func apiServerInfo(w http.ResponseWriter, r *http.Request, _ httprouter.Params)
|
||||||
MaxPoolCount: cfg.MaxPoolCount,
|
MaxPoolCount: cfg.MaxPoolCount,
|
||||||
HeartBeatTimeout: cfg.HeartBeatTimeout,
|
HeartBeatTimeout: cfg.HeartBeatTimeout,
|
||||||
|
|
||||||
TotalFlowIn: serverStats.TotalFlowIn,
|
TotalTrafficIn: serverStats.TotalTrafficIn,
|
||||||
TotalFlowOut: serverStats.TotalFlowOut,
|
TotalTrafficOut: serverStats.TotalTrafficOut,
|
||||||
CurConns: serverStats.CurConns,
|
CurConns: serverStats.CurConns,
|
||||||
ClientCounts: serverStats.ClientCounts,
|
ClientCounts: serverStats.ClientCounts,
|
||||||
ProxyTypeCounts: serverStats.ProxyTypeCounts,
|
ProxyTypeCounts: serverStats.ProxyTypeCounts,
|
||||||
|
@ -81,9 +81,10 @@ func apiServerInfo(w http.ResponseWriter, r *http.Request, _ httprouter.Params)
|
||||||
|
|
||||||
// Get proxy info.
|
// Get proxy info.
|
||||||
type ProxyStatsInfo struct {
|
type ProxyStatsInfo struct {
|
||||||
|
Name string `json:"name"`
|
||||||
Conf config.ProxyConf `json:"conf"`
|
Conf config.ProxyConf `json:"conf"`
|
||||||
TodayFlowIn int64 `json:"today_flow_in"`
|
TodayTrafficIn int64 `json:"today_traffic_in"`
|
||||||
TodayFlowOut int64 `json:"today_flow_out"`
|
TodayTrafficOut int64 `json:"today_traffic_out"`
|
||||||
CurConns int64 `json:"cur_conns"`
|
CurConns int64 `json:"cur_conns"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
|
@ -172,43 +173,44 @@ func getProxyStatsByType(proxyType string) (proxyInfos []*ProxyStatsInfo) {
|
||||||
} else {
|
} else {
|
||||||
proxyInfo.Status = consts.Offline
|
proxyInfo.Status = consts.Offline
|
||||||
}
|
}
|
||||||
proxyInfo.TodayFlowIn = ps.TodayFlowIn
|
proxyInfo.TodayTrafficIn = ps.TodayTrafficIn
|
||||||
proxyInfo.TodayFlowOut = ps.TodayFlowOut
|
proxyInfo.TodayTrafficOut = ps.TodayTrafficOut
|
||||||
proxyInfo.CurConns = ps.CurConns
|
proxyInfo.CurConns = ps.CurConns
|
||||||
|
proxyInfo.Name = ps.Name
|
||||||
proxyInfos = append(proxyInfos, proxyInfo)
|
proxyInfos = append(proxyInfos, proxyInfo)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// api/proxy/:name/flow
|
// api/proxy/traffic/:name
|
||||||
type GetProxyFlowResp struct {
|
type GetProxyTrafficResp struct {
|
||||||
GeneralResponse
|
GeneralResponse
|
||||||
|
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
FlowIn []int64 `json:"flow_in"`
|
TrafficIn []int64 `json:"traffic_in"`
|
||||||
FlowOut []int64 `json:"flow_out"`
|
TrafficOut []int64 `json:"traffic_out"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiProxyFlow(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
func apiProxyTraffic(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
||||||
var (
|
var (
|
||||||
buf []byte
|
buf []byte
|
||||||
res GetProxyFlowResp
|
res GetProxyTrafficResp
|
||||||
)
|
)
|
||||||
name := params.ByName("name")
|
name := params.ByName("name")
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
log.Info("Http response [/api/proxy/flow/:name]: code [%d]", res.Code)
|
log.Info("Http response [/api/proxy/traffic/:name]: code [%d]", res.Code)
|
||||||
}()
|
}()
|
||||||
log.Info("Http request: [/api/proxy/flow/:name]")
|
log.Info("Http request: [/api/proxy/traffic/:name]")
|
||||||
|
|
||||||
res.Name = name
|
res.Name = name
|
||||||
proxyFlowInfo := StatsGetProxyFlow(name)
|
proxyTrafficInfo := StatsGetProxyTraffic(name)
|
||||||
if proxyFlowInfo == nil {
|
if proxyTrafficInfo == nil {
|
||||||
res.Code = 1
|
res.Code = 1
|
||||||
res.Msg = "no proxy info found"
|
res.Msg = "no proxy info found"
|
||||||
} else {
|
} else {
|
||||||
res.FlowIn = proxyFlowInfo.FlowIn
|
res.TrafficIn = proxyTrafficInfo.TrafficIn
|
||||||
res.FlowOut = proxyFlowInfo.FlowOut
|
res.TrafficOut = proxyTrafficInfo.TrafficOut
|
||||||
}
|
}
|
||||||
|
|
||||||
buf, _ = json.Marshal(&res)
|
buf, _ = json.Marshal(&res)
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
// Copyright 2016 fatedier, fatedier@gmail.com
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package server
|
|
||||||
|
|
||||||
/*
|
|
||||||
import (
|
|
||||||
"html/template"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/fatedier/frp/src/assets"
|
|
||||||
"github.com/fatedier/frp/src/models/metric"
|
|
||||||
"github.com/fatedier/frp/src/utils/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func viewDashboard(w http.ResponseWriter, r *http.Request) {
|
|
||||||
metrics := metric.GetAllProxyMetrics()
|
|
||||||
dashboardTpl, err := assets.ReadFile("index.html")
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, "get dashboard template file error", http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t := template.Must(template.New("index.html").Delims("<<<", ">>>").Parse(dashboardTpl))
|
|
||||||
|
|
||||||
err = t.Execute(w, metrics)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("parse template file [index.html] error: %v", err)
|
|
||||||
http.Error(w, "parse template file error", http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
|
@ -28,8 +28,8 @@ const (
|
||||||
var globalStats *ServerStatistics
|
var globalStats *ServerStatistics
|
||||||
|
|
||||||
type ServerStatistics struct {
|
type ServerStatistics struct {
|
||||||
TotalFlowIn metric.DateCounter
|
TotalTrafficIn metric.DateCounter
|
||||||
TotalFlowOut metric.DateCounter
|
TotalTrafficOut metric.DateCounter
|
||||||
CurConns metric.Counter
|
CurConns metric.Counter
|
||||||
|
|
||||||
ClientCounts metric.Counter
|
ClientCounts metric.Counter
|
||||||
|
@ -42,15 +42,15 @@ type ServerStatistics struct {
|
||||||
|
|
||||||
type ProxyStatistics struct {
|
type ProxyStatistics struct {
|
||||||
ProxyType string
|
ProxyType string
|
||||||
FlowIn metric.DateCounter
|
TrafficIn metric.DateCounter
|
||||||
FlowOut metric.DateCounter
|
TrafficOut metric.DateCounter
|
||||||
CurConns metric.Counter
|
CurConns metric.Counter
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
globalStats = &ServerStatistics{
|
globalStats = &ServerStatistics{
|
||||||
TotalFlowIn: metric.NewDateCounter(ReserveDays),
|
TotalTrafficIn: metric.NewDateCounter(ReserveDays),
|
||||||
TotalFlowOut: metric.NewDateCounter(ReserveDays),
|
TotalTrafficOut: metric.NewDateCounter(ReserveDays),
|
||||||
CurConns: metric.NewCounter(),
|
CurConns: metric.NewCounter(),
|
||||||
|
|
||||||
ClientCounts: metric.NewCounter(),
|
ClientCounts: metric.NewCounter(),
|
||||||
|
@ -88,8 +88,8 @@ func StatsNewProxy(name string, proxyType string) {
|
||||||
proxyStats = &ProxyStatistics{
|
proxyStats = &ProxyStatistics{
|
||||||
ProxyType: proxyType,
|
ProxyType: proxyType,
|
||||||
CurConns: metric.NewCounter(),
|
CurConns: metric.NewCounter(),
|
||||||
FlowIn: metric.NewDateCounter(ReserveDays),
|
TrafficIn: metric.NewDateCounter(ReserveDays),
|
||||||
FlowOut: metric.NewDateCounter(ReserveDays),
|
TrafficOut: metric.NewDateCounter(ReserveDays),
|
||||||
}
|
}
|
||||||
globalStats.ProxyStatistics[name] = proxyStats
|
globalStats.ProxyStatistics[name] = proxyStats
|
||||||
}
|
}
|
||||||
|
@ -134,31 +134,31 @@ func StatsCloseConnection(name string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func StatsAddFlowIn(name string, flowIn int64) {
|
func StatsAddTrafficIn(name string, trafficIn int64) {
|
||||||
if config.ServerCommonCfg.DashboardPort != 0 {
|
if config.ServerCommonCfg.DashboardPort != 0 {
|
||||||
globalStats.TotalFlowIn.Inc(flowIn)
|
globalStats.TotalTrafficIn.Inc(trafficIn)
|
||||||
|
|
||||||
globalStats.mu.Lock()
|
globalStats.mu.Lock()
|
||||||
defer globalStats.mu.Unlock()
|
defer globalStats.mu.Unlock()
|
||||||
|
|
||||||
proxyStats, ok := globalStats.ProxyStatistics[name]
|
proxyStats, ok := globalStats.ProxyStatistics[name]
|
||||||
if ok {
|
if ok {
|
||||||
proxyStats.FlowIn.Inc(flowIn)
|
proxyStats.TrafficIn.Inc(trafficIn)
|
||||||
globalStats.ProxyStatistics[name] = proxyStats
|
globalStats.ProxyStatistics[name] = proxyStats
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func StatsAddFlowOut(name string, flowOut int64) {
|
func StatsAddTrafficOut(name string, trafficOut int64) {
|
||||||
if config.ServerCommonCfg.DashboardPort != 0 {
|
if config.ServerCommonCfg.DashboardPort != 0 {
|
||||||
globalStats.TotalFlowOut.Inc(flowOut)
|
globalStats.TotalTrafficOut.Inc(trafficOut)
|
||||||
|
|
||||||
globalStats.mu.Lock()
|
globalStats.mu.Lock()
|
||||||
defer globalStats.mu.Unlock()
|
defer globalStats.mu.Unlock()
|
||||||
|
|
||||||
proxyStats, ok := globalStats.ProxyStatistics[name]
|
proxyStats, ok := globalStats.ProxyStatistics[name]
|
||||||
if ok {
|
if ok {
|
||||||
proxyStats.FlowOut.Inc(flowOut)
|
proxyStats.TrafficOut.Inc(trafficOut)
|
||||||
globalStats.ProxyStatistics[name] = proxyStats
|
globalStats.ProxyStatistics[name] = proxyStats
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,8 +166,8 @@ func StatsAddFlowOut(name string, flowOut int64) {
|
||||||
|
|
||||||
// Functions for getting server stats.
|
// Functions for getting server stats.
|
||||||
type ServerStats struct {
|
type ServerStats struct {
|
||||||
TotalFlowIn int64
|
TotalTrafficIn int64
|
||||||
TotalFlowOut int64
|
TotalTrafficOut int64
|
||||||
CurConns int64
|
CurConns int64
|
||||||
ClientCounts int64
|
ClientCounts int64
|
||||||
ProxyTypeCounts map[string]int64
|
ProxyTypeCounts map[string]int64
|
||||||
|
@ -177,8 +177,8 @@ func StatsGetServer() *ServerStats {
|
||||||
globalStats.mu.Lock()
|
globalStats.mu.Lock()
|
||||||
defer globalStats.mu.Unlock()
|
defer globalStats.mu.Unlock()
|
||||||
s := &ServerStats{
|
s := &ServerStats{
|
||||||
TotalFlowIn: globalStats.TotalFlowIn.TodayCount(),
|
TotalTrafficIn: globalStats.TotalTrafficIn.TodayCount(),
|
||||||
TotalFlowOut: globalStats.TotalFlowOut.TodayCount(),
|
TotalTrafficOut: globalStats.TotalTrafficOut.TodayCount(),
|
||||||
CurConns: globalStats.CurConns.Count(),
|
CurConns: globalStats.CurConns.Count(),
|
||||||
ClientCounts: globalStats.ClientCounts.Count(),
|
ClientCounts: globalStats.ClientCounts.Count(),
|
||||||
ProxyTypeCounts: make(map[string]int64),
|
ProxyTypeCounts: make(map[string]int64),
|
||||||
|
@ -192,8 +192,8 @@ func StatsGetServer() *ServerStats {
|
||||||
type ProxyStats struct {
|
type ProxyStats struct {
|
||||||
Name string
|
Name string
|
||||||
Type string
|
Type string
|
||||||
TodayFlowIn int64
|
TodayTrafficIn int64
|
||||||
TodayFlowOut int64
|
TodayTrafficOut int64
|
||||||
CurConns int64
|
CurConns int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,8 +210,8 @@ func StatsGetProxiesByType(proxyType string) []*ProxyStats {
|
||||||
ps := &ProxyStats{
|
ps := &ProxyStats{
|
||||||
Name: name,
|
Name: name,
|
||||||
Type: proxyStats.ProxyType,
|
Type: proxyStats.ProxyType,
|
||||||
TodayFlowIn: proxyStats.FlowIn.TodayCount(),
|
TodayTrafficIn: proxyStats.TrafficIn.TodayCount(),
|
||||||
TodayFlowOut: proxyStats.FlowOut.TodayCount(),
|
TodayTrafficOut: proxyStats.TrafficOut.TodayCount(),
|
||||||
CurConns: proxyStats.CurConns.Count(),
|
CurConns: proxyStats.CurConns.Count(),
|
||||||
}
|
}
|
||||||
res = append(res, ps)
|
res = append(res, ps)
|
||||||
|
@ -219,23 +219,23 @@ func StatsGetProxiesByType(proxyType string) []*ProxyStats {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProxyFlowInfo struct {
|
type ProxyTrafficInfo struct {
|
||||||
Name string
|
Name string
|
||||||
FlowIn []int64
|
TrafficIn []int64
|
||||||
FlowOut []int64
|
TrafficOut []int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func StatsGetProxyFlow(name string) (res *ProxyFlowInfo) {
|
func StatsGetProxyTraffic(name string) (res *ProxyTrafficInfo) {
|
||||||
globalStats.mu.Lock()
|
globalStats.mu.Lock()
|
||||||
defer globalStats.mu.Unlock()
|
defer globalStats.mu.Unlock()
|
||||||
|
|
||||||
proxyStats, ok := globalStats.ProxyStatistics[name]
|
proxyStats, ok := globalStats.ProxyStatistics[name]
|
||||||
if ok {
|
if ok {
|
||||||
res = &ProxyFlowInfo{
|
res = &ProxyTrafficInfo{
|
||||||
Name: name,
|
Name: name,
|
||||||
}
|
}
|
||||||
res.FlowIn = proxyStats.FlowIn.GetLastDaysCount(ReserveDays)
|
res.TrafficIn = proxyStats.TrafficIn.GetLastDaysCount(ReserveDays)
|
||||||
res.FlowOut = proxyStats.FlowOut.GetLastDaysCount(ReserveDays)
|
res.TrafficOut = proxyStats.TrafficOut.GetLastDaysCount(ReserveDays)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -306,7 +306,7 @@ func (pxy *UdpProxy) Run() (err error) {
|
||||||
if errRet := msg.ReadMsgInto(conn, &udpMsg); errRet != nil {
|
if errRet := msg.ReadMsgInto(conn, &udpMsg); errRet != nil {
|
||||||
pxy.Warn("read from workConn for udp error: %v", errRet)
|
pxy.Warn("read from workConn for udp error: %v", errRet)
|
||||||
conn.Close()
|
conn.Close()
|
||||||
// notity proxy to start a new work connection
|
// notify proxy to start a new work connection
|
||||||
errors.PanicToError(func() {
|
errors.PanicToError(func() {
|
||||||
pxy.checkCloseCh <- 1
|
pxy.checkCloseCh <- 1
|
||||||
})
|
})
|
||||||
|
@ -314,6 +314,7 @@ func (pxy *UdpProxy) Run() (err error) {
|
||||||
}
|
}
|
||||||
if errRet := errors.PanicToError(func() {
|
if errRet := errors.PanicToError(func() {
|
||||||
pxy.readCh <- &udpMsg
|
pxy.readCh <- &udpMsg
|
||||||
|
StatsAddTrafficOut(pxy.GetName(), int64(len(udpMsg.Content)))
|
||||||
}); errRet != nil {
|
}); errRet != nil {
|
||||||
pxy.Info("reader goroutine for udp work connection closed")
|
pxy.Info("reader goroutine for udp work connection closed")
|
||||||
return
|
return
|
||||||
|
@ -332,6 +333,7 @@ func (pxy *UdpProxy) Run() (err error) {
|
||||||
pxy.Info("sender goroutine for udp work connection closed: %v", errRet)
|
pxy.Info("sender goroutine for udp work connection closed: %v", errRet)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
StatsAddTrafficIn(pxy.GetName(), int64(len(udpMsg.Content)))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
|
@ -420,7 +422,7 @@ func HandleUserTcpConnection(pxy Proxy, userConn frpNet.Conn) {
|
||||||
StatsOpenConnection(pxy.GetName())
|
StatsOpenConnection(pxy.GetName())
|
||||||
inCount, outCount := tcp.Join(local, userConn)
|
inCount, outCount := tcp.Join(local, userConn)
|
||||||
StatsCloseConnection(pxy.GetName())
|
StatsCloseConnection(pxy.GetName())
|
||||||
StatsAddFlowIn(pxy.GetName(), inCount)
|
StatsAddTrafficIn(pxy.GetName(), inCount)
|
||||||
StatsAddFlowOut(pxy.GetName(), outCount)
|
StatsAddTrafficOut(pxy.GetName(), outCount)
|
||||||
pxy.Debug("join connections closed")
|
pxy.Debug("join connections closed")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue