mirror of https://github.com/hashicorp/consul
Add doc links for metrics endpoint
parent
5b998cacb1
commit
c1c883f441
|
@ -54,6 +54,21 @@ func (s *HTTPServer) AgentSelf(resp http.ResponseWriter, req *http.Request) (int
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *HTTPServer) AgentMetrics(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
|
// Fetch the ACL token, if any, and enforce agent policy.
|
||||||
|
var token string
|
||||||
|
s.parseToken(req, &token)
|
||||||
|
acl, err := s.agent.resolveToken(token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if acl != nil && !acl.AgentRead(s.agent.config.NodeName) {
|
||||||
|
return nil, errPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.agent.MemSink.DisplayMetrics(resp, req)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *HTTPServer) AgentReload(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
func (s *HTTPServer) AgentReload(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
if req.Method != "PUT" {
|
if req.Method != "PUT" {
|
||||||
resp.WriteHeader(http.StatusMethodNotAllowed)
|
resp.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
|
|
|
@ -239,6 +239,34 @@ func TestAgent_Self_ACLDeny(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAgent_Metrics_ACLDeny(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
a := NewTestAgent(t.Name(), TestACLConfig())
|
||||||
|
defer a.Shutdown()
|
||||||
|
|
||||||
|
t.Run("no token", func(t *testing.T) {
|
||||||
|
req, _ := http.NewRequest("GET", "/v1/agent/metrics", nil)
|
||||||
|
if _, err := a.srv.AgentSelf(nil, req); !isPermissionDenied(err) {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("agent master token", func(t *testing.T) {
|
||||||
|
req, _ := http.NewRequest("GET", "/v1/agent/metrics?token=towel", nil)
|
||||||
|
if _, err := a.srv.AgentSelf(nil, req); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("read-only token", func(t *testing.T) {
|
||||||
|
ro := makeReadOnlyAgentACL(t, a.srv)
|
||||||
|
req, _ := http.NewRequest("GET", fmt.Sprintf("/v1/agent/metrics?token=%s", ro), nil)
|
||||||
|
if _, err := a.srv.AgentSelf(nil, req); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestAgent_Reload(t *testing.T) {
|
func TestAgent_Reload(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
cfg := TestConfig()
|
cfg := TestConfig()
|
||||||
|
|
|
@ -98,7 +98,7 @@ func (s *HTTPServer) handler(enableDebug bool) http.Handler {
|
||||||
handleFuncMetrics("/v1/agent/maintenance", s.wrap(s.AgentNodeMaintenance))
|
handleFuncMetrics("/v1/agent/maintenance", s.wrap(s.AgentNodeMaintenance))
|
||||||
handleFuncMetrics("/v1/agent/reload", s.wrap(s.AgentReload))
|
handleFuncMetrics("/v1/agent/reload", s.wrap(s.AgentReload))
|
||||||
handleFuncMetrics("/v1/agent/monitor", s.wrap(s.AgentMonitor))
|
handleFuncMetrics("/v1/agent/monitor", s.wrap(s.AgentMonitor))
|
||||||
handleFuncMetrics("/v1/agent/metrics", s.wrap(s.requireAgentRead(s.agent.MemSink.DisplayMetrics)))
|
handleFuncMetrics("/v1/agent/metrics", s.wrap(s.AgentMetrics))
|
||||||
handleFuncMetrics("/v1/agent/services", s.wrap(s.AgentServices))
|
handleFuncMetrics("/v1/agent/services", s.wrap(s.AgentServices))
|
||||||
handleFuncMetrics("/v1/agent/checks", s.wrap(s.AgentChecks))
|
handleFuncMetrics("/v1/agent/checks", s.wrap(s.AgentChecks))
|
||||||
handleFuncMetrics("/v1/agent/members", s.wrap(s.AgentMembers))
|
handleFuncMetrics("/v1/agent/members", s.wrap(s.AgentMembers))
|
||||||
|
@ -264,26 +264,6 @@ func (s *HTTPServer) wrap(handler func(resp http.ResponseWriter, req *http.Reque
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type handlerFunc func(resp http.ResponseWriter, req *http.Request) (interface{}, error)
|
|
||||||
|
|
||||||
// requireAgentRead wraps the given function, requiring a token with agent read permissions
|
|
||||||
func (s *HTTPServer) requireAgentRead(handler handlerFunc) handlerFunc {
|
|
||||||
return func(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
|
||||||
// Fetch the ACL token, if any, and enforce agent policy.
|
|
||||||
var token string
|
|
||||||
s.parseToken(req, &token)
|
|
||||||
acl, err := s.agent.resolveToken(token)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if acl != nil && !acl.AgentRead(s.agent.config.NodeName) {
|
|
||||||
return nil, errPermissionDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
return handler(resp, req)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// marshalJSON marshals the object into JSON, respecting the user's pretty-ness
|
// marshalJSON marshals the object into JSON, respecting the user's pretty-ness
|
||||||
// configuration.
|
// configuration.
|
||||||
func (s *HTTPServer) marshalJSON(req *http.Request, obj interface{}) ([]byte, error) {
|
func (s *HTTPServer) marshalJSON(req *http.Request, obj interface{}) ([]byte, error) {
|
||||||
|
|
|
@ -1345,3 +1345,4 @@ items which are reloaded include:
|
||||||
* Watches
|
* Watches
|
||||||
* HTTP Client Address
|
* HTTP Client Address
|
||||||
* <a href="#node_meta">Node Metadata</a>
|
* <a href="#node_meta">Node Metadata</a>
|
||||||
|
* <a href="#telemetry-prefix_filter">Metric Prefix Filter</a>
|
||||||
|
|
|
@ -22,7 +22,8 @@ getting a better view of what Consul is doing.
|
||||||
Additionally, if the [`telemetry` configuration options](/docs/agent/options.html#telemetry)
|
Additionally, if the [`telemetry` configuration options](/docs/agent/options.html#telemetry)
|
||||||
are provided, the telemetry information will be streamed to a
|
are provided, the telemetry information will be streamed to a
|
||||||
[statsite](http://github.com/armon/statsite) or [statsd](http://github.com/etsy/statsd) server where
|
[statsite](http://github.com/armon/statsite) or [statsd](http://github.com/etsy/statsd) server where
|
||||||
it can be aggregated and flushed to Graphite or any other metrics store.
|
it can be aggregated and flushed to Graphite or any other metrics store. This
|
||||||
|
information can also be viewed with the [metrics endpoint](/api/agent.html#view-metrics)
|
||||||
|
|
||||||
Below is sample output of a telemetry dump:
|
Below is sample output of a telemetry dump:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue