Skip to content

Commit c7c5599

Browse files
committed
in_tail: add new 'multiline.parser' option and feature
Signed-off-by: Eduardo Silva <[email protected]>
1 parent 88c0f17 commit c7c5599

File tree

5 files changed

+144
-8
lines changed

5 files changed

+144
-8
lines changed

plugins/in_tail/tail.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,12 @@ static struct flb_config_map config_map[] = {
649649
"Parser_2 ab2, Parser_N abN."
650650
},
651651

652+
/* Multiline Core Engine based API */
653+
{
654+
FLB_CONFIG_MAP_CLIST, "multiline.parser", NULL,
655+
FLB_CONFIG_MAP_MULT, FLB_TRUE, offsetof(struct flb_tail_config, multiline_parsers),
656+
"specify one or multiple multiline parsers: docker, cri, go, java, etc."
657+
},
652658
#endif
653659

654660
/* EOF */

plugins/in_tail/tail_config.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#include <fluent-bit/flb_info.h>
2222
#include <fluent-bit/flb_input_plugin.h>
23+
#include <fluent-bit/multiline/flb_ml.h>
24+
#include <fluent-bit/multiline/flb_ml_parser.h>
2325

2426
#include <stdlib.h>
2527
#include <fcntl.h>
@@ -35,6 +37,43 @@
3537
#include "tail_multiline.h"
3638
#endif
3739

