diff --git a/server/dashboard.go b/server/dashboard.go index 3c77875c..1516f489 100644 --- a/server/dashboard.go +++ b/server/dashboard.go @@ -40,6 +40,10 @@ func RunDashboardServer(addr string, port int) (err error) { // api, see dashboard_api.go router.GET("/api/serverinfo", frpNet.HttprouterBasicAuth(apiServerInfo, user, passwd)) + router.GET("/api/proxy/tcp/:name", frpNet.HttprouterBasicAuth(apiProxyTcpByName, user, passwd)) + router.GET("/api/proxy/udp/:name", frpNet.HttprouterBasicAuth(apiProxyUdpByName, user, passwd)) + router.GET("/api/proxy/http/:name", frpNet.HttprouterBasicAuth(apiProxyHttpByName, user, passwd)) + router.GET("/api/proxy/https/:name", frpNet.HttprouterBasicAuth(apiProxyHttpsByName, user, passwd)) router.GET("/api/proxy/tcp", frpNet.HttprouterBasicAuth(apiProxyTcp, user, passwd)) router.GET("/api/proxy/udp", frpNet.HttprouterBasicAuth(apiProxyUdp, user, passwd)) router.GET("/api/proxy/http", frpNet.HttprouterBasicAuth(apiProxyHttp, user, passwd)) diff --git a/server/dashboard_api.go b/server/dashboard_api.go index 3f9acd0f..967b0176 100644 --- a/server/dashboard_api.go +++ b/server/dashboard_api.go @@ -189,6 +189,119 @@ func getProxyStatsByType(proxyType string) (proxyInfos []*ProxyStatsInfo) { return } +// Get proxy info by name. +type GetProxyStatsResp struct { + GeneralResponse + + Name string `json:"name"` + Conf config.ProxyConf `json:"conf"` + TodayTrafficIn int64 `json:"today_traffic_in"` + TodayTrafficOut int64 `json:"today_traffic_out"` + CurConns int64 `json:"cur_conns"` + LastStartTime string `json:"last_start_time"` + LastCloseTime string `json:"last_close_time"` + Status string `json:"status"` +} + +// api/proxy/tcp/:name +func apiProxyTcpByName(w http.ResponseWriter, r *http.Request, params httprouter.Params) { + var ( + buf []byte + res GetProxyStatsResp + ) + name := params.ByName("name") + + defer func() { + log.Info("Http response [/api/proxy/tcp/:name]: code [%d]", res.Code) + }() + log.Info("Http request: [/api/proxy/tcp/:name]") + + res = getProxyStatsByTypeAndName(consts.TcpProxy, name) + + buf, _ = json.Marshal(&res) + w.Write(buf) +} + +// api/proxy/udp/:name +func apiProxyUdpByName(w http.ResponseWriter, r *http.Request, params httprouter.Params) { + var ( + buf []byte + res GetProxyStatsResp + ) + name := params.ByName("name") + + defer func() { + log.Info("Http response [/api/proxy/udp/:name]: code [%d]", res.Code) + }() + log.Info("Http request: [/api/proxy/udp/:name]") + + res = getProxyStatsByTypeAndName(consts.UdpProxy, name) + + buf, _ = json.Marshal(&res) + w.Write(buf) +} + +// api/proxy/http/:name +func apiProxyHttpByName(w http.ResponseWriter, r *http.Request, params httprouter.Params) { + var ( + buf []byte + res GetProxyStatsResp + ) + name := params.ByName("name") + + defer func() { + log.Info("Http response [/api/proxy/http/:name]: code [%d]", res.Code) + }() + log.Info("Http request: [/api/proxy/http/:name]") + + res = getProxyStatsByTypeAndName(consts.HttpProxy, name) + + buf, _ = json.Marshal(&res) + w.Write(buf) +} + +// api/proxy/https/:name +func apiProxyHttpsByName(w http.ResponseWriter, r *http.Request, params httprouter.Params) { + var ( + buf []byte + res GetProxyStatsResp + ) + name := params.ByName("name") + + defer func() { + log.Info("Http response [/api/proxy/https/:name]: code [%d]", res.Code) + }() + log.Info("Http request: [/api/proxy/https/:name]") + + res = getProxyStatsByTypeAndName(consts.HttpsProxy, name) + + buf, _ = json.Marshal(&res) + w.Write(buf) +} + +func getProxyStatsByTypeAndName(proxyType string, proxyName string) (proxyInfo GetProxyStatsResp) { + proxyInfo.Name = proxyName + ps := StatsGetProxiesByTypeAndName(proxyType, proxyName) + if ps == nil { + proxyInfo.Code = 1 + proxyInfo.Msg = "no proxy info found" + } else { + if pxy, ok := ServerService.pxyManager.GetByName(proxyName); ok { + proxyInfo.Conf = pxy.GetConf() + proxyInfo.Status = consts.Online + } else { + proxyInfo.Status = consts.Offline + } + proxyInfo.TodayTrafficIn = ps.TodayTrafficIn + proxyInfo.TodayTrafficOut = ps.TodayTrafficOut + proxyInfo.CurConns = ps.CurConns + proxyInfo.LastStartTime = ps.LastStartTime + proxyInfo.LastCloseTime = ps.LastCloseTime + } + + return +} + // api/proxy/traffic/:name type GetProxyTrafficResp struct { GeneralResponse diff --git a/server/metric.go b/server/metric.go index 0e1680ca..990d26f9 100644 --- a/server/metric.go +++ b/server/metric.go @@ -263,6 +263,37 @@ func StatsGetProxiesByType(proxyType string) []*ProxyStats { return res } +func StatsGetProxiesByTypeAndName(proxyType string, proxyName string) (res *ProxyStats) { + globalStats.mu.Lock() + defer globalStats.mu.Unlock() + + for name, proxyStats := range globalStats.ProxyStatistics { + if proxyStats.ProxyType != proxyType { + continue + } + + if name != proxyName { + continue + } + + res = &ProxyStats{ + Name: name, + Type: proxyStats.ProxyType, + TodayTrafficIn: proxyStats.TrafficIn.TodayCount(), + TodayTrafficOut: proxyStats.TrafficOut.TodayCount(), + CurConns: proxyStats.CurConns.Count(), + } + if !proxyStats.LastStartTime.IsZero() { + res.LastStartTime = proxyStats.LastStartTime.Format("01-02 15:04:05") + } + if !proxyStats.LastCloseTime.IsZero() { + res.LastCloseTime = proxyStats.LastCloseTime.Format("01-02 15:04:05") + } + break + } + return +} + type ProxyTrafficInfo struct { Name string TrafficIn []int64