Skip to content

Commit 9fa5f02

Browse files
Patrick Stephensedsiper
Patrick Stephens
authored andcommitted
dockerfiles: add top-level link
Signed-off-by: Patrick Stephens <[email protected]>
1 parent 63ac130 commit 9fa5f02

File tree

4 files changed

+86
-37
lines changed

4 files changed

+86
-37
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,5 @@ compile_commands.json
3535

3636
workflow/
3737
.kitchen/
38+
39+
.vagrant/

DEVELOPER_GUIDE.md

+79-35
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,44 @@
1-
## Beginners Guide to Contributing to Fluent Bit
1+
# Beginners Guide to Contributing to Fluent Bit
22

33
Assuming you have some basic knowledge of C, this guide should help you understand how to make code
44
changes to Fluent Bit.
55

6-
### Table of Contents
7-
- [Libraries](#libraries)
6+
## Table of Contents
7+
8+
- [Beginners Guide to Contributing to Fluent Bit](#beginners-guide-to-contributing-to-fluent-bit)
9+
- [Table of Contents](#table-of-contents)
10+
- [Libraries](#libraries)
811
- [Memory Management](#memory-management)
912
- [Strings](#strings)
1013
- [HTTP Client](#http-client)
1114
- [Linked Lists](#linked-lists)
1215
- [Message Pack](#message-pack)
13-
- [Concurrency](#concurrency)
14-
- [Plugin API](#plugin-api)
16+
- [Concurrency](#concurrency)
17+
- [Coroutine Code: How does it work?](#coroutine-code-how-does-it-work)
18+
- [Practical Advice: How coroutines will affect your code](#practical-advice-how-coroutines-will-affect-your-code)
19+
- [Filter Plugins](#filter-plugins)
20+
- [Output plugins](#output-plugins)
21+
- [Plugin API](#plugin-api)
1522
- [Input](#input)
1623
- [Filter](#filter)
1724
- [Output](#output)
1825
- [Config Maps](#config-maps)
19-
- [Testing](#testing)
26+
- [Testing](#testing)
2027
- [Valgrind](#valgrind)
21-
- [Need more help?](#need-more-help)
28+
- [Need more help?](#need-more-help)
2229

23-
### Libraries
30+
## Libraries
2431

2532
Most external libraries are embedded in the project in the [/lib](/lib) folder. To keep its footprint low and make cross-platform builds simple, Fluent Bit attempts keep its dependency graph small.
2633

2734
The external library you are mostly likely to interact with is [msgpack](https://github.com/msgpack/msgpack-c).
2835

2936
For crypto, Fluent Bit uses [mbedtls](https://github.com/ARMmbed/mbedtls).
3037

31-
#### Memory Management
38+
### Memory Management
3239

3340
When you write Fluent Bit code, you will use Fluent Bit's versions of the standard C functions for working with memory:
41+
3442
- [`flb_malloc()`](include/fluent-bit/flb_mem.h) - equivalent to `malloc`, allocates memory.
3543
- [`flb_calloc()`](include/fluent-bit/flb_mem.h) - equivalent to `calloc`, allocates memory and initializes it to zero.
3644
- [`flb_realloc()`](include/fluent-bit/flb_mem.h) - equivalent to `realloc`.
@@ -39,15 +47,16 @@ When you write Fluent Bit code, you will use Fluent Bit's versions of the standa
3947
Note that many types have a specialized create and destroy function. For example,
4048
[`flb_sds_create()` and `flb_sds_destroy()`](include/fluent-bit/flb_sds.h) (more about this in the next section).
4149

42-
#### Strings
50+
### Strings
4351

4452
Fluent Bit has a stripped down version of the popular [SDS](https://github.com/antirez/sds) string library. See [flb_sds.h](include/fluent-bit/flb_sds.h) for the API.
4553

4654
In general, you should use SDS strings in any string processing code. SDS strings are fully compatible with any C function that accepts a null-terminated sequence of characters; to understand how they work, see the [explanation on Github](https://github.com/antirez/sds#how-sds-strings-work).
4755

48-
#### HTTP Client
56+
### HTTP Client
4957

5058
Fluent Bit has its own network connection library. The key types and functions are defined in the following header files:
59+
5160
- [flb_upstream.h](include/fluent-bit/flb_upstream.h)
5261
- [flb_http_client.h](include/fluent-bit/flb_http_client.h)
5362
- [flb_io.h](include/fluent-bit/flb_io.h)
@@ -103,7 +112,7 @@ static flb_sds_t make_request(struct flb_config *config)
103112
}
104113

105114
/* Perform the HTTP request */
106-
ret = flb_http_do(client, &b_sent)
115+
ret = flb_http_do(client, &b_sent)
107116

108117
/* Validate return status and HTTP status if set */
109118
if (ret != 0 || client->resp.status != 200) {
@@ -131,7 +140,7 @@ static flb_sds_t make_request(struct flb_config *config)
131140
132141
An `flb_upstream` structure represents a host/endpoint that you want to call. Normally, you'd store this structure somewhere so that it can be re-used. An `flb_upstream_conn` represents a connection to that host for a single HTTP request. The connection structure should not be used for more than one request.
133142
134-
#### Linked Lists
143+
### Linked Lists
135144
136145
Fluent Bit contains a library for constructing linked lists- [mk_list](lib/monkey/include/monkey/mk_core/mk_list.h). The type stores data as a circular linked list.
137146
@@ -190,7 +199,7 @@ static int example()
190199
}
191200
```
192201

193-
#### Message Pack
202+
### Message Pack
194203

195204
Fluent Bit uses [msgpack](https://msgpack.org/index.html) to internally store data. If you write code for Fluent Bit, it is almost certain that you will interact with msgpack.
196205

@@ -280,29 +289,32 @@ static int cb_filter(const void *data, size_t bytes,
280289
281290
Please also check out the message pack examples on the [msgpack-c GitHub repo](https://github.com/msgpack/msgpack-c).
282291
283-
### Concurrency
292+
## Concurrency
284293
285294
Fluent Bit uses ["coroutines"](https://en.wikipedia.org/wiki/Coroutine); a concurrent programming model in which subroutines can be paused and resumed. Co-routines are cooperative routines- instead of blocking, they cooperatively pass execution between each other. Coroutines are implemented as part of Fluent Bit's core network IO libraries. When a blocking network IO operation is made (for example, waiting for a response on a socket), a routine will cooperatively yield (pause itself) and pass execution to Fluent Bit engine, which will schedule (activate) other routines. Once the blocking IO operation is complete, the sleeping coroutine will be scheduled again (resumed). This model allows Fluent Bit to achieve performance benefits without the headaches that often come from having multiple active threads.
286295
287296
This Fluent Bit engine consists of an event loop that is built upon [github.com/monkey/monkey](https://github.com/monkey/monkey). The monkey project is a server and library designed for low resource usage. It was primarily implemented by Eduardo Silva, who also created Fluent Bit.
288297
289-
#### Coroutine Code: How does it work?
298+
### Coroutine Code: How does it work?
290299
291300
To understand how this works, let's walkthrough an example in the code.
292301
293302
The elasticsearch plugin makes an HTTP request to an elasticsearch cluster, when the following [line of code runs](https://github.com/fluent/fluent-bit/blob/1.3/plugins/out_es/es.c#L581):
303+
294304
```c
295305
ret = flb_http_do(c, &b_sent);
296306
```
297307

298308
This calls the http request function, in [`flb_http_client.c`, which makes a TCP write call](https://github.com/fluent/fluent-bit/blob/1.3/src/flb_http_client.c#L840):
309+
299310
```c
300311
ret = flb_io_net_write(c->u_conn,
301312
c->body_buf, c->body_len,
302313
&bytes_body);
303314
```
304315

305316
That activates code in Fluent Bit's core TCP library, which is where the coroutine magic happens. This code is in [flb_io.c](https://github.com/fluent/fluent-bit/blob/1.3/src/flb_io.c#L241). After opening a socket, the code inserts an item on the event loop:
317+
306318
```c
307319
ret = mk_event_add(u->evl,
308320
u_conn->fd,
@@ -311,6 +323,7 @@ ret = mk_event_add(u->evl,
311323
```
312324

313325
This instructs the event loop to watch our socket's file descriptor. Then, [a few lines below, we yield back to the engine thread](https://github.com/fluent/fluent-bit/blob/1.3/src/flb_io.c#L304):
326+
314327
```c
315328
/*
316329
* Return the control to the parent caller, we need to wait for
@@ -322,6 +335,7 @@ flb_thread_yield(th, FLB_FALSE);
322335
Remember, only one thread is active at a time. If the current coroutine did not yield back to engine, it would monopolize execution until the socket IO operation was complete. Since IO operations may take a long time, we can increase performance by allowing another routine to perform work.
323336
324337
The core routine in Fluent Bit is the engine in `flb_engine.c`. Here we can find the [code that will resume the elasticsearch plugin](https://github.com/fluent/fluent-bit/blob/1.3/src/flb_engine.c#L553) once it's IO operation is complete:
338+
325339
```c
326340
if (event->type == FLB_ENGINE_EV_THREAD) {
327341
struct flb_upstream_conn *u_conn;
@@ -340,17 +354,18 @@ if (event->type == FLB_ENGINE_EV_THREAD) {
340354

341355
This will return execution to the code right after the [flb_thread_yield](https://github.com/fluent/fluent-bit/blob/1.3/src/flb_io.c#L304) call in the IO library.
342356

343-
#### Practical Advice: How coroutines will affect your code
357+
### Practical Advice: How coroutines will affect your code
344358

345-
##### Filter Plugins
359+
#### Filter Plugins
346360

347361
Filter plugins do not support coroutines, consequently you must disable async mode if your filter makes an HTTP request:
362+
348363
```c
349364
/* Remove async flag from upstream */
350365
upstream->flags &= ~(FLB_IO_ASYNC);
351366
```
352367

353-
##### Output plugins
368+
#### Output plugins
354369

355370
Output plugins use coroutines. Plugins have a context structure which is available in all calls and can be used to store state. In general, you can write code without ever considering concurrency. This is because only one coroutine is active at a time. Thus, synchronization primitives like mutex locks or semaphores are not needed.
356371

@@ -393,18 +408,17 @@ This can be re-enabled at any time:
393408
upstream->flags |= FLB_IO_ASYNC;
394409
```
395410

396-
397-
### Plugin API
411+
## Plugin API
398412

399413
Each plugin is a shared object which is [loaded into Fluent Bit](https://github.com/fluent/fluent-bit/blob/1.3/src/flb_plugin.c#L70) using dlopen and dlsym.
400414

401-
#### Input
415+
### Input
402416

403417
The input plugin structure is defined in [flb_input.h](https://github.com/fluent/fluent-bit/blob/master/include/fluent-bit/flb_input.h#L62). There are a number of functions which a plugin can implement, most only implement `cb_init`, `cb_collect`, and `cb_exit`.
404418

405419
The [`"dummy"` input plugin](plugins/in_dummy) very simple and is an excellent example to review to understand more.
406420

407-
#### Filter
421+
### Filter
408422

409423
The structure for filter plugins is defined in [flb_filter.h](https://github.com/fluent/fluent-bit/blob/master/include/fluent-bit/flb_filter.h#L44). Each plugin must implement `cb_init`, `cb_filter`, and `cb_exit`.
410424

@@ -417,13 +431,13 @@ Note that filter plugins can not asynchronously make HTTP requests. If your plug
417431
upstream->flags &= ~(FLB_IO_ASYNC);
418432
```
419433

420-
#### Output
434+
### Output
421435

422436
Output plugins are defined in [flb_output.h](https://github.com/fluent/fluent-bit/blob/master/include/fluent-bit/flb_output.h#L57). Each plugin must implement `cb_init`, `cb_flush`, and `cb_exit`.
423437

424438
The [stdout plugin](plugins/out_stdout) is very simple; review its code to understand how output plugins work.
425439

426-
#### Config Maps
440+
### Config Maps
427441

428442
Config maps are an improvement to the previous Fluent Bit API that was used by plugins to read configuration values. The new config maps feature warns the user if there is an unknown configuration key and reduces risk of bad configuration due to typos or deprecated property names. They will also allow dynamic configuration reloading to be implemented in the future.
429443

@@ -488,10 +502,10 @@ struct flb_output_plugin out_stdout_plugin = {
488502
};
489503

490504
```
505+
491506
In the above code snippet, the property *format* is of type string which supports formats like json, msgpack etc. It has default value NULL(in which case it uses msgpack), no flags, and it is being only validated by the config map and hence set_property field is `FLB_FALSE` with member offset 0. No description is written for *format* property at present.
492507
Similarly, for the property *json_date_key*, type is string, default value is date, and it is being written to context so the set_property field is `FLB_TRUE` with a member offset. Again, no description is written for it.
493508

494-
495509
Upon initilization the engine loads the config map like [this](https://github.com/fluent/fluent-bit/blob/v1.4.2/plugins/out_stdout/stdout.c#L48):
496510

497511
```c
@@ -501,23 +515,53 @@ Upon initilization the engine loads the config map like [this](https://github.co
501515
[flb_output_config_map_set](https://github.com/fluent/fluent-bit/blob/v1.4.2/include/fluent-bit/flb_output.h#L510) returns [flb_config_map_set](https://github.com/fluent/fluent-bit/blob/v1.4.2/src/flb_config_map.c#L513) which is a function used by plugins that needs to populate their context structure with the configuration properties already mapped.
502516

503517
Some points to keep in mind while migrating an existing plugin to a config map interface:
518+
504519
- All memory allocations and releases of properties on exit are handled by the config map interface.
505520
- The config map does not parse host and port properties since these properties are handled automatically for plugins that perform network operations.
506521
- Some plugins might also have an empty config_map. This is so that it would show an error when someone tried to use a non-existent parameter.
507522

508-
### Testing
523+
## Testing
509524

510525
During development, you can build Fluent Bit as follows:
511526

512-
```
527+
```shell
513528
cd build
514529
cmake -DFLB_DEV=On ../
515530
make
516531
```
532+
517533
Note that Fluent Bit uses Cmake 3 and on some systems you may need to invoke it as `cmake3`.
518534

519-
To enable the unit tests run:
535+
To set up and build your environment, please refer to the packaging containers for a dependency list: <https://github.com/fluent/fluent-bit/tree/master/packaging/distros>.
536+
537+
A [`Vagrantfile`](./Vagrantfile) is provided to simplify building on a VM, this will set up a VM using Vagrant you can then build in.
538+
539+
```shell
540+
vagrant up
541+
vagrant ssh
542+
cd build
543+
rm -rf *
544+
cmake ...
545+
make
546+
```
547+
548+
Be aware of any permissions issues with the filesystem on the VM vs the host.
549+
You may prefer to build to an un-exposed filesystem:
550+
551+
```shell
552+
vagrant up
553+
vagrant ssh
554+
mkdir -p /tmp/build
555+
cd /tmp/build
556+
cmake ... /vagrant
557+
make
520558
```
559+
560+
It also acts as a reference for the tooling required to be installed on a local PC if you want to build things.
561+
562+
To enable the unit tests run:
563+
564+
```shell
521565
cmake -DFLB_DEV=On -DFLB_TESTS_RUNTIME=On -DFLB_TESTS_INTERNAL=On ../
522566
make
523567
```
@@ -526,31 +570,31 @@ Internal tests are for the internal libraries of Fluent Bit. Runtime tests are f
526570

527571
You can run the unit tests with `make test`, however, this is inconvenient in practice. Each test file will create an executable in the `build/bin` directory which you can run directly. For example, if you want to run the SDS tests, you can invoke them as follows:
528572

529-
```
573+
```shell
530574
$ ./bin/flb-it-sds
531575
Test sds_usage... [ OK ]
532576
Test sds_printf... [ OK ]
533577
SUCCESS: All unit tests have passed.
534578
```
535579

536-
#### Valgrind
580+
### Valgrind
537581

538582
[Valgrind](https://valgrind.org/) is a tool that will help you detect and diagnose memory issues in your code. It will check for memory leaks and invalid memory accesses.
539583

540584
To use it while developing, invoke it before Fluent Bit:
541585

542-
```
586+
```shell
543587
valgrind ./bin/fluent-bit {args for fluent bit}
544588
```
545589

546590
Valgrind becomes especially powerful when you run it on your unit tests. We recommend writing unit tests that cover a large fraction of code paths in your contribution. You can then check your code for memory issues by invoking the test binaries with Valgrind:
547591

548-
```
549-
$ valgrind ./bin/flb-rt-your-test
592+
```shell
593+
valgrind ./bin/flb-rt-your-test
550594
```
551595

552596
This will allow you to check for memory issues in code paths (ex error cases) which are hard to trigger through manual testing.
553597

554-
### Need more help?
598+
## Need more help?
555599

556600
The best way to learn how Fluent Bit code works is to read it. If you need help understanding the code, reach out to the community, or open a PR with changes that are a work in progress.

Dockerfile

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
./dockerfiles/Dockerfile

dockerfiles/Dockerfile

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
# docker buildx build --platform "linux/amd64,linux/arm64,linux/arm/v7" -f ./dockerfiles/Dockerfile.multiarch --build-arg FLB_TARBALL=https://github.com/fluent/fluent-bit/archive/v1.8.11.tar.gz ./dockerfiles/
1212

1313
# Set this to the current release version: it gets done so as part of the release.
14-
ARG RELEASE_VERSION=1.9.5
14+
ARG RELEASE_VERSION=1.9.6
1515

1616
# For multi-arch builds - assumption is running on an AMD64 host
1717
FROM multiarch/qemu-user-static:x86_64-arm as qemu-arm32
1818
FROM multiarch/qemu-user-static:x86_64-aarch64 as qemu-arm64
1919

20-
FROM debian:bullseye-slim as builder
20+
FROM debian:bullseye-slim as builder-base
2121

2222
COPY --from=qemu-arm32 /usr/bin/qemu-arm-static /usr/bin/
2323
COPY --from=qemu-arm64 /usr/bin/qemu-aarch64-static /usr/bin/
@@ -56,6 +56,8 @@ RUN apt-get update && \
5656
WORKDIR /src/fluent-bit/
5757
COPY . ./
5858

59+
# We split the builder setup out so people can target it or use as a base image without doing a full build.
60+
FROM builder-base as builder
5961
WORKDIR /src/fluent-bit/build/
6062
RUN cmake -DFLB_RELEASE=On \
6163
-DFLB_TRACE=Off \

0 commit comments

Comments
 (0)