Skip to content

Commit 8ec09d3

Browse files
authored
[receiver/splunkhec] Align hec receiver errors messages to splunk enterprise (#19769)
* Align hec receiver errors messages to splunk enterprise * include chlog * revert removing obsrecv in raw
1 parent ce31815 commit 8ec09d3

File tree

3 files changed

+85
-11
lines changed

3 files changed

+85
-11
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
2+
change_type: enhancement
3+
4+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
5+
component: splunkhecreceiver
6+
7+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
8+
note: align error message with splunk enterprise to include No Data, Invalid Data Format, Event field is required, and Event field cannot be blank
9+
10+
# One or more tracking issues related to the change
11+
issues: [19219]

receiver/splunkhecreceiver/receiver.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,16 @@ const (
4545
responseOK = "OK"
4646
responseInvalidMethod = `Only "POST" method is supported`
4747
responseInvalidEncoding = `"Content-Encoding" must be "gzip" or empty`
48+
responseInvalidDataFormat = `{"text":"Invalid data format","code":6}`
49+
responseErrEventRequired = `{"text":"Event field is required","code":12}`
50+
responseErrEventBlank = `{"text":"Event field cannot be blank","code":13}`
4851
responseErrGzipReader = "Error on gzip body"
4952
responseErrUnmarshalBody = "Failed to unmarshal message body"
5053
responseErrInternalServerError = "Internal Server Error"
5154
responseErrUnsupportedMetricEvent = "Unsupported metric event"
5255
responseErrUnsupportedLogEvent = "Unsupported log event"
5356
responseErrHandlingIndexedFields = `{"text":"Error in handling indexed fields","code":15,"invalid-event-number":%d}`
57+
responseNoData = `{"text":"No data","code":5}`
5458
// Centralizing some HTTP and related string constants.
5559
gzipEncoding = "gzip"
5660
httpContentEncodingHeader = "Content-Encoding"
@@ -64,13 +68,17 @@ var (
6468
errInvalidEncoding = errors.New("invalid encoding")
6569

6670
okRespBody = initJSONResponse(responseOK)
67-
invalidMethodRespBody = initJSONResponse(responseInvalidMethod)
71+
eventRequiredRespBody = initJSONResponse(responseErrEventRequired)
72+
eventBlankRespBody = initJSONResponse(responseErrEventBlank)
6873
invalidEncodingRespBody = initJSONResponse(responseInvalidEncoding)
74+
invalidFormatRespBody = initJSONResponse(responseInvalidDataFormat)
75+
invalidMethodRespBody = initJSONResponse(responseInvalidMethod)
6976
errGzipReaderRespBody = initJSONResponse(responseErrGzipReader)
7077
errUnmarshalBodyRespBody = initJSONResponse(responseErrUnmarshalBody)
7178
errInternalServerError = initJSONResponse(responseErrInternalServerError)
7279
errUnsupportedMetricEvent = initJSONResponse(responseErrUnsupportedMetricEvent)
7380
errUnsupportedLogEvent = initJSONResponse(responseErrUnsupportedLogEvent)
81+
noDataRespBody = initJSONResponse(responseNoData)
7482
)
7583

7684
// splunkReceiver implements the receiver.Metrics for Splunk HEC metric protocol.
@@ -246,6 +254,7 @@ func (r *splunkReceiver) handleRawReq(resp http.ResponseWriter, req *http.Reques
246254

247255
if req.ContentLength == 0 {
248256
r.obsrecv.EndLogsOp(ctx, typeStr, 0, nil)
257+
r.failRequest(ctx, resp, http.StatusBadRequest, noDataRespBody, 0, nil)
249258
return
250259
}
251260

@@ -311,9 +320,7 @@ func (r *splunkReceiver) handleReq(resp http.ResponseWriter, req *http.Request)
311320
}
312321

313322
if req.ContentLength == 0 {
314-
if _, err := resp.Write(okRespBody); err != nil {
315-
r.failRequest(ctx, resp, http.StatusInternalServerError, errInternalServerError, 0, err)
316-
}
323+
r.failRequest(ctx, resp, http.StatusBadRequest, noDataRespBody, 0, nil)
317324
return
318325
}
319326

@@ -325,7 +332,17 @@ func (r *splunkReceiver) handleReq(resp http.ResponseWriter, req *http.Request)
325332
var msg splunk.Event
326333
err := dec.Decode(&msg)
327334
if err != nil {
328-
r.failRequest(ctx, resp, http.StatusBadRequest, errUnmarshalBodyRespBody, len(events), err)
335+
r.failRequest(ctx, resp, http.StatusBadRequest, invalidFormatRespBody, len(events), err)
336+
return
337+
}
338+
339+
if msg.Event == nil {
340+
r.failRequest(ctx, resp, http.StatusBadRequest, eventRequiredRespBody, len(events), nil)
341+
return
342+
}
343+
344+
if msg.Event == "" {
345+
r.failRequest(ctx, resp, http.StatusBadRequest, eventBlankRespBody, len(events), nil)
329346
return
330347
}
331348

receiver/splunkhecreceiver/receiver_test.go

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,9 @@ func Test_splunkhecReceiver_handleReq(t *testing.T) {
190190
{
191191
name: "incorrect_content_type",
192192
req: func() *http.Request {
193-
req := httptest.NewRequest("POST", "http://localhost/foo", nil)
193+
msgBytes, err := json.Marshal(splunkMsg)
194+
require.NoError(t, err)
195+
req := httptest.NewRequest("POST", "http://localhost/foo", bytes.NewReader(msgBytes))
194196
req.Header.Set("Content-Type", "application/not-json")
195197
return req
196198
}(),
@@ -234,7 +236,7 @@ func Test_splunkhecReceiver_handleReq(t *testing.T) {
234236
}(),
235237
assertResponse: func(t *testing.T, status int, body string) {
236238
assert.Equal(t, http.StatusBadRequest, status)
237-
assert.Equal(t, responseErrUnmarshalBody, body)
239+
assert.Equal(t, responseInvalidDataFormat, body)
238240
},
239241
},
240242
{
@@ -244,8 +246,51 @@ func Test_splunkhecReceiver_handleReq(t *testing.T) {
244246
return req
245247
}(),
246248
assertResponse: func(t *testing.T, status int, body string) {
247-
assert.Equal(t, http.StatusOK, status)
248-
assert.Equal(t, responseOK, body)
249+
assert.Equal(t, http.StatusBadRequest, status)
250+
assert.Equal(t, responseNoData, body)
251+
},
252+
},
253+
{
254+
name: "invalid_data_format",
255+
req: func() *http.Request {
256+
msgBytes, err := json.Marshal(`{"foo":"bar"}`)
257+
require.NoError(t, err)
258+
req := httptest.NewRequest("POST", "http://localhost/foo", bytes.NewReader(msgBytes))
259+
return req
260+
}(),
261+
assertResponse: func(t *testing.T, status int, body string) {
262+
assert.Equal(t, http.StatusBadRequest, status)
263+
assert.Equal(t, responseInvalidDataFormat, body)
264+
},
265+
},
266+
{
267+
name: "event_required_error",
268+
req: func() *http.Request {
269+
nilEventMsg := buildSplunkHecMsg(currentTime, 3)
270+
nilEventMsg.Event = nil
271+
msgBytes, err := json.Marshal(nilEventMsg)
272+
require.NoError(t, err)
273+
req := httptest.NewRequest("POST", "http://localhost/foo", bytes.NewReader(msgBytes))
274+
return req
275+
}(),
276+
assertResponse: func(t *testing.T, status int, body string) {
277+
assert.Equal(t, http.StatusBadRequest, status)
278+
assert.Equal(t, responseErrEventRequired, body)
279+
},
280+
},
281+
{
282+
name: "event_cannot_be_blank_error",
283+
req: func() *http.Request {
284+
blankEventMsg := buildSplunkHecMsg(currentTime, 3)
285+
blankEventMsg.Event = ""
286+
msgBytes, err := json.Marshal(blankEventMsg)
287+
require.NoError(t, err)
288+
req := httptest.NewRequest("POST", "http://localhost/foo", bytes.NewReader(msgBytes))
289+
return req
290+
}(),
291+
assertResponse: func(t *testing.T, status int, body string) {
292+
assert.Equal(t, http.StatusBadRequest, status)
293+
assert.Equal(t, responseErrEventBlank, body)
249294
},
250295
},
251296
{
@@ -864,7 +909,7 @@ func Test_splunkhecReceiver_handleRawReq(t *testing.T) {
864909
{
865910
name: "incorrect_content_type",
866911
req: func() *http.Request {
867-
req := httptest.NewRequest("POST", "http://localhost/foo", nil)
912+
req := httptest.NewRequest("POST", "http://localhost/foo", strings.NewReader("foo\nbar"))
868913
req.Header.Set("Content-Type", "application/not-json")
869914
return req
870915
}(),
@@ -891,7 +936,8 @@ func Test_splunkhecReceiver_handleRawReq(t *testing.T) {
891936
return req
892937
}(),
893938
assertResponse: func(t *testing.T, status int, body string) {
894-
assert.Equal(t, http.StatusOK, status)
939+
assert.Equal(t, http.StatusBadRequest, status)
940+
assert.Equal(t, responseNoData, body)
895941
},
896942
},
897943

0 commit comments

Comments
 (0)