14
14
package splunkhecexporter
15
15
16
16
import (
17
+ "bytes"
17
18
"compress/gzip"
18
19
"context"
19
20
"errors"
@@ -128,7 +129,7 @@ func createLogData(numResources int, numLibraries int, numRecords int) pdata.Log
128
129
129
130
type CapturingData struct {
130
131
testing * testing.T
131
- receivedRequest chan string
132
+ receivedRequest chan [] byte
132
133
statusCode int
133
134
checkCompression bool
134
135
}
@@ -146,7 +147,7 @@ func (c *CapturingData) ServeHTTP(w http.ResponseWriter, r *http.Request) {
146
147
panic (err )
147
148
}
148
149
go func () {
149
- c .receivedRequest <- string ( body )
150
+ c .receivedRequest <- body
150
151
}()
151
152
w .WriteHeader (c .statusCode )
152
153
}
@@ -163,7 +164,7 @@ func runMetricsExport(disableCompression bool, numberOfDataPoints int, t *testin
163
164
cfg .DisableCompression = disableCompression
164
165
cfg .Token = "1234-1234"
165
166
166
- receivedRequest := make (chan string )
167
+ receivedRequest := make (chan [] byte )
167
168
capture := CapturingData {testing : t , receivedRequest : receivedRequest , statusCode : 200 , checkCompression : ! cfg .DisableCompression }
168
169
s := & http.Server {
169
170
Handler : & capture ,
@@ -184,7 +185,7 @@ func runMetricsExport(disableCompression bool, numberOfDataPoints int, t *testin
184
185
assert .NoError (t , err )
185
186
select {
186
187
case request := <- receivedRequest :
187
- return request , nil
188
+ return string ( request ) , nil
188
189
case <- time .After (1 * time .Second ):
189
190
return "" , errors .New ("timeout" )
190
191
}
@@ -202,7 +203,7 @@ func runTraceExport(disableCompression bool, numberOfTraces int, t *testing.T) (
202
203
cfg .DisableCompression = disableCompression
203
204
cfg .Token = "1234-1234"
204
205
205
- receivedRequest := make (chan string )
206
+ receivedRequest := make (chan [] byte )
206
207
capture := CapturingData {testing : t , receivedRequest : receivedRequest , statusCode : 200 , checkCompression : ! cfg .DisableCompression }
207
208
s := & http.Server {
208
209
Handler : & capture ,
@@ -223,13 +224,13 @@ func runTraceExport(disableCompression bool, numberOfTraces int, t *testing.T) (
223
224
assert .NoError (t , err )
224
225
select {
225
226
case request := <- receivedRequest :
226
- return request , nil
227
+ return string ( request ) , nil
227
228
case <- time .After (1 * time .Second ):
228
229
return "" , errors .New ("timeout" )
229
230
}
230
231
}
231
232
232
- func runLogExport (cfg * Config , ld pdata.Logs , t * testing.T ) ([]string , error ) {
233
+ func runLogExport (cfg * Config , ld pdata.Logs , t * testing.T ) ([][] byte , error ) {
233
234
listener , err := net .Listen ("tcp" , "127.0.0.1:0" )
234
235
if err != nil {
235
236
panic (err )
@@ -238,7 +239,7 @@ func runLogExport(cfg *Config, ld pdata.Logs, t *testing.T) ([]string, error) {
238
239
cfg .Endpoint = "http://" + listener .Addr ().String () + "/services/collector"
239
240
cfg .Token = "1234-1234"
240
241
241
- receivedRequest := make (chan string )
242
+ receivedRequest := make (chan [] byte )
242
243
capture := CapturingData {testing : t , receivedRequest : receivedRequest , statusCode : 200 , checkCompression : ! cfg .DisableCompression }
243
244
s := & http.Server {
244
245
Handler : & capture ,
@@ -256,7 +257,7 @@ func runLogExport(cfg *Config, ld pdata.Logs, t *testing.T) ([]string, error) {
256
257
err = exporter .ConsumeLogs (context .Background (), ld )
257
258
assert .NoError (t , err )
258
259
259
- var requests []string
260
+ var requests [][] byte
260
261
for {
261
262
select {
262
263
case request := <- receivedRequest :
@@ -286,8 +287,13 @@ func TestReceiveLogs(t *testing.T) {
286
287
type wantType struct {
287
288
batches []string
288
289
numBatches int
290
+ compressed bool
289
291
}
290
292
293
+ // The test cases depend on the constant minCompressionLen = 1500.
294
+ // If the constant changed, the test cases with want.compressed=true must be updated.
295
+ require .Equal (t , minCompressionLen , 1500 )
296
+
291
297
tests := []struct {
292
298
name string
293
299
conf * Config
@@ -348,6 +354,62 @@ func TestReceiveLogs(t *testing.T) {
348
354
numBatches : 2 ,
349
355
},
350
356
},
357
+ {
358
+ name : "1 compressed batch of 1837 bytes, make sure the event size is more than minCompressionLen=1500 to trigger compression" ,
359
+ logs : createLogData (1 , 1 , 10 ),
360
+ conf : func () * Config {
361
+ return NewFactory ().CreateDefaultConfig ().(* Config )
362
+ }(),
363
+ want : wantType {
364
+ batches : []string {
365
+ `{"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
366
+ `{"time":0.001,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
367
+ `{"time":0.002,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
368
+ `{"time":0.003,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
369
+ `{"time":0.004,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
370
+ `{"time":0.005,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
371
+ `{"time":0.006,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
372
+ `{"time":0.007,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
373
+ `{"time":0.008,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
374
+ `{"time":0.009,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " ,
375
+ },
376
+ numBatches : 1 ,
377
+ compressed : true ,
378
+ },
379
+ },
380
+ {
381
+ name : "2 compressed batches - 1652 bytes each, make sure the log size is more than minCompressionLen=1500 to trigger compression" ,
382
+ logs : createLogData (1 , 1 , 18 ), // comes to HEC events payload size - 1837 bytes
383
+ conf : func () * Config {
384
+ cfg := NewFactory ().CreateDefaultConfig ().(* Config )
385
+ cfg .MaxContentLengthLogs = 1700
386
+ return cfg
387
+ }(),
388
+ want : wantType {
389
+ batches : []string {
390
+ `{"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
391
+ `{"time":0.001,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
392
+ `{"time":0.002,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
393
+ `{"time":0.003,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
394
+ `{"time":0.004,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
395
+ `{"time":0.005,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
396
+ `{"time":0.006,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
397
+ `{"time":0.007,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
398
+ `{"time":0.008,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " ,
399
+ `{"time":0.009,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
400
+ `{"time":0.01,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
401
+ `{"time":0.011,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
402
+ `{"time":0.012,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
403
+ `{"time":0.013,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
404
+ `{"time":0.014,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
405
+ `{"time":0.015,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
406
+ `{"time":0.016,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " +
407
+ `{"time":0.017,"host":"myhost","source":"myapp","sourcetype":"myapp-type","index":"myindex","event":"mylog","fields":{"custom":"custom","host.name":"myhost","service.name":"myapp"}}` + "\n \r \n \r \n " ,
408
+ },
409
+ numBatches : 2 ,
410
+ compressed : true ,
411
+ },
412
+ },
351
413
}
352
414
353
415
for _ , test := range tests {
@@ -359,7 +421,11 @@ func TestReceiveLogs(t *testing.T) {
359
421
360
422
for i := 0 ; i < test .want .numBatches ; i ++ {
361
423
require .NotZero (t , got [i ])
362
- assert .Equal (t , test .want .batches [i ], got [i ])
424
+ if test .want .compressed {
425
+ validateCompressedEqual (t , test .want .batches [i ], got [i ])
426
+ } else {
427
+ assert .Equal (t , test .want .batches [i ], string (got [i ]))
428
+ }
363
429
364
430
}
365
431
})
@@ -391,7 +457,7 @@ func TestReceiveMetricsWithCompression(t *testing.T) {
391
457
}
392
458
393
459
func TestErrorReceived (t * testing.T ) {
394
- receivedRequest := make (chan string )
460
+ receivedRequest := make (chan [] byte )
395
461
capture := CapturingData {receivedRequest : receivedRequest , statusCode : 500 }
396
462
listener , err := net .Listen ("tcp" , "127.0.0.1:0" )
397
463
if err != nil {
@@ -720,3 +786,15 @@ func TestSubLogs(t *testing.T) {
720
786
// The name of the sole log record should be 1_1_2.
721
787
assert .Equal (t , "1_1_2" , got .ResourceLogs ().At (0 ).InstrumentationLibraryLogs ().At (0 ).Logs ().At (0 ).Name ())
722
788
}
789
+
790
+ // validateCompressedEqual validates that GZipped `got` contains `expected` string
791
+ func validateCompressedEqual (t * testing.T , expected string , got []byte ) {
792
+ z , err := gzip .NewReader (bytes .NewReader (got ))
793
+ require .NoError (t , err )
794
+ defer z .Close ()
795
+
796
+ p , err := ioutil .ReadAll (z )
797
+ require .NoError (t , err )
798
+
799
+ assert .Equal (t , expected , string (p ))
800
+ }
0 commit comments