@@ -48,83 +48,138 @@ static void destroy_context(struct selector_ctx *context)
4848{
4949 if (context != NULL ) {
5050 delete_metrics_rules (context );
51- flb_free (context -> selector_pattern );
51+ if (context -> selector_pattern != NULL ) {
52+ flb_free (context -> selector_pattern );
53+ }
54+ if (context -> label_key != NULL ) {
55+ flb_sds_destroy (context -> label_key );
56+ }
57+ if (context -> label_value != NULL ) {
58+ flb_sds_destroy (context -> label_value );
59+ }
5260 flb_free (context );
5361 }
5462}
5563
5664static int set_metrics_rules (struct selector_ctx * ctx , struct flb_processor_instance * p_ins )
5765{
66+ flb_sds_t tmp ;
5867 const char * action ;
5968 const char * metric_name ;
6069 const char * op_type ;
6170 const char * context ;
71+ const char * label ;
6272 size_t name_len = 0 ;
73+ struct mk_list * split ;
74+ struct flb_split_entry * sentry ;
6375
64- action = flb_processor_instance_get_property ("action" , p_ins );
65- if (action == NULL ) {
66- ctx -> action_type = SELECTOR_INCLUDE ;
76+ ctx -> selector_pattern = NULL ;
77+ ctx -> label_key = NULL ;
78+ ctx -> label_value = NULL ;
79+
80+ context = flb_processor_instance_get_property ("context" , p_ins );
81+ if (context == NULL ) {
82+ ctx -> context_type = SELECTOR_CONTEXT_FQNAME ;
6783 }
68- else if (strncasecmp (action , "include" , 7 ) == 0 ) {
69- flb_plg_debug (ctx -> ins , "action type INCLUDE" );
70- ctx -> action_type = SELECTOR_INCLUDE ;
84+ else if (strncasecmp (context , "metric_name" , 11 ) == 0 ) {
85+ ctx -> context_type = SELECTOR_CONTEXT_FQNAME ;
7186 }
72- else if (strncasecmp (action , "exclude" , 7 ) == 0 ) {
73- flb_plg_debug (ctx -> ins , "action type EXCLUDE" );
74- ctx -> action_type = SELECTOR_EXCLUDE ;
87+ else if (strncasecmp (context , "delete_label_value" , 18 ) == 0 ) {
88+ ctx -> context_type = SELECTOR_CONTEXT_DELETE_LABEL_VALUE ;
7589 }
7690 else {
77- flb_plg_error (ctx -> ins , "unknown action type '%s'" , action );
91+ flb_plg_error (ctx -> ins , "unknown context '%s'" , context );
92+ delete_metrics_rules (ctx );
7893 return -1 ;
7994 }
8095
81- metric_name = flb_processor_instance_get_property ("metric_name" , p_ins );
82- if (metric_name == NULL ) {
83- flb_plg_error (ctx -> ins , "metric_name is needed for selector" );
84- return -1 ;
85- }
86- ctx -> selector_pattern = flb_strdup (metric_name );
87- name_len = strlen (metric_name );
96+ if (ctx -> context_type == SELECTOR_CONTEXT_FQNAME ) {
97+ action = flb_processor_instance_get_property ("action" , p_ins );
98+ if (action == NULL ) {
99+ ctx -> action_type = SELECTOR_INCLUDE ;
100+ }
101+ else if (strncasecmp (action , "include" , 7 ) == 0 ) {
102+ flb_plg_debug (ctx -> ins , "action type INCLUDE" );
103+ ctx -> action_type = SELECTOR_INCLUDE ;
104+ }
105+ else if (strncasecmp (action , "exclude" , 7 ) == 0 ) {
106+ flb_plg_debug (ctx -> ins , "action type EXCLUDE" );
107+ ctx -> action_type = SELECTOR_EXCLUDE ;
108+ }
109+ else {
110+ flb_plg_error (ctx -> ins , "unknown action type '%s'" , action );
111+ return -1 ;
112+ }
88113
89- op_type = flb_processor_instance_get_property ("operation_type" , p_ins );
90- if (op_type == NULL ) {
91- ctx -> op_type = SELECTOR_OPERATION_PREFIX ;
92- }
93- else if (strncasecmp (op_type , "prefix" , 6 ) == 0 ) {
94- flb_plg_debug (ctx -> ins , "operation type PREFIX" );
95- ctx -> op_type = SELECTOR_OPERATION_PREFIX ;
96- }
97- else if (strncasecmp (op_type , "substring" , 9 ) == 0 ) {
98- flb_plg_debug (ctx -> ins , "operation type SUBSTRING" );
99- ctx -> op_type = SELECTOR_OPERATION_SUBSTRING ;
100- }
101- else {
102- flb_plg_error (ctx -> ins , "unknown action type '%s'" , op_type );
103- return -1 ;
104- }
114+ metric_name = flb_processor_instance_get_property ("metric_name" , p_ins );
115+ if (metric_name == NULL ) {
116+ flb_plg_error (ctx -> ins , "metric_name is needed for selector" );
117+ return -1 ;
118+ }
119+ ctx -> selector_pattern = flb_strdup (metric_name );
120+ name_len = strlen (metric_name );
105121
106- if (ctx -> selector_pattern [0 ] == '/' && ctx -> selector_pattern [name_len - 1 ] == '/' ) {
107- /* Convert string to regex pattern for metrics */
108- ctx -> name_regex = flb_regex_create (ctx -> selector_pattern );
109- if (!ctx -> name_regex ) {
110- flb_plg_error (ctx -> ins , "could not compile regex pattern '%s'" ,
111- ctx -> selector_pattern );
122+ op_type = flb_processor_instance_get_property ("operation_type" , p_ins );
123+ if (op_type == NULL ) {
124+ ctx -> op_type = SELECTOR_OPERATION_PREFIX ;
125+ }
126+ else if (strncasecmp (op_type , "prefix" , 6 ) == 0 ) {
127+ flb_plg_debug (ctx -> ins , "operation type PREFIX" );
128+ ctx -> op_type = SELECTOR_OPERATION_PREFIX ;
129+ }
130+ else if (strncasecmp (op_type , "substring" , 9 ) == 0 ) {
131+ flb_plg_debug (ctx -> ins , "operation type SUBSTRING" );
132+ ctx -> op_type = SELECTOR_OPERATION_SUBSTRING ;
133+ }
134+ else {
135+ flb_plg_error (ctx -> ins , "unknown action type '%s'" , op_type );
112136 return -1 ;
113137 }
114- ctx -> op_type = SELECTOR_OPERATION_REGEX ;
115- }
116138
117- context = flb_processor_instance_get_property ("context" , p_ins );
118- if (context == NULL ) {
119- ctx -> context_type = SELECTOR_CONTEXT_FQNAME ;
120- }
121- else if (strncasecmp (context , "metric_name" , 11 ) == 0 ) {
122- ctx -> context_type = SELECTOR_CONTEXT_FQNAME ;
139+ if (ctx -> selector_pattern [0 ] == '/' && ctx -> selector_pattern [name_len - 1 ] == '/' ) {
140+ /* Convert string to regex pattern for metrics */
141+ ctx -> name_regex = flb_regex_create (ctx -> selector_pattern );
142+ if (!ctx -> name_regex ) {
143+ flb_plg_error (ctx -> ins , "could not compile regex pattern '%s'" ,
144+ ctx -> selector_pattern );
145+ return -1 ;
146+ }
147+ ctx -> op_type = SELECTOR_OPERATION_REGEX ;
148+ }
123149 }
124- else {
125- flb_plg_error (ctx -> ins , "unknown context '%s'" , context );
126- delete_metrics_rules (ctx );
127- return -1 ;
150+ else if (ctx -> context_type == SELECTOR_CONTEXT_DELETE_LABEL_VALUE ) {
151+ label = flb_processor_instance_get_property ("label" , p_ins );
152+ if (label != NULL ) {
153+ split = flb_utils_split (label , ' ' , 1 );
154+ if (mk_list_size (split ) != 2 ) {
155+ flb_plg_error (ctx -> ins , "invalid value, expected key and value" );
156+ flb_utils_split_free (split );
157+ return -1 ;
158+ }
159+
160+ /* Get first value (label's key) */
161+ sentry = mk_list_entry_first (split , struct flb_split_entry , _head );
162+ tmp = flb_sds_create_len (sentry -> value , sentry -> len );
163+ if (tmp == NULL ) {
164+ flb_plg_error (ctx -> ins , "allocation failed for label key" );
165+ flb_utils_split_free (split );
166+ return -1 ;
167+ }
168+ ctx -> label_key = tmp ;
169+
170+ /* Get last value (label's value) */
171+ sentry = mk_list_entry_last (split , struct flb_split_entry , _head );
172+ tmp = flb_sds_create_len (sentry -> value , sentry -> len );
173+ if (tmp == NULL ) {
174+ flb_plg_error (ctx -> ins , "allocation failed for label value" );
175+ flb_utils_split_free (split );
176+ return -1 ;
177+ }
178+ ctx -> label_value = tmp ;
179+ ctx -> op_type = SELECTOR_CONTEXT_DELETE_LABEL_VALUE ;
180+
181+ flb_utils_split_free (split );
182+ }
128183 }
129184
130185 return 0 ;
@@ -279,13 +334,48 @@ static inline int selector_metrics_process_fqname(struct cmt *cmt, struct cmt *o
279334 return found ? SELECTOR_RET_EXCLUDE : SELECTOR_RET_KEEP ;
280335}
281336
337+ static inline int selector_metrics_process_delete_label_value (struct cmt * cmt , struct cmt * out_cmt ,
338+ struct selector_ctx * ctx )
339+ {
340+ int ret ;
341+ int removed = FLB_FALSE ;
342+ struct cmt * filtered = NULL ;
343+
344+ /* On processor_selector, we only process one rule in each of contexts */
345+
346+ filtered = cmt_create ();
347+ if (filtered == NULL ) {
348+ flb_plg_error (ctx -> ins , "could not create filtered context" );
349+
350+ return SELECTOR_FAILURE ;
351+ }
352+
353+ ret = cmt_filter_with_label_pair (filtered , cmt , ctx -> label_key , ctx -> label_value );
354+
355+ if (ret == 0 ) {
356+ removed = FLB_TRUE ;
357+ }
358+ else if (ret != 0 ) {
359+ flb_plg_debug (ctx -> ins , "not matched for a key-value pair: \"%s\",\"%s\"" ,
360+ ctx -> label_key , ctx -> label_value );
361+ }
362+
363+ cmt_cat (out_cmt , filtered );
364+ cmt_destroy (filtered );
365+
366+ return removed ? SELECTOR_RET_EXCLUDE : SELECTOR_RET_KEEP ;
367+ }
368+
282369/* Given a metrics context, do some select action based on the defined rules */
283370static inline int selector_metrics (struct cmt * cmt , struct cmt * out_cmt ,
284371 struct selector_ctx * ctx )
285372{
286373 if (ctx -> context_type == SELECTOR_CONTEXT_FQNAME ) {
287374 return selector_metrics_process_fqname (cmt , out_cmt , ctx );
288375 }
376+ else if (ctx -> context_type == SELECTOR_CONTEXT_DELETE_LABEL_VALUE ) {
377+ return selector_metrics_process_delete_label_value (cmt , out_cmt , ctx );
378+ }
289379
290380 return 0 ;
291381}
@@ -365,13 +455,18 @@ static struct flb_config_map config_map[] = {
365455 {
366456 FLB_CONFIG_MAP_STR , "context" , NULL ,
367457 FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
368- "Specify matching context. Currently, metric_name is only supported."
458+ "Specify matching context. Currently, metric_name and delete_label_value are only supported."
369459 },
370460 {
371461 FLB_CONFIG_MAP_STR , "action" , NULL ,
372462 0 , FLB_FALSE , 0 ,
373463 "Specify the action for specified metrics. INCLUDE and EXCLUDE are allowed."
374464 },
465+ {
466+ FLB_CONFIG_MAP_STR , "label" , NULL ,
467+ 0 , FLB_FALSE , 0 ,
468+ "Specify a label key and value pair."
469+ },
375470 {
376471 FLB_CONFIG_MAP_STR , "operation_type" , NULL ,
377472 0 , FLB_FALSE , 0 ,
0 commit comments