github.com/go-graphite/carbonapi@v0.17.0/cmd/carbonapi/http/info_handlers.go (about) 1 package http 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "time" 8 9 "github.com/ansel1/merry" 10 uuid "github.com/satori/go.uuid" 11 12 "github.com/go-graphite/carbonapi/carbonapipb" 13 "github.com/go-graphite/carbonapi/cmd/carbonapi/config" 14 utilctx "github.com/go-graphite/carbonapi/util/ctx" 15 16 "github.com/lomik/zapwriter" 17 ) 18 19 func infoHandler(w http.ResponseWriter, r *http.Request) { 20 t0 := time.Now() 21 uuid := uuid.NewV4() 22 // TODO: Migrate to context.WithTimeout 23 // ctx, _ := context.WithTimeout(context.TODO(), config.Config.ZipperTimeout) 24 ctx := utilctx.SetUUID(r.Context(), uuid.String()) 25 username, _, _ := r.BasicAuth() 26 srcIP, srcPort := splitRemoteAddr(r.RemoteAddr) 27 format, ok, formatRaw := getFormat(r, jsonFormat) 28 29 requestHeaders := utilctx.GetLogHeaders(ctx) 30 31 accessLogger := zapwriter.Logger("access") 32 var accessLogDetails = carbonapipb.AccessLogDetails{ 33 Handler: "info", 34 Username: username, 35 CarbonapiUUID: uuid.String(), 36 URL: r.URL.RequestURI(), 37 PeerIP: srcIP, 38 PeerPort: srcPort, 39 Host: r.Host, 40 Referer: r.Referer(), 41 Format: formatRaw, 42 URI: r.RequestURI, 43 RequestHeaders: requestHeaders, 44 } 45 46 logAsError := false 47 defer func() { 48 deferredAccessLogging(accessLogger, &accessLogDetails, t0, logAsError) 49 }() 50 51 if !ok || !format.ValidFindFormat() { 52 http.Error(w, "unsupported format: "+formatRaw, http.StatusBadRequest) 53 accessLogDetails.HTTPCode = http.StatusBadRequest 54 accessLogDetails.Reason = "unsupported format: " + formatRaw 55 logAsError = true 56 return 57 } 58 59 query := r.Form["target"] 60 if len(query) == 0 { 61 http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) 62 accessLogDetails.HTTPCode = http.StatusBadRequest 63 accessLogDetails.Reason = "no target specified" 64 logAsError = true 65 return 66 } 67 68 data, stats, err := config.Config.ZipperInstance.Info(ctx, query) 69 if stats != nil { 70 accessLogDetails.ZipperRequests = stats.ZipperRequests 71 accessLogDetails.TotalMetricsCount += stats.TotalMetricsCount 72 } 73 if err != nil { 74 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 75 accessLogDetails.HTTPCode = http.StatusInternalServerError 76 accessLogDetails.Reason = err.Error() 77 logAsError = true 78 return 79 } 80 81 var b []byte 82 var err2 error 83 switch format { 84 case jsonFormat: 85 b, err2 = json.Marshal(data) 86 case protoV3Format, protoV2Format: 87 err2 = fmt.Errorf("not implemented yet") 88 default: 89 err2 = fmt.Errorf("unknown format %v", format) 90 } 91 err = merry.Wrap(err2) 92 93 if err != nil { 94 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 95 accessLogDetails.HTTPCode = http.StatusInternalServerError 96 accessLogDetails.Reason = err.Error() 97 logAsError = true 98 return 99 } 100 101 w.Header().Set(ctxHeaderUUID, uuid.String()) 102 _, _ = w.Write(b) 103 accessLogDetails.Runtime = time.Since(t0).Seconds() 104 accessLogDetails.HTTPCode = http.StatusOK 105 }