@@ -312,6 +312,92 @@ void flb_test_severity_promoted_as_level()
312312 flb_destroy (ctx );
313313}
314314
315+ /*
316+ * Test: record with both "level" and "severity" — only first is promoted,
317+ * neither appears in line body, and no msgpack corruption occurs.
318+ */
319+ #define JSON_LEVEL_AND_SEVERITY \
320+ "[12345678, {\"message\":\"hello\"," \
321+ "\"level\":\"info\"," \
322+ "\"severity\":\"warning\"," \
323+ "\"host\":\"server1\"}]"
324+
325+ static void cb_check_level_and_severity (void * ctx , int ffd , int res_ret ,
326+ void * res_data , size_t res_size ,
327+ void * data )
328+ {
329+ flb_sds_t json = res_data ;
330+
331+ /* First level/severity key promoted as "level" */
332+ if (!TEST_CHECK (strstr (json , "\"level\":\"info\"" ) != NULL )) {
333+ TEST_MSG ("level not promoted: %s" , json );
334+ }
335+
336+ /* Neither level nor severity in line body */
337+ if (!TEST_CHECK (strstr (json , "\\\"level\\\":" ) == NULL )) {
338+ TEST_MSG ("level duplicated in line: %s" , json );
339+ }
340+ if (!TEST_CHECK (strstr (json , "\\\"severity\\\":" ) == NULL )) {
341+ TEST_MSG ("severity duplicated in line: %s" , json );
342+ }
343+
344+ /* Non-primary keys preserved in line */
345+ if (!TEST_CHECK (strstr (json , "\\\"message\\\":" ) != NULL )) {
346+ TEST_MSG ("message missing from line: %s" , json );
347+ }
348+ if (!TEST_CHECK (strstr (json , "\\\"host\\\":" ) != NULL )) {
349+ TEST_MSG ("host missing from line: %s" , json );
350+ }
351+
352+ set_output_num (get_output_num () + 1 );
353+ flb_sds_destroy (json );
354+ }
355+
356+ void flb_test_level_and_severity ()
357+ {
358+ int ret ;
359+ flb_ctx_t * ctx ;
360+ int in_ffd , out_ffd ;
361+
362+ clear_output_num ();
363+
364+ ctx = flb_create ();
365+ flb_service_set (ctx , "flush" , "1" , "grace" , "1" ,
366+ "log_level" , "error" , NULL );
367+
368+ in_ffd = flb_input (ctx , (char * ) "lib" , NULL );
369+ TEST_CHECK (in_ffd >= 0 );
370+ flb_input_set (ctx , in_ffd , "tag" , "test" , NULL );
371+
372+ out_ffd = flb_output (ctx , (char * ) "logdna" , NULL );
373+ TEST_CHECK (out_ffd >= 0 );
374+ flb_output_set (ctx , out_ffd ,
375+ "match" , "test" ,
376+ "api_key" , "test-key" ,
377+ "exclude_promoted_keys" , "true" ,
378+ NULL );
379+
380+ ret = flb_output_set_test (ctx , out_ffd , "formatter" ,
381+ cb_check_level_and_severity , NULL , NULL );
382+ TEST_CHECK (ret == 0 );
383+
384+ ret = flb_start (ctx );
385+ TEST_CHECK (ret == 0 );
386+
387+ flb_lib_push (ctx , in_ffd ,
388+ (char * ) JSON_LEVEL_AND_SEVERITY ,
389+ sizeof (JSON_LEVEL_AND_SEVERITY ) - 1 );
390+
391+ sleep (2 );
392+
393+ if (!TEST_CHECK (get_output_num () > 0 )) {
394+ TEST_MSG ("formatter callback was not invoked" );
395+ }
396+
397+ flb_stop (ctx );
398+ flb_destroy (ctx );
399+ }
400+
315401/*
316402 * Test: default app name is set when record has no "app" key.
317403 */
@@ -649,6 +735,7 @@ TEST_LIST = {
649735 {"non_duplication" , flb_test_non_duplication },
650736 {"data_completeness" , flb_test_data_completeness },
651737 {"severity_promoted_as_level" , flb_test_severity_promoted_as_level },
738+ {"level_and_severity" , flb_test_level_and_severity },
652739 {"default_app" , flb_test_default_app },
653740 {"no_primary_keys" , flb_test_no_primary_keys },
654741 {"payload_structure" , flb_test_payload_structure },
0 commit comments