github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/pkg/integrations/splunk/splunk.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 splunk 18 19 import ( 20 "encoding/json" 21 "fmt" 22 23 writer "github.com/siglens/siglens/pkg/es/writer" 24 "github.com/siglens/siglens/pkg/utils" 25 vtable "github.com/siglens/siglens/pkg/virtualtable" 26 log "github.com/sirupsen/logrus" 27 "github.com/valyala/fasthttp" 28 ) 29 30 func ProcessSplunkHecIngestRequest(ctx *fasthttp.RequestCtx, myid uint64) { 31 responseBody := make(map[string]interface{}) 32 body, err := utils.GetDecodedBody(ctx) 33 if err != nil { 34 log.Errorf("ProcessSplunkHecIngestRequest: Unable to decode request body, err=%v", err) 35 ctx.SetStatusCode(fasthttp.StatusBadRequest) 36 responseBody["error"] = "Unable to decode request body" 37 utils.WriteJsonResponse(ctx, responseBody) 38 return 39 } 40 41 jsonObjects, err := utils.ExtractSeriesOfJsonObjects(body) 42 if err != nil { 43 log.Errorf("ProcessSplunkHecIngestRequest: Unable to extract json objects from request body, err=%v", err) 44 ctx.SetStatusCode(fasthttp.StatusBadRequest) 45 responseBody["error"] = "Unable to extract json objects from request body" 46 utils.WriteJsonResponse(ctx, responseBody) 47 return 48 } 49 50 for _, record := range jsonObjects { 51 err, statusCode := handleSingleRecord(record, myid) 52 if err != nil { 53 log.Errorf("ProcessSplunkHecIngestRequest: Failed to handle record, err=%v", err) 54 ctx.SetStatusCode(statusCode) 55 responseBody["error"] = err.Error() 56 utils.WriteJsonResponse(ctx, responseBody) 57 return 58 } 59 } 60 61 responseBody["status"] = "Success" 62 utils.WriteJsonResponse(ctx, responseBody) 63 ctx.SetStatusCode(fasthttp.StatusOK) 64 } 65 66 func handleSingleRecord(record map[string]interface{}, myid uint64) (error, int) { 67 if record["index"] == "" || record["index"] == nil { 68 record["index"] = "default" 69 } 70 71 indexNameIn, ok := record["index"].(string) 72 if !ok { 73 return fmt.Errorf("Index field should be a string"), fasthttp.StatusBadRequest 74 } 75 76 recordAsBytes, err := json.Marshal(record) 77 if err != nil { 78 return fmt.Errorf("Failed to marshal record to string"), fasthttp.StatusBadRequest 79 } 80 recordAsString := string(recordAsBytes) 81 82 tsNow := utils.GetCurrentTimeInMs() 83 if !vtable.IsVirtualTablePresent(&indexNameIn, myid) { 84 log.Infof("handleSingleRecord: Index name %v does not exist. Adding virtual table name and mapping.", indexNameIn) 85 86 err := vtable.AddVirtualTable(&indexNameIn, myid) 87 if err != nil { 88 return fmt.Errorf("Failed to add virtual table for index"), fasthttp.StatusServiceUnavailable 89 } 90 91 err = vtable.AddMappingFromADoc(&indexNameIn, &recordAsString, myid) 92 if err != nil { 93 return fmt.Errorf("Failed to add mapping from a doc for index"), fasthttp.StatusServiceUnavailable 94 } 95 } 96 97 localIndexMap := make(map[string]string) 98 err = writer.ProcessIndexRequest(recordAsBytes, tsNow, indexNameIn, uint64(len(recordAsString)), false, localIndexMap, myid) 99 if err != nil { 100 return fmt.Errorf("Failed to add entry to in mem buffer"), fasthttp.StatusServiceUnavailable 101 } 102 103 return nil, fasthttp.StatusOK 104 }