mirror of
https://github.com/minio/minio.git
synced 2025-04-07 21:25:36 -04:00
Add error filter to admin trace API (#7923)
This allows MinIO to have the ability to send back only error trace
This commit is contained in:
parent
559a59220e
commit
0373a1699b
@ -1465,6 +1465,7 @@ func (a adminAPIHandlers) SetConfigKeysHandler(w http.ResponseWriter, r *http.Re
|
|||||||
func (a adminAPIHandlers) TraceHandler(w http.ResponseWriter, r *http.Request) {
|
func (a adminAPIHandlers) TraceHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := newContext(r, w, "HTTPTrace")
|
ctx := newContext(r, w, "HTTPTrace")
|
||||||
trcAll := r.URL.Query().Get("all") == "true"
|
trcAll := r.URL.Query().Get("all") == "true"
|
||||||
|
trcErr := r.URL.Query().Get("err") == "true"
|
||||||
|
|
||||||
// Validate request signature.
|
// Validate request signature.
|
||||||
adminAPIErr := checkAdminRequestAuthType(ctx, r, "")
|
adminAPIErr := checkAdminRequestAuthType(ctx, r, "")
|
||||||
@ -1487,11 +1488,15 @@ func (a adminAPIHandlers) TraceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
traceCh := make(chan interface{}, 4000)
|
traceCh := make(chan interface{}, 4000)
|
||||||
|
|
||||||
filter := func(entry interface{}) bool {
|
filter := func(entry interface{}) bool {
|
||||||
|
trcInfo := entry.(trace.Info)
|
||||||
|
if trcErr && isHTTPStatusOK(trcInfo.RespInfo.StatusCode) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if trcAll {
|
if trcAll {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
trcInfo := entry.(trace.Info)
|
|
||||||
return !strings.HasPrefix(trcInfo.ReqInfo.Path, minioReservedBucketPath)
|
return !strings.HasPrefix(trcInfo.ReqInfo.Path, minioReservedBucketPath)
|
||||||
|
|
||||||
}
|
}
|
||||||
remoteHosts := getRemoteHosts(globalEndpoints)
|
remoteHosts := getRemoteHosts(globalEndpoints)
|
||||||
peers, err := getRestClients(remoteHosts)
|
peers, err := getRestClients(remoteHosts)
|
||||||
@ -1501,7 +1506,7 @@ func (a adminAPIHandlers) TraceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
globalHTTPTrace.Subscribe(traceCh, doneCh, filter)
|
globalHTTPTrace.Subscribe(traceCh, doneCh, filter)
|
||||||
|
|
||||||
for _, peer := range peers {
|
for _, peer := range peers {
|
||||||
peer.Trace(traceCh, doneCh, trcAll)
|
peer.Trace(traceCh, doneCh, trcAll, trcErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
enc := json.NewEncoder(w)
|
enc := json.NewEncoder(w)
|
||||||
|
@ -394,3 +394,20 @@ func getHostName(r *http.Request) (hostName string) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isHTTPStatusOK(statusCode int) bool {
|
||||||
|
// List of success status.
|
||||||
|
var successStatus = []int{
|
||||||
|
http.StatusOK,
|
||||||
|
http.StatusCreated,
|
||||||
|
http.StatusAccepted,
|
||||||
|
http.StatusNoContent,
|
||||||
|
http.StatusPartialContent,
|
||||||
|
}
|
||||||
|
for _, okstatus := range successStatus {
|
||||||
|
if statusCode == okstatus {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -467,9 +467,10 @@ func (client *peerRESTClient) BackgroundHealStatus() (madmin.BgHealState, error)
|
|||||||
return state, err
|
return state, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *peerRESTClient) doTrace(traceCh chan interface{}, doneCh chan struct{}, trcAll bool) {
|
func (client *peerRESTClient) doTrace(traceCh chan interface{}, doneCh chan struct{}, trcAll, trcErr bool) {
|
||||||
values := make(url.Values)
|
values := make(url.Values)
|
||||||
values.Set(peerRESTTraceAll, strconv.FormatBool(trcAll))
|
values.Set(peerRESTTraceAll, strconv.FormatBool(trcAll))
|
||||||
|
values.Set(peerRESTTraceErr, strconv.FormatBool(trcErr))
|
||||||
|
|
||||||
// To cancel the REST request in case doneCh gets closed.
|
// To cancel the REST request in case doneCh gets closed.
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
@ -507,10 +508,10 @@ func (client *peerRESTClient) doTrace(traceCh chan interface{}, doneCh chan stru
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Trace - send http trace request to peer nodes
|
// Trace - send http trace request to peer nodes
|
||||||
func (client *peerRESTClient) Trace(traceCh chan interface{}, doneCh chan struct{}, trcAll bool) {
|
func (client *peerRESTClient) Trace(traceCh chan interface{}, doneCh chan struct{}, trcAll, trcErr bool) {
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
client.doTrace(traceCh, doneCh, trcAll)
|
client.doTrace(traceCh, doneCh, trcAll, trcErr)
|
||||||
select {
|
select {
|
||||||
case <-doneCh:
|
case <-doneCh:
|
||||||
return
|
return
|
||||||
|
@ -56,4 +56,5 @@ const (
|
|||||||
peerRESTProfiler = "profiler"
|
peerRESTProfiler = "profiler"
|
||||||
peerRESTDryRun = "dry-run"
|
peerRESTDryRun = "dry-run"
|
||||||
peerRESTTraceAll = "all"
|
peerRESTTraceAll = "all"
|
||||||
|
peerRESTTraceErr = "err"
|
||||||
)
|
)
|
||||||
|
@ -717,17 +717,23 @@ func (s *peerRESTServer) TraceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
trcAll := r.URL.Query().Get(peerRESTTraceAll) == "true"
|
trcAll := r.URL.Query().Get(peerRESTTraceAll) == "true"
|
||||||
|
trcErr := r.URL.Query().Get(peerRESTTraceErr) == "true"
|
||||||
|
|
||||||
w.Header().Set(xhttp.Connection, "close")
|
w.Header().Set(xhttp.Connection, "close")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
w.(http.Flusher).Flush()
|
w.(http.Flusher).Flush()
|
||||||
|
|
||||||
filter := func(entry interface{}) bool {
|
filter := func(entry interface{}) bool {
|
||||||
|
trcInfo := entry.(trace.Info)
|
||||||
|
|
||||||
|
if trcErr && isHTTPStatusOK(trcInfo.RespInfo.StatusCode) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if trcAll {
|
if trcAll {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
trcInfo := entry.(trace.Info)
|
|
||||||
return !strings.HasPrefix(trcInfo.ReqInfo.Path, minioReservedBucketPath)
|
return !strings.HasPrefix(trcInfo.ReqInfo.Path, minioReservedBucketPath)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doneCh := make(chan struct{})
|
doneCh := make(chan struct{})
|
||||||
|
@ -32,7 +32,7 @@ type TraceInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Trace - listen on http trace notifications.
|
// Trace - listen on http trace notifications.
|
||||||
func (adm AdminClient) Trace(allTrace bool, doneCh <-chan struct{}) <-chan TraceInfo {
|
func (adm AdminClient) Trace(allTrace, errTrace bool, doneCh <-chan struct{}) <-chan TraceInfo {
|
||||||
traceInfoCh := make(chan TraceInfo)
|
traceInfoCh := make(chan TraceInfo)
|
||||||
// Only success, start a routine to start reading line by line.
|
// Only success, start a routine to start reading line by line.
|
||||||
go func(traceInfoCh chan<- TraceInfo) {
|
go func(traceInfoCh chan<- TraceInfo) {
|
||||||
@ -40,6 +40,7 @@ func (adm AdminClient) Trace(allTrace bool, doneCh <-chan struct{}) <-chan Trace
|
|||||||
for {
|
for {
|
||||||
urlValues := make(url.Values)
|
urlValues := make(url.Values)
|
||||||
urlValues.Set("all", strconv.FormatBool(allTrace))
|
urlValues.Set("all", strconv.FormatBool(allTrace))
|
||||||
|
urlValues.Set("err", strconv.FormatBool(errTrace))
|
||||||
reqData := requestData{
|
reqData := requestData{
|
||||||
relPath: "/v1/trace",
|
relPath: "/v1/trace",
|
||||||
queryValues: urlValues,
|
queryValues: urlValues,
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/minio/minio/pkg/madmin"
|
"github.com/minio/minio/pkg/madmin"
|
||||||
@ -40,7 +41,9 @@ func main() {
|
|||||||
|
|
||||||
// Start listening on all http trace activity from all servers
|
// Start listening on all http trace activity from all servers
|
||||||
// in the minio cluster.
|
// in the minio cluster.
|
||||||
traceCh := madmClnt.Trace(false, doneCh)
|
allTrace := false
|
||||||
|
errTrace := false
|
||||||
|
traceCh := madmClnt.Trace(allTrace, errTrace, doneCh)
|
||||||
for traceInfo := range traceCh {
|
for traceInfo := range traceCh {
|
||||||
if traceInfo.Err != nil {
|
if traceInfo.Err != nil {
|
||||||
fmt.Println(traceInfo.Err)
|
fmt.Println(traceInfo.Err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user