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  }