Updated to support load balanced API Rest

- system collects all the domains, servers, and stats. /domains
- added support for a WSS state, displays on the UI
- moved all server related domain structures to ServerDomain* etc. to avoid collision with Domains
- create new Domains structure to handle Domains, Domain, Servers and Traffic at each level.
- updated initial lastUpate to the connection time rather than 0 which gave a silly duration.
- added properties for DomainTrack (Requests and Responses)
This commit is contained in:
Henry Camacho 2017-03-25 20:33:09 -05:00
parent 41adbfaef5
commit a72bbc63e4
8 changed files with 159 additions and 90 deletions

View File

@ -27,8 +27,9 @@
<th width="10%">Address</th>
<th width="10%">Xfer (in/out)</th>
<th width="10%">Req/Resp</th>
<th width="10%">Time</th>
<th width="10%">Idle</th>
<th width="5%">Duration</th>
<th width="5%">State</th>
<th width="5%">Idle</th>
<th width="1%"><center><span class="glyphicon glyphicon-option-vertical" aria-hidden="true"></span></center></th>
@ -64,6 +65,7 @@
</td>
<td>{{ s.duration | hfcduration }}</td>
<td>{{ s.server_state }}</td>
<td>{{ s.idle | hfcduration }}</td>
<td>
<span class="glyphicon glyphicon-zoom-in" title="Detail" aria-hidden="false" ng-click="triggerDetail(s.server_id)"></span>

View File

