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  }