fluent-forward-go is a fast, memory-efficient implementation of the Fluent Forward v1 specification. It allows you to send events to Fluentd, Fluent Bit, and other endpoints supporting the Fluent protocol. It also includes a websocket client for high-speed proxying of Fluent events over ports such as 80 and 443.
Features include:
- TCP, TLS, mTLS, and unix socket transport
- shared-key authentication
- support for all Fluent message modes
gzipcompression- ability to send byte-encoded messages
acksupport- a websocket client for proxying Fluent messages
go get github.com/IBM/fluent-forward-goc := client.New(client.ConnectionOptions{
Factory: &client.ConnFactory{
Address: "localhost:24224",
},
})
if err := c.Connect(); err != nil {
// ...
}
defer c.Disconnect()c := client.New(client.ConnectionOptions{
Factory: &client.ConnFactory{
Address: "localhost:24224",
TLSConfig: &tls.Config{InsecureSkipVerify: true},
},
})
if err := c.Connect(); err != nil {
// ...
}
defer c.Disconnect()The record object must be a map or struct. Objects that implement the msgp.Encodable interface will the be most performant.
record := map[string]interface{}{
"Hello": "World",
}
err := c.SendMessage("tag", record)err := c.SendRaw(myMessageBytes)The client supports ack confirmations as specified by the Fluent protocol. When enabled, Send returns once the acknowledgement is received or the timeout is reached.
Note: For types other than RawMessage, the Send function sets the "chunk" option before sending. A RawMessage is immutable and must already contain a "chunk" value. The behavior is otherwise identical.
c := client.New(client.ConnectionOptions{
RequireAck: true,
})
//...
err := c.Send(myMsg)tl;dr fluent-forward-go is fast and memory efficient.
You can read more about the benchmarks here.
Run on localhost. Does not include message creation.
Benchmark_Fluent_Forward_Go_SendOnly-16 10000 10847 ns/op 0 B/op 0 allocs/opThe benchmarks below compare fluent-forward-go with the official package, fluent-logger-golang. The message is a simple map with twelve keys.
The differences in execution times can vary from one test run to another. The differences in memory allocations, however, are constant.
Benchmark_Fluent_Forward_Go_SingleMessage-16 10000 11355 ns/op 48 B/op 1 allocs/op
Benchmark_Fluent_Logger_Golang_SingleMessage-16 10000 19687 ns/op 2169 B/op 33 allocs/opBenchmark_Fluent_Forward_Go_SingleMessageAck-16 10000 768743 ns/op 185 B/op 6 allocs/op
Benchmark_Fluent_Logger_Golang_SingleMessageAck-16 10000 793360 ns/op 6015 B/op 47 allocs/opBefore running the generate tool, you must have msgp installed. To install run:
go get github.com/tinylib/msgpAfterwards, generate the msgp packets with:
go generate ./...To test against fluent-bit, start up fluent-bit in a docker container with:
docker pull fluent/fluent-bit:1.8.2
docker run -p 127.0.0.1:24224:24224/tcp -v `pwd`:`pwd` -w `pwd` \
-ti fluent/fluent-bit:1.8.2 /fluent-bit/bin/fluent-bit \
-c $(pwd)/fixtures/fluent.confYou can then build and run with:
go run ./cmd/forward -t foo.barThis will send two regular Messages, one with the timestamp as seconds since
the epoch, the other with the timestamp as seconds.nanoseconds. Those will
then be written to a file with the same name as the tag supplied as the argument
to the -t flag (foo.bar in the above example).
It will also send a ForwardMessage containing a pair of events - these will be
written to the same file.
It will then send a PackedForwardMessage containing a pair of events - these
will be written to $TAG.packed.
Last, it will send a CompressedPackedForwardMessage with the same pair of events, which should then be written to $TAG.compressed.