@ -1,60 +1,69 @@
package genericlistener
//DomainsAPI -- Structure to support the server API
type DomainsAPI struct {
DomainName string `json:"domain_name"`
ServerID int64 `json:"server_id"`
BytesIn int64 `json:"bytes_in"`
BytesOut int64 `json:"bytes_out"`
Requests int64 `json:"requests"`
Responses int64 `json:"responses"`
//DomainsAPI -- A collections of all the domains
//List of Domains -> DomainAPI
//DomainsAPI -> DomainServerAPI
//
//DomainServerAPI -- Container for Server Stats related to a domain
type DomainServerAPI struct {
ServerName string `json:"server_name"`
Traffic TrafficAPI `json:"traffic"`
}
//NewDomainsAPI - Constructor
func NewDomainsAPI(c *Connection, d *DomainTrack) (s *DomainsAPI) {
s = new(DomainsAPI)
s.DomainName = d.DomainName
s.ServerID = c.ConnectionID()
s.BytesIn = d.BytesIn()
s.BytesOut = d.BytesOut()
s.Requests = d.requests
s.Responses = d.responses
//NewDomainServerAPI -- Constructor
func NewDomainServerAPI(domain string, conn *Connection) (p *DomainServerAPI) {
p = new(DomainServerAPI)
dt := conn.DomainTrack[domain]
p.Traffic.BytesIn = dt.BytesIn()
p.Traffic.BytesOut = dt.BytesOut()
p.Traffic.Requests = dt.Requests()
p.Traffic.Responses = dt.Responses()
p.ServerName = conn.ServerName()
return
}
//DomainsAPIContainer -- Holder for all the Servers
type DomainsAPIContainer struct {
Domains []*DomainsAPI `json:"domains"`
}
//NewDomainsAPIContainer -- Constructor
func NewDomainsAPIContainer() (p *DomainsAPIContainer) {
p = new(DomainsAPIContainer)
p.Domains = make([]*DomainsAPI, 0)
return p
}
//DomainAPI -- Structure to support the server API
//DomainAPI -- Container for domain and related servers
type DomainAPI struct {
DomainName string `json:"domain_name"`
ServerID int64 `json:"server_id"`
BytesIn int64 `json:"bytes_in"`
BytesOut int64 `json:"bytes_out"`
Requests int64 `json:"requests"`
Responses int64 `json:"responses"`
Source string `json:"source_addr"`
TotalServers int `json:"server_total"`
Servers []*DomainServerAPI `json:"servers"`
Traffic TrafficAPI `json:"traffic"`
}
//NewDomainAPI - Constructor
func NewDomainAPI(c *Connection, d *DomainTrack) (s *DomainAPI) {
s = new(DomainAPI)
s.DomainName = d.DomainName
s.ServerID = c.ConnectionID()
s.BytesIn = d.BytesIn()
s.BytesOut = d.BytesOut()
s.Requests = d.requests
s.Responses = d.responses
s.Source = c.Source()
//NewDomainAPI -- Constructor
func NewDomainAPI(domain string, domainLoadBalance *DomainLoadBalance) (p *DomainAPI) {
p = new(DomainAPI)
for pos := range domainLoadBalance.connections {
ds := NewDomainServerAPI(domain, domainLoadBalance.connections[pos])
p.Servers = append(p.Servers, ds)
p.TotalServers++
p.Traffic.BytesIn += domainLoadBalance.connections[pos].BytesIn()
p.Traffic.BytesOut += domainLoadBalance.connections[pos].BytesOut()
p.Traffic.Requests += domainLoadBalance.connections[pos].requests
p.Traffic.Responses += domainLoadBalance.connections[pos].responses
}
return
}
//DomainsAPI -- Container for Domains
type DomainsAPI struct {
TotalDomains int `json:"domain_total"`
Domains []*DomainAPI `json:"domains"`
Traffic TrafficAPI `json:"traffic"`
}
//NewDomainsAPI -- Constructor
func NewDomainsAPI(domains map[string]*DomainLoadBalance) (p *DomainsAPI) {
p = new(DomainsAPI)
for domain := range domains {
d := NewDomainAPI(domain, domains[domain])
p.Domains = append(p.Domains, d)
p.Traffic.BytesIn += d.Traffic.BytesIn
p.Traffic.BytesOut += d.Traffic.BytesOut
p.Traffic.Requests += d.Traffic.Requests
p.Traffic.Responses += d.Traffic.Responses
}
return
}

View File

@ -4,14 +4,15 @@ import "time"
//ServerAPI -- Structure to support the server API
type ServerAPI struct {
ServerName string `json:"server_name"`
ServerID int64 `json:"server_id"`
Domains []*DomainAPI `json:"domains"`
Duration float64 `json:"duration"`
Idle float64 `json:"idle"`
BytesIn int64 `json:"bytes_in"`
BytesOut int64 `json:"bytes_out"`
Source string `json:"source_address"`
ServerName string `json:"server_name"`
ServerID int64 `json:"server_id"`
Domains []*ServerDomainAPI `json:"domains"`
Duration float64 `json:"duration"`
Idle float64 `json:"idle"`
BytesIn int64 `json:"bytes_in"`
BytesOut int64 `json:"bytes_out"`
Source string `json:"source_address"`
State bool `json:"server_state"`
}
//NewServerAPI - Constructor
@ -19,7 +20,7 @@ func NewServerAPI(c *Connection) (s *ServerAPI) {
s = new(ServerAPI)
s.ServerName = c.ServerName()
s.ServerID = c.ConnectionID()
s.Domains = make([]*DomainAPI, 0)
s.Domains = make([]*ServerDomainAPI, 0)
s.Duration = time.Since(c.ConnectTime()).Seconds()
s.Idle = time.Since(c.LastUpdate()).Seconds()
s.BytesIn = c.BytesIn()
@ -28,7 +29,7 @@ func NewServerAPI(c *Connection) (s *ServerAPI) {
for domainName := range c.DomainTrack {
domainAPI := NewDomainAPI(c, c.DomainTrack[domainName])
domainAPI := NewServerDomainAPI(c, c.DomainTrack[domainName])
s.Domains = append(s.Domains, domainAPI)
}
return

View File

@ -0,0 +1,60 @@
package genericlistener
//ServerDomainsAPI -- Structure to support the server API
type ServerDomainsAPI struct {
DomainName string `json:"domain_name"`
ServerID int64 `json:"server_id"`
BytesIn int64 `json:"bytes_in"`
BytesOut int64 `json:"bytes_out"`
Requests int64 `json:"requests"`
Responses int64 `json:"responses"`
}
//NewServerDomainsAPI - Constructor
func NewServerDomainsAPI(c *Connection, d *DomainTrack) (s *ServerDomainsAPI) {
s = new(ServerDomainsAPI)
s.DomainName = d.DomainName
s.ServerID = c.ConnectionID()
s.BytesIn = d.BytesIn()
s.BytesOut = d.BytesOut()
s.Requests = d.requests
s.Responses = d.responses
return
}
//ServerDomainsAPIContainer -- Holder for all the Servers
type ServerDomainsAPIContainer struct {
Domains []*ServerDomainsAPI `json:"domains"`
}
//NewServerDomainsAPIContainer -- Constructor
func NewServerDomainsAPIContainer() (p *ServerDomainsAPIContainer) {
p = new(ServerDomainsAPIContainer)
p.Domains = make([]*ServerDomainsAPI, 0)
return p
}
//ServerDomainAPI -- Structure to support the server API
type ServerDomainAPI struct {
DomainName string `json:"domain_name"`
ServerID int64 `json:"server_id"`
BytesIn int64 `json:"bytes_in"`
BytesOut int64 `json:"bytes_out"`
Requests int64 `json:"requests"`
Responses int64 `json:"responses"`
Source string `json:"source_addr"`
}
//NewServerDomainAPI - Constructor
func NewServerDomainAPI(c *Connection, d *DomainTrack) (s *ServerDomainAPI) {
s = new(ServerDomainAPI)
s.DomainName = d.DomainName
s.ServerID = c.ConnectionID()
s.BytesIn = d.BytesIn()
s.BytesOut = d.BytesOut()
s.Requests = d.requests
s.Responses = d.responses
s.Source = c.Source()
return
}

View File

@ -4,16 +4,17 @@ import "time"
//ServersAPI -- Structure to support the server API
type ServersAPI struct {
ServerName string `json:"server_name"`
ServerID int64 `json:"server_id"`
Domains []*DomainAPI `json:"domains"`
Duration float64 `json:"duration"`
Idle float64 `json:"idle"`
BytesIn int64 `json:"bytes_in"`
BytesOut int64 `json:"bytes_out"`
Requests int64 `json:"requests"`
Responses int64 `json:"responses"`
Source string `json:"source_address"`
ServerName string `json:"server_name"`
ServerID int64 `json:"server_id"`
Domains []*ServerDomainAPI `json:"domains"`
Duration float64 `json:"duration"`
Idle float64 `json:"idle"`
BytesIn int64 `json:"bytes_in"`
BytesOut int64 `json:"bytes_out"`
Requests int64 `json:"requests"`
Responses int64 `json:"responses"`
Source string `json:"source_address"`
State bool `json:"server_state"`
}
//NewServersAPI - Constructor
@ -21,7 +22,7 @@ func NewServersAPI(c *Connection) (s *ServersAPI) {
s = new(ServersAPI)
s.ServerName = c.ServerName()
s.ServerID = c.ConnectionID()
s.Domains = make([]*DomainAPI, 0)
s.Domains = make([]*ServerDomainAPI, 0)
s.Duration = time.Since(c.ConnectTime()).Seconds()
s.Idle = time.Since(c.LastUpdate()).Seconds()
s.BytesIn = c.BytesIn()
@ -29,10 +30,11 @@ func NewServersAPI(c *Connection) (s *ServersAPI) {
s.Requests = c.requests
s.Responses = c.responses
s.Source = c.Source()
s.State = c.State()
for d := range c.DomainTrack {
dt := c.DomainTrack[d]
domainAPI := NewDomainAPI(c, dt)
domainAPI := NewServerDomainAPI(c, dt)
s.Domains = append(s.Domains, domainAPI)
}
return

View File

@ -98,18 +98,7 @@ func getDomainsEndpoint(w http.ResponseWriter, r *http.Request) {
serverStatus.AdminStats.IncRequests()
domainsContainer := NewDomainsAPIContainer()
for domain := range connectionTable.domains {
domainLB := connectionTable.domains[domain]
conns := domainLB.Connections()
for pos := range conns {
conn := conns[pos]
domainAPI := NewDomainsAPI(conn, conn.DomainTrack[domain])
domainsContainer.Domains = append(domainsContainer.Domains, domainAPI)
}
}
domainsContainer := NewDomainsAPI(connectionTable.domains)
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
@ -139,11 +128,11 @@ func getDomainEndpoint(w http.ResponseWriter, r *http.Request) {
env.ErrorURI = r.RequestURI
env.ErrorDescription = "domain-name not found"
} else {
var domainAPIContainer []*DomainAPI
var domainAPIContainer []*ServerDomainAPI
conns := domainLB.Connections()
for pos := range conns {
conn := conns[pos]
domainAPI := NewDomainAPI(conn, conn.DomainTrack[domainName])
domainAPI := NewServerDomainAPI(conn, conn.DomainTrack[domainName])
domainAPIContainer = append(domainAPIContainer, domainAPI)
}
env.Result = domainAPIContainer

View File

@ -12,11 +12,6 @@ import (
"git.daplie.com/Daplie/go-rvpn-server/rvpn/packer"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 4096,
WriteBufferSize: 4096,
}
// Connection track websocket and faciliates in and out data
type Connection struct {
mutex sync.Mutex
@ -91,6 +86,7 @@ func NewConnection(connectionTable *Table, conn *websocket.Conn, remoteAddress s
p.initialDomains = initialDomains
p.connectionTrack = connectionTrack
p.DomainTrack = make(map[string]*DomainTrack)
p.lastUpdate = time.Now()
for _, domain := range initialDomains {
p.AddTrackedDomain(string(domain.(string)))

View File

@ -49,3 +49,13 @@ func (c *DomainTrack) AddRequests() {
func (c *DomainTrack) AddResponses() {
c.responses = c.responses + 1
}
//Requests -- Property
func (c *DomainTrack) Requests() int64 {
return c.requests
}
//Responses -- Property
func (c *DomainTrack) Responses() int64 {
return c.responses
}