github.com/m3db/m3@v1.5.0/src/query/api/v1/handler/prom/common.go (about)

     1  // Copyright (c) 2020 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package prom
    22  
    23  import (
    24  	"math"
    25  	"net/http"
    26  	"time"
    27  
    28  	xhttp "github.com/m3db/m3/src/x/net/http"
    29  
    30  	jsoniter "github.com/json-iterator/go"
    31  	promql "github.com/prometheus/prometheus/promql/parser"
    32  	promstorage "github.com/prometheus/prometheus/storage"
    33  )
    34  
    35  // All of this is taken from prometheus to ensure we have consistent return/error
    36  // formats with prometheus.
    37  // https://github.com/prometheus/prometheus/blob/43acd0e2e93f9f70c49b2267efa0124f1e759e86/web/api/v1/api.go#L1097
    38  
    39  var (
    40  	minTime = time.Unix(math.MinInt64/1000+62135596801, 0).UTC()
    41  	maxTime = time.Unix(math.MaxInt64/1000-62135596801, 999999999).UTC()
    42  
    43  	minTimeFormatted = minTime.Format(time.RFC3339Nano)
    44  	maxTimeFormatted = maxTime.Format(time.RFC3339Nano)
    45  )
    46  
    47  type status string
    48  
    49  const (
    50  	statusSuccess status = "success"
    51  	statusError   status = "error"
    52  )
    53  
    54  type errorType string
    55  
    56  // QueryData struct to be used when responding from HTTP handler.
    57  type QueryData struct {
    58  	ResultType promql.ValueType `json:"resultType"`
    59  	Result     promql.Value     `json:"result"`
    60  }
    61  
    62  type response struct {
    63  	Status    status      `json:"status"`
    64  	Data      interface{} `json:"data,omitempty"`
    65  	ErrorType errorType   `json:"errorType,omitempty"`
    66  	Error     string      `json:"error,omitempty"`
    67  	Warnings  []string    `json:"warnings,omitempty"`
    68  }
    69  
    70  // Respond responds with HTTP OK status code and writes response JSON to response body.
    71  func Respond(w http.ResponseWriter, data interface{}, warnings promstorage.Warnings) error {
    72  	statusMessage := statusSuccess
    73  	var warningStrings []string
    74  	for _, warning := range warnings {
    75  		warningStrings = append(warningStrings, warning.Error())
    76  	}
    77  	w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeJSON)
    78  	json := jsoniter.ConfigCompatibleWithStandardLibrary
    79  	return json.NewEncoder(w).Encode(&response{
    80  		Status:   statusMessage,
    81  		Data:     data,
    82  		Warnings: warningStrings,
    83  	})
    84  }