Skip to content

Commit 2bfab63

Browse files
author
Warren Fernandes
committed
examples: out_multiinstance: update out_multiinstnace example
- Update README to explain multi-instance go plugin support - Update the plugin code to print out the reords like out_gstdout - Add Dockerfile that provides ability to build, run and visualize multi-instance example.
1 parent 66fb080 commit 2bfab63

File tree

5 files changed

+173
-7
lines changed

5 files changed

+173
-7
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
FROM golang:1.12 as gobuilder
2+
3+
WORKDIR /root
4+
5+
ENV GOOS=linux\
6+
GOARCH=amd64
7+
8+
COPY / /root/
9+
10+
RUN go get github.com/fluent/fluent-bit-go/...
11+
12+
RUN go build \
13+
-buildmode=c-shared \
14+
-o /out_multiinstance.so \
15+
out.go
16+
17+
FROM fluent/fluent-bit:1.1
18+
19+
COPY --from=gobuilder /out_multiinstance.so /fluent-bit/bin/
20+
COPY --from=gobuilder /root/fluent-bit.conf /fluent-bit/etc/
21+
COPY --from=gobuilder /root/plugins.conf /fluent-bit/etc/
22+
23+
EXPOSE 2020
24+
25+
# CMD ["/fluent-bit/bin/fluent-bit", "--plugin", "/fluent-bit/bin/out_multiinstance.so", "--config", "/fluent-bit/etc/fluent-bit.conf"]¬
26+
CMD ["/fluent-bit/bin/fluent-bit", "--config", "/fluent-bit/etc/fluent-bit.conf"
Lines changed: 100 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,100 @@
1-
This example demonstrates using a plugin where there are multiple instances
2-
and `FLBPluginFlushCtx` is used to disambiguate multiple instances of the
3-
output plugin.
1+
# Example: out_multiinstance
2+
3+
The following example code implements an output plugin that works with
4+
multiple configured instances. It describes how to share context from the
5+
specified instance configuration to the flush callback.
6+
7+
Every output plugin go through four callbacks associated to different phases:
8+
9+
| Plugin Phase | Callback |
10+
|---------------------|----------------------------|
11+
| Registration | FLBPluginRegister() |
12+
| Initialization | FLBPluginInit() |
13+
| Runtime Flush | FLBPluginFlushCtx() |
14+
| Exit | FLBPluginExit() |
15+
16+
## Plugin Registration
17+
18+
When Fluent Bit loads a Golang plugin, it looks up and loads the registration
19+
callback that aims to populate the internal structure with plugin name and
20+
description:
21+
22+
```go
23+
//export FLBPluginRegister
24+
func FLBPluginRegister(def unsafe.Pointer) int {
25+
return output.FLBPluginRegister(ctx, "multiinstance", "Testing multiple instances")
26+
}
27+
```
28+
29+
This function is invoked at start time _before_ any configuration is done
30+
inside the engine.
31+
32+
## Plugin Initialization
33+
34+
Before the engine starts, it initializes all plugins that were configured.
35+
As part of the initialization, the plugin can obtain configuration parameters
36+
and do any other internal checks. It can also set the context for this
37+
instance in case params need to be retrieved during flush.
38+
E.g:
39+
40+
```go
41+
//export FLBPluginInit
42+
func FLBPluginInit(ctx unsafe.Pointer) int {
43+
id := output.FLBPluginConfigKey(plugin, "id")
44+
log.Printf("[multiinstance] id = %q", id)
45+
// Set the context to point to any Go variable
46+
output.FLBPluginSetContext(plugin, unsafe.Pointer(&id))
47+
return output.FLB_OK
48+
}
49+
```
50+
51+
The function must return FLB\_OK when it initialized properly or FLB\_ERROR if
52+
something went wrong. If the plugin reports an error, the engine will _not_
53+
load the instance.
54+
55+
## Runtime Flush with Context
56+
57+
Upon flush time, when Fluent Bit wants to flush it's buffers, the runtime flush
58+
callback will be triggered.
59+
60+
The callback will receive the configuration context, a raw buffer of msgpack
61+
data, the proper bytes length and the associated tag.
62+
63+
```go
64+
//export FLBPluginFlushCtx
65+
func FLBPluginFlush(ctx, data unsafe.Pointer, length C.int, tag *C.char) int {
66+
67+
id := *(*string)(ctx)
68+
log.Printf("[multiinstance] Flush called for id: %s", *id)
69+
return output.FLB_OK
70+
}
71+
```
72+
73+
When done, there are three returning values available:
74+
75+
| Return value | Description |
76+
|---------------|------------------------------------------------|
77+
| FLB\_OK | The data have been processed normally. |
78+
| FLB\_ERROR | An internal error have ocurred, the plugin will not handle the set of records/data again. |
79+
| FLB\_RETRY | A recoverable error have ocurred, the engine can try to flush the records/data later.|
80+
81+
## Plugin Exit
82+
83+
When Fluent Bit will stop using the instance of the plugin, it will trigger the exit callback. e.g:
84+
85+
```go
86+
//export FLBPluginExit
87+
func FLBPluginExit() int {
88+
return output.FLB_OK
89+
}
90+
```
91+
92+
## Playground
93+
94+
Build the docker image locally to see how it works.
95+
96+
```bash
97+
$ cd $GOPATH/src/github.com/fluent/fluent-bit-go/examples/out_multiinstance
98+
$ docker build . -t fluent-bit-multiinstance
99+
$ docker run -it --rm fluent-bit-multiinstance
100+
```
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[SERVICE]
2+
Flush 5
3+
Daemon Off
4+
Log_Level info
5+
Parsers_File parsers.conf
6+
Plugins_File plugins.conf
7+
HTTP_Server Off
8+
HTTP_Listen 0.0.0.0
9+
HTTP_Port 2020
10+
11+
[INPUT]
12+
Name cpu
13+
Tag cpu.local
14+
Interval_Sec 1
15+
16+
[INPUT]
17+
Name dummy
18+
Tag dummy.local
19+
20+
[OUTPUT]
21+
Name multiinstance
22+
Match cpu*
23+
Id cpu_metrics
24+
25+
[OUTPUT]
26+
Name multiinstance
27+
Match dummy*
28+
Id dummy_metrics

examples/out_multiinstance/out.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
// +build example
12
package main
23

34
import (
45
"C"
6+
"fmt"
57
"log"
68
"unsafe"
79

@@ -24,23 +26,34 @@ func FLBPluginInit(plugin unsafe.Pointer) int {
2426

2527
//export FLBPluginFlush
2628
func FLBPluginFlush(data unsafe.Pointer, length C.int, tag *C.char) int {
27-
log.Print("Flush called for unknown instance")
29+
log.Print("[multiinstance] Flush called for unknown instance")
2830
return output.FLB_OK
2931
}
3032

3133
//export FLBPluginFlushCtx
3234
func FLBPluginFlushCtx(ctx, data unsafe.Pointer, length C.int, tag *C.char) int {
3335
// Cast context back into the original type for the Go variable
34-
id := (*string)(ctx)
35-
log.Printf("Flush called for id: %s", *id)
36+
id := *(*string)(ctx)
37+
log.Printf("[multiinstance] Flush called for id: %s", id)
3638

3739
dec := output.NewDecoder(data, int(length))
3840

41+
count := 0
3942
for {
40-
ret, _, _ := output.GetRecord(dec)
43+
ret, ts, record := output.GetRecord(dec)
4144
if ret != 0 {
4245
break
4346
}
47+
48+
// Print record keys and values
49+
timestamp := ts.(output.FLBTime)
50+
fmt.Printf("[%d] %s: [%s, {", count, C.GoString(tag), timestamp.String())
51+
52+
for k, v := range record {
53+
fmt.Printf("\"%s\": %v, ", k, v)
54+
}
55+
fmt.Printf("}\n")
56+
count++
4457
}
4558

4659
return output.FLB_OK
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[PLUGINS]
2+
Path /fluent-bit/bin/out_multiinstance.so

0 commit comments

Comments
 (0)