@@ -78,6 +78,17 @@ volatile sig_atomic_t flb_bin_restarting = FLB_RELOAD_IDLE;
7878struct flb_stacktrace flb_st ;
7979#endif
8080
81+ #ifdef FLB_HAVE_CHUNK_TRACE
82+
83+ #include <fluent-bit/flb_chunk_trace.h>
84+
85+ #define FLB_LONG_TRACE (1024 + 1)
86+ #define FLB_LONG_TRACE_INPUT (1024 + 2)
87+ #define FLB_LONG_TRACE_OUTPUT (1024 + 3)
88+ #define FLB_LONG_TRACE_OUTPUT_PROPERTY (1024 + 4)
89+
90+ #endif
91+
8192#define FLB_HELP_TEXT 0
8293#define FLB_HELP_JSON 1
8394
@@ -138,6 +149,10 @@ static void flb_help(int rc, struct flb_config *config)
138149#endif
139150#ifdef FLB_HAVE_CHUNK_TRACE
140151 print_opt ("-Z, --enable-chunk-trace" , "enable chunk tracing. activating it requires using the HTTP Server API." );
152+ print_opt ("--trace-input" , "input to start tracing on startup." );
153+ print_opt ("--trace-output" , "output to use for tracing on startup." );
154+ print_opt ("--trace-output-property" , "set a property for output tracing on startup." );
155+ print_opt ("--trace" , "setup a trace pipeline on startup. Uses a single line, ie: \"input=dummy.0 output=stdout output.format='json'\"" );
141156#endif
142157 print_opt ("-w, --workdir" , "set the working directory" );
143158#ifdef FLB_HAVE_HTTP_SERVER
@@ -726,6 +741,173 @@ static struct flb_cf *service_configure(struct flb_cf *cf,
726741 return cf ;
727742}
728743
744+ #ifdef FLB_HAVE_CHUNK_TRACE
745+ static struct flb_input_instance * find_input (flb_ctx_t * ctx , const char * name )
746+ {
747+ struct mk_list * head ;
748+ struct flb_input_instance * in ;
749+
750+
751+ mk_list_foreach (head , & ctx -> config -> inputs ) {
752+ in = mk_list_entry (head , struct flb_input_instance , _head );
753+ if (strcmp (name , in -> name ) == 0 ) {
754+ return in ;
755+ }
756+ if (in -> alias ) {
757+ if (strcmp (name , in -> alias ) == 0 ) {
758+ return in ;
759+ }
760+ }
761+ }
762+ return NULL ;
763+ }
764+
765+ static int enable_trace_input (flb_ctx_t * ctx , const char * name , const char * prefix , const char * output_name , struct mk_list * props )
766+ {
767+ struct flb_input_instance * in ;
768+
769+
770+ in = find_input (ctx , name );
771+ if (in == NULL ) {
772+ return FLB_ERROR ;
773+ }
774+
775+ flb_chunk_trace_context_new (in , output_name , prefix , NULL , props );
776+ return (in -> chunk_trace_ctxt == NULL ? FLB_ERROR : FLB_OK );
777+ }
778+
779+ static int disable_trace_input (flb_ctx_t * ctx , const char * name )
780+ {
781+ struct flb_input_instance * in ;
782+
783+
784+ in = find_input (ctx , name );
785+ if (in == NULL ) {
786+ return FLB_ERROR ;
787+ }
788+
789+ if (in -> chunk_trace_ctxt != NULL ) {
790+ flb_chunk_trace_context_destroy (in );
791+ }
792+ return FLB_OK ;
793+ }
794+
795+ static int set_trace_property (struct mk_list * props , char * kv )
796+ {
797+ int len ;
798+ int sep ;
799+ char * key ;
800+ char * value ;
801+
802+ len = strlen (kv );
803+ sep = mk_string_char_search (kv , '=' , len );
804+ if (sep == -1 ) {
805+ return -1 ;
806+ }
807+
808+ key = mk_string_copy_substr (kv , 0 , sep );
809+ value = kv + sep + 1 ;
810+
811+ if (!key ) {
812+ return -1 ;
813+ }
814+
815+ flb_kv_item_create_len (props ,
816+ (char * )key , strlen (key ),
817+ (char * )value , strlen (value ));
818+
819+ mk_mem_free (key );
820+ return 0 ;
821+ }
822+
823+ static int parse_trace_pipeline_prop (flb_ctx_t * ctx , const char * kv , char * * key , char * * value )
824+ {
825+ int len ;
826+ int sep ;
827+
828+ len = strlen (kv );
829+ sep = mk_string_char_search (kv , '=' , len );
830+ if (sep == -1 ) {
831+ return FLB_ERROR ;
832+ }
833+
834+ * key = mk_string_copy_substr (kv , 0 , sep );
835+ if (!key ) {
836+ return FLB_ERROR ;
837+ }
838+
839+ * value = flb_strdup (kv + sep + 1 );
840+ return FLB_OK ;
841+ }
842+
843+ static int parse_trace_pipeline (flb_ctx_t * ctx , const char * pipeline , char * * trace_input , char * * trace_output , struct mk_list * * props )
844+ {
845+ struct mk_list * parts = NULL ;
846+ struct mk_list * cur ;
847+ struct flb_split_entry * part ;
848+ char * key ;
849+ char * value ;
850+ const char * propname ;
851+ const char * propval ;
852+
853+
854+ parts = flb_utils_split (pipeline , (int )' ' , 0 );
855+ if (parts == NULL ) {
856+ return FLB_ERROR ;
857+ }
858+
859+ mk_list_foreach (cur , parts ) {
860+ key = NULL ;
861+ value = NULL ;
862+ part = mk_list_entry (cur , struct flb_split_entry , _head );
863+ if (parse_trace_pipeline_prop (ctx , part -> value , & key , & value ) == FLB_ERROR ) {
864+ return FLB_ERROR ;
865+ }
866+ if (strcmp (key , "input" ) == 0 ) {
867+ if (* trace_input != NULL ) {
868+ flb_free (* trace_input );
869+ }
870+ * trace_input = flb_strdup (value );
871+ }
872+ else if (strcmp (key , "output" ) == 0 ) {
873+ if (* trace_output != NULL ) {
874+ flb_free (* trace_output );
875+ }
876+ * trace_output = flb_strdup (value );
877+ }
878+ else if (strncmp (key , "output." , strlen ("output." )) == 0 ) {
879+ propname = mk_string_copy_substr (key , strlen ("output." ), strlen (key ));
880+ if (propname == NULL ) {
881+ return FLB_ERROR ;
882+ }
883+
884+ propval = flb_strdup (value );
885+ if (propval == NULL ) {
886+ return FLB_ERROR ;
887+ }
888+
889+ if (* props == NULL ) {
890+ * props = flb_calloc (1 , sizeof (struct mk_list ));
891+ flb_kv_init (* props );
892+ }
893+
894+ flb_kv_item_create_len (* props ,
895+ (char * )propname , strlen (propname ),
896+ (char * )propval , strlen (propval ));
897+ }
898+ if (key != NULL ) {
899+ mk_mem_free (key );
900+ }
901+ if (value != NULL ) {
902+ flb_free (value );
903+ }
904+ }
905+
906+ flb_utils_split_free (parts );
907+ return FLB_OK ;
908+ }
909+ #endif
910+
729911int flb_main (int argc , char * * argv )
730912{
731913 int opt ;
@@ -762,6 +944,12 @@ int flb_main(int argc, char **argv)
762944 flb_stacktrace_init (argv [0 ], & flb_st );
763945#endif
764946
947+ #ifdef FLB_HAVE_CHUNK_TRACE
948+ char * trace_input = NULL ;
949+ char * trace_output = flb_strdup ("stdout" );
950+ struct mk_list * trace_props = NULL ;
951+ #endif
952+
765953 /* Setup long-options */
766954 static const struct option long_opts [] = {
767955 { "storage_path" , required_argument , NULL , 'b' },
@@ -804,6 +992,10 @@ int flb_main(int argc, char **argv)
804992 { "enable-hot-reload" , no_argument , NULL , 'Y' },
805993#ifdef FLB_HAVE_CHUNK_TRACE
806994 { "enable-chunk-trace" , no_argument , NULL , 'Z' },
995+ { "trace" , required_argument , NULL , FLB_LONG_TRACE },
996+ { "trace-input" , required_argument , NULL , FLB_LONG_TRACE_INPUT },
997+ { "trace-output" , required_argument , NULL , FLB_LONG_TRACE_OUTPUT },
998+ { "trace-output-property" , required_argument , NULL , FLB_LONG_TRACE_OUTPUT_PROPERTY },
807999#endif
8081000 { "disable-thread-safety-on-hot-reload" , no_argument , NULL , 'W' },
8091001 { NULL , 0 , NULL , 0 }
@@ -998,6 +1190,28 @@ int flb_main(int argc, char **argv)
9981190 case 'Z' :
9991191 flb_cf_section_property_add (cf_opts , service -> properties , FLB_CONF_STR_ENABLE_CHUNK_TRACE , 0 , "on" , 0 );
10001192 break ;
1193+ case FLB_LONG_TRACE :
1194+ parse_trace_pipeline (ctx , optarg , & trace_input , & trace_output , & trace_props );
1195+ break ;
1196+ case FLB_LONG_TRACE_INPUT :
1197+ if (trace_input != NULL ) {
1198+ flb_free (trace_input );
1199+ }
1200+ trace_input = flb_strdup (optarg );
1201+ break ;
1202+ case FLB_LONG_TRACE_OUTPUT :
1203+ if (trace_output != NULL ) {
1204+ flb_free (trace_output );
1205+ }
1206+ trace_output = flb_strdup (optarg );
1207+ break ;
1208+ case FLB_LONG_TRACE_OUTPUT_PROPERTY :
1209+ if (trace_props == NULL ) {
1210+ trace_props = flb_calloc (1 , sizeof (struct mk_list ));
1211+ flb_kv_init (trace_props );
1212+ }
1213+ set_trace_property (trace_props , optarg );
1214+ break ;
10011215#endif /* FLB_HAVE_CHUNK_TRACE */
10021216 default :
10031217 flb_help (EXIT_FAILURE , config );
@@ -1113,6 +1327,12 @@ int flb_main(int argc, char **argv)
11131327 */
11141328 ctx = flb_context_get ();
11151329
1330+ #ifdef FLB_HAVE_CHUNK_TRACE
1331+ if (trace_input != NULL ) {
1332+ enable_trace_input (ctx , trace_input , NULL /* prefix ... */ , trace_output , trace_props );
1333+ }
1334+ #endif
1335+
11161336 while (ctx -> status == FLB_LIB_OK && exit_signal == 0 ) {
11171337 sleep (1 );
11181338
@@ -1130,6 +1350,17 @@ int flb_main(int argc, char **argv)
11301350 if (cf_opts != NULL ) {
11311351 flb_cf_destroy (cf_opts );
11321352 }
1353+
1354+ #ifdef FLB_HAVE_CHUNK_TRACE
1355+ if (trace_input != NULL ) {
1356+ disable_trace_input (ctx , trace_input );
1357+ flb_free (trace_input );
1358+ }
1359+ if (trace_output ) {
1360+ flb_free (trace_output );
1361+ }
1362+ #endif
1363+
11331364 flb_stop (ctx );
11341365 flb_destroy (ctx );
11351366
0 commit comments