update for metric

pull/316/head
fatedier 2017-03-27 01:39:05 +08:00
parent 634e048d0c
commit 8b2cde3a30
5 changed files with 79 additions and 116 deletions

View File

@ -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{

View File

@ -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)

View File

@ -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)
}
}
*/

View File

@ -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
} }

View File

@ -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")
} }