github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/pkg/integrations/otsdb/writer/putmetrics.go (about) 1 /* 2 Copyright 2023. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package writer 18 19 import ( 20 "encoding/json" 21 22 jp "github.com/buger/jsonparser" 23 . "github.com/siglens/siglens/pkg/segment/utils" 24 "github.com/siglens/siglens/pkg/segment/writer" 25 "github.com/siglens/siglens/pkg/usageStats" 26 "github.com/siglens/siglens/pkg/utils" 27 log "github.com/sirupsen/logrus" 28 "github.com/valyala/fasthttp" 29 ) 30 31 const METRICS_INDEXNAME = "metricsdb" 32 33 type OtsdbPutResp struct { 34 Failed uint64 `json:"failed"` 35 Success uint64 `json:"success"` 36 Errors []string `json:"errors,omitempty"` 37 } 38 39 func PutMetrics(ctx *fasthttp.RequestCtx, myid uint64) { 40 var processedCount uint64 41 var failedCount uint64 42 var err error 43 44 cType := string(ctx.Request.Header.ContentType()) 45 switch cType { 46 case "gzip": 47 var body []byte 48 body, err = ctx.Request.BodyGunzip() 49 if err != nil { 50 log.Errorf("PutMetrics: error unzipping body! %v", err) 51 break 52 } 53 processedCount, failedCount, err = HandlePutMetrics(body, myid) 54 case "application/json", "json": 55 body := ctx.PostBody() 56 processedCount, failedCount, err = HandlePutMetrics(body, myid) 57 default: 58 log.Errorf("PutMetrics: unknown content type [%s]! %v", cType, err) 59 writeOtsdbResponse(ctx, processedCount, failedCount, "unknown content type", fasthttp.StatusBadRequest) 60 return 61 } 62 if err != nil { 63 writeOtsdbResponse(ctx, processedCount, failedCount, err.Error(), fasthttp.StatusBadRequest) 64 } 65 writeOtsdbResponse(ctx, processedCount, failedCount, "", fasthttp.StatusOK) 66 } 67 68 func HandlePutMetrics(fullData []byte, myid uint64) (uint64, uint64, error) { 69 70 //to have a check if there are any errors in the request 71 //to check for status : 200 or 400 72 //to check if json is greater than MAX_RECORD_SIZE 73 var inCount uint64 = 0 74 var successCount uint64 = 0 75 var failedCount uint64 = 0 76 77 bytesReceived := uint64(len(fullData)) 78 _, err := jp.ArrayEach(fullData, func(value []byte, valueType jp.ValueType, offset int, err error) { 79 inCount++ 80 switch valueType { 81 case jp.Object: 82 mErr := writer.AddTimeSeriesEntryToInMemBuf(value, SIGNAL_METRICS_OTSDB, myid) 83 if mErr != nil { 84 log.Errorf("HandlePutMetrics: failed to add time series entry %+v", mErr) 85 failedCount++ 86 } else { 87 successCount++ 88 } 89 default: 90 log.Errorf("HandlePutMetrics: Unknown type %+v for a read put metrics reqeust", valueType) 91 failedCount++ 92 } 93 }) 94 if err != nil { 95 mErr := writer.AddTimeSeriesEntryToInMemBuf(fullData, SIGNAL_METRICS_OTSDB, myid) 96 if mErr != nil { 97 log.Errorf("HandlePutMetrics: failed to add time series entry %+v", mErr) 98 failedCount++ 99 } else { 100 successCount++ 101 } 102 return 0, 0, err 103 } 104 usageStats.UpdateMetricsStats(bytesReceived, successCount, myid) 105 return successCount, failedCount, nil 106 107 } 108 109 func writeOtsdbResponse(ctx *fasthttp.RequestCtx, processedCount uint64, failedCount uint64, err string, code int) { 110 111 resp := OtsdbPutResp{Success: processedCount, Failed: failedCount} 112 if err != "" { 113 resp.Errors = []string{err} 114 } 115 116 ctx.SetStatusCode(code) 117 ctx.SetContentType(utils.ContentJson) 118 jval, mErr := json.Marshal(resp) 119 if mErr != nil { 120 log.Errorf("writeInfluxResponse: failed to marshal resp %+v", mErr) 121 } 122 _, mErr = ctx.Write(jval) 123 124 if mErr != nil { 125 log.Errorf("writeInfluxResponse: failed to write jval to http request %+v", mErr) 126 } 127 }