40+
static int multiline_load_parsers(struct flb_tail_config *ctx)
41+
{
42+
struct mk_list *head;
43+
struct mk_list *head_p;
44+
struct flb_config_map_val *mv;
45+
struct flb_slist_entry *val = NULL;
46+
struct flb_ml_parser_ins *parser_i;
47+
48+
if (!ctx->multiline_parsers) {
49+
return 0;
50+
}
51+
52+
/* Create Multiline context using the plugin instance name */
53+
ctx->ml_ctx = flb_ml_create(ctx->config, ctx->ins->name);
54+
if (!ctx->ml_ctx) {
55+
return -1;
56+
}
57+
58+
/*
59+
* Iterate all 'multiline.parser' entries. Every entry is considered
60+
* a group which can have multiple multiline parser instances.
61+
*/
62+
flb_config_map_foreach(head, mv, ctx->multiline_parsers) {
63+
mk_list_foreach(head_p, mv->val.list) {
64+
val = mk_list_entry(head_p, struct flb_slist_entry, _head);
65+
66+
/* Create an instance of the defined parser */
67+
parser_i = flb_ml_parser_instance_create(ctx->ml_ctx, val->str);
68+
if (!parser_i) {
69+
return -1;
70+
}
71+
}
72+
}
73+
74+
return 0;
75+
}
76+
3877
struct flb_tail_config *flb_tail_config_create(struct flb_input_instance *ins,
3978
struct flb_config *config)
4079
{
@@ -50,6 +89,7 @@ struct flb_tail_config *flb_tail_config_create(struct flb_input_instance *ins,
5089
flb_errno();
5190
return NULL;
5291
}
92+
ctx->config = config;
5393
ctx->ins = ins;
5494
ctx->ignore_older = 0;
5595
ctx->skip_long_lines = FLB_FALSE;
@@ -319,6 +359,27 @@ struct flb_tail_config *flb_tail_config_create(struct flb_input_instance *ins,
319359
}
320360
#endif
321361

362+
#ifdef FLB_HAVE_PARSER
363+
/* Multiline core API */
364+
if (ctx->multiline_parsers && mk_list_size(ctx->multiline_parsers) > 0) {
365+
ret = multiline_load_parsers(ctx);
366+
if (ret != 0) {
367+
flb_plg_error(ctx->ins, "could not load multiline parsers");
368+
flb_tail_config_destroy(ctx);
369+
return NULL;
370+
}
371+
372+
/* Enable auto-flush routine */
373+
ret = flb_ml_auto_flush_init(ctx->ml_ctx);
374+
if (ret == -1) {
375+
flb_plg_error(ctx->ins, "could not start multiline auto-flush");
376+
flb_tail_config_destroy(ctx);
377+
return NULL;
378+
}
379+
flb_plg_info(ctx->ins, "multiline core started");
380+
}
381+
#endif
382+
322383
#ifdef FLB_HAVE_METRICS
323384
flb_metrics_add(FLB_TAIL_METRIC_F_OPENED,
324385
"files_opened", ctx->ins->metrics);
@@ -336,6 +397,10 @@ int flb_tail_config_destroy(struct flb_tail_config *config)
336397

337398
#ifdef FLB_HAVE_PARSER
338399
flb_tail_mult_destroy(config);
400+
401+
if (config->ml_ctx) {
402+
flb_ml_destroy(config->ml_ctx);
403+
}
339404
#endif
340405

341406
/* Close pipe ends */

plugins/in_tail/tail_config.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
#ifdef FLB_HAVE_REGEX
3030
#include <fluent-bit/flb_regex.h>
3131
#endif
32+
#ifdef FLB_HAVE_PARSER
33+
#include <fluent-bit/multiline/flb_ml.h>
34+
#endif
3235

3336
/* Metrics */
3437
#ifdef FLB_HAVE_METRICS
@@ -111,6 +114,10 @@ struct flb_tail_config {
111114
int docker_mode_flush; /* Docker mode flush/wait */
112115
struct flb_parser *docker_mode_parser; /* Parser for separate multiline logs */
113116

117+
/* Multiline core engine */
118+
struct flb_ml *ml_ctx;
119+
struct mk_list *multiline_parsers;
120+
114121
/* Lists head for files consumed statically (read) and by events (inotify) */
115122
struct mk_list files_static;
116123
struct mk_list files_event;
@@ -123,6 +130,8 @@ struct flb_tail_config {
123130

124131
/* Plugin input instance */
125132
struct flb_input_instance *ins;
133+
134+
struct flb_config *config;
126135
};
127136

128137
struct flb_tail_config *flb_tail_config_create(struct flb_input_instance *ins,

plugins/in_tail/tail_file.c

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -248,19 +248,24 @@ static int process_content(struct flb_tail_file *file, size_t *bytes)
248248
continue;
249249
}
250250

251-
/* Empty line (just \n) */
252-
if (len == 0) {
251+
/*
252+
* Empty line (just \n): we skip empty lines only if we are NOT using
253+
* multiline core mode.
254+
*/
255+
if (len == 0 && !ctx->ml_ctx) {
253256
data++;
254257
processed_bytes++;
255258
continue;
256259
}
257260

258261
/* Process '\r\n' */
259-
crlf = (data[len-1] == '\r');
260-
if (len == 1 && crlf) {
261-
data += 2;
262-
processed_bytes += 2;
263-
continue;
262+
if (len >= 2) {
263+
crlf = (data[len-1] == '\r');
264+
if (len == 1 && crlf) {
265+
data += 2;
266+
processed_bytes += 2;
267+
continue;
268+
}
264269
}
265270

266271
/* Reset time for each line */
@@ -269,7 +274,14 @@ static int process_content(struct flb_tail_file *file, size_t *bytes)
269274
line = data;
270275
line_len = len - crlf;
271276
repl_line = NULL;
272-
if (ctx->docker_mode) {
277+
278+
if (ctx->ml_ctx) {
279+
ret = flb_ml_append(ctx->ml_ctx, file->ml_stream_id,
280+
FLB_ML_TYPE_TEXT,
281+
&out_time, line, line_len);
282+
goto go_next;
283+
}
284+
else if (ctx->docker_mode) {
273285
ret = flb_tail_dmode_process_content(now, line, line_len,
274286
&repl_line, &repl_line_len,
275287
file, ctx, out_sbuf, out_pck);
@@ -627,11 +639,26 @@ static int set_file_position(struct flb_tail_config *ctx,
627639
return 0;
628640
}
629641

642+
static int ml_flush_callback(struct flb_ml_parser *parser,
643+
struct flb_ml_stream *mst,
644+
void *data, char *buf_data, size_t buf_size)
645+
{
646+
struct flb_tail_file *file = data;
647+
648+
flb_input_chunk_append_raw(file->config->ins,
649+
file->tag_buf,
650+
file->tag_len,
651+
buf_data,
652+
buf_size);
653+
return 0;
654+
}
655+
630656
int flb_tail_file_append(char *path, struct stat *st, int mode,
631657
struct flb_tail_config *ctx)
632658
{
633659
int fd;
634660
int ret;
661+
uint64_t stream_id;
635662
size_t len;
636663
char *tag;
637664
size_t tag_len;
@@ -716,6 +743,22 @@ int flb_tail_file_append(char *path, struct stat *st, int mode,
716743
file->skip_next = FLB_FALSE;
717744
file->skip_warn = FLB_FALSE;
718745

746+
/* Multiline core mode */
747+
if (ctx->ml_ctx) {
748+
/* Create a stream for this file */
749+
ret = flb_ml_stream_create(ctx->ml_ctx,
750+
file->name, file->name_len,
751+
ml_flush_callback, file,
752+
&stream_id);
753+
if (ret != 0) {
754+
flb_plg_error(ctx->ins,
755+
"could not create multiline stream for file: %s",
756+
file->name);
757+
goto error;
758+
}
759+
file->ml_stream_id = stream_id;
760+
}
761+
719762
/* Local buffer */
720763
file->buf_size = ctx->buf_chunk_size;
721764
file->buf_data = flb_malloc(file->buf_size);
@@ -816,6 +859,11 @@ void flb_tail_file_remove(struct flb_tail_file *file)
816859
flb_plg_debug(ctx->ins, "inode=%"PRIu64" removing file name %s",
817860
file->inode, file->name);
818861

862+
/* remove the multiline.core stream */
863+
if (ctx->ml_ctx && file->ml_stream_id > 0) {
864+
flb_ml_stream_id_destroy_all(ctx->ml_ctx, file->ml_stream_id);
865+
}
866+
819867
if (file->rotated > 0) {
820868
#ifdef FLB_HAVE_SQLDB
821869
/*
@@ -833,6 +881,7 @@ void flb_tail_file_remove(struct flb_tail_file *file)
833881
flb_sds_destroy(file->dmode_lastline);
834882
mk_list_del(&file->_head);
835883
flb_tail_fs_remove(ctx, file);
884+
836885
/* avoid deleting file with -1 fd */
837886
if (file->fd != -1) {
838887
close(file->fd);

plugins/in_tail/tail_file_internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
#include <fluent-bit/flb_sds.h>
2727
#include <fluent-bit/flb_time.h>
2828

29+
#ifdef FLB_HAVE_PARSER
30+
#include <fluent-bit/multiline/flb_ml.h>
31+
#endif
32+
2933
#include "tail.h"
3034
#include "tail_config.h"
3135

@@ -67,6 +71,9 @@ struct flb_tail_file {
6771
bool dmode_complete; /* buffer contains completed log */
6872
bool dmode_firstline; /* dmode mult firstline found ? */
6973

74+
/* multiline engine: file stream_id */
75+
uint64_t ml_stream_id;
76+
7077
/* buffering */
7178
size_t parsed;
7279
size_t buf_len;

0 commit comments

Comments
 (0)