Hotdog is a syslog-to-Kafka forwarder which aims to get log entries into Apache Kafka as quickly as possible.
It listens for syslog messages over plaintext or TLS-encrupted TCP connection and depending on the defined Rules it will route and even modify messages on their way into a configured Kafka broker.
-
syslog over plaintext or TLS-encrypted TCP connections.
-
Rules and Actions for matching, modifying, and routing syslog messages based on the message content.
-
Rich integration with Kafka with full configuration passthrough for librdkafka
-
Built-in metrics integration for daemon health reporting.
Hotdog 0.1.0
R Tyler Croy <rtyler+hotdog@brokenco.de
Forward syslog over to Kafka with ease
USAGE:
hotdog [OPTIONS]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-c, --config <FILE> Sets a custom config file [default: hotdog.yml]
-t, --test <TEST_FILE> Test a log file against the configured rules
Hotdog can be installed by grabbing a
released binary.
The system which will run hotdog
must have libsasl2
installed, e.g.:
sudo apt-get install libsasl2-2
sudo zypper install libsasl2-3
Hotdog is configured by the hotdog.yml
file, which has a very fluid syntax at
the moment. The two main sections are the global
and rules
blocks.
Rules defined in the configuration can be tested against an example log file in order to verify that the right rules are matching the expected log inputs, for example:
❯ RUST_LOG=info ./target/debug/hotdog -t example.log
Line 1 matches on:
- Regex: ^hello\s+(?P<name>\w+)?
- Regex: .*
Line 2 matches on:
- Regex: .*
Line 3 matches on:
- Regex: .*
Line 4 matches on:
- JMESPath: meta.topic
- Regex: .*
The global
configuration configures hotdog
itself. The listen
, kafka
, and metrics
keys are all
required by default in order for hotdog
to start properly.
The global.listen
configuration is required and will determine on which
address and port hotdog
will listen. The tls
configuration key is required to function as well. When tls
is left blank,
hotdog
will listen for syslog messages in plaintext on the specified port
.
global:
listen:
address: '127.0.0.1'
port: 1514
tls:
The global.listen.tls
configuration section can be used to enable
syslog-over-TLS support from hotdog
. Currently the only two valid keys for
this section are cert
and key
, both of which should be absolute or relative
paths to PEM-encoded files on disk.
Certificate and Key files can be created with certtool --generate-privkey
--outfile ca-key.pem
global:
listen:
tls:
cert: './a/path.crt'
key: './a/path.key'
# ca is optional and when provided will ensure certificate validation
# happens
ca: './a/ca.crt'
The global.status
is an optional configuration entry which will enable the
launching of an HTTP status server on the specified addresss
and port
.
JSON formatted statistics can be retrieved on /stats
.
global:
status:
address: '127.0.0.1'
port: 8585
A global.kafka
configuration is required in order for hotdog
to function
properly. The two main configuration values are conf
and topic
.
global:
kafka:
conf:
bootstrap.servers: 'localhost:9092'
client.id: 'hotdog'
topic: 'logs'
Default: 1024
global.kafka.buffer
may contain a number indicating the size of the internal
queue for sending messages to Kafka. This queue represents the number of
internal messages hotdog
will buffer during Kafka availability issues.
This value is not the same as the librdkafka queue.buffering.max.messages
configuration, which governs the number of in-flight messages which can be sent
at any given time to the Kafka broker(s). To set that variable, include it in
the Conf section documented below.
🔥
|
If the internal Kafka queue has been filled up, new log lines received by
|
global.kafka.conf
should contain a map of
librdkafka configuration values.
hotdog
will expect every key and value to be a String. These configuration
values are passed right on to the underlying librdkafka client connection, so
whatever librdkafka supports, hotdog
supports!
Default: 30_000
global.kafka.timeout_ms
is an optional configuration which defines the
timeout in milliseconds for hotdog
to make an initial connection to the
configured Kafka brokers.
global.kafka.topic
may contain a string value which is to be considered the
"default topic" for the Forward action.
The global.metrics
configuration tells hotdog
where to send its own
internal metrics The only currently supported metrics format is
statsd.
If your environment doesn’t use statsd or you do not wish to report metrics,
set the statsd
value to an invalid host and port.
global:
metrics:
statsd: 'localhost:8125'
The global.status
configuration is fully optional but when it is enabled hotdog
will spin up an HTTP server on the configured address
and port
in order to provide
real-time status information about the daemon’s runtime to HTTP clients.
global:
status:
address: 'localhost'
port: 8585
Hotdog’s rules define how it should handle and route the syslog messages it
receives. In the hotdog.yml
, the rules must be defined as an array of maps.
Each rule is expected to a "matcher" (either regex
or
jmespath
), the field
upon which the matcher should
apply, and the actions
defining how the message should be
handled.
rules:
- jmespath: 'meta.topic'
field: msg
actions:
- type: forward
topic: '{{value}}'
# Catch-all, send everything else to a "logs-unknown" topic
- regex: '.*'
field: msg
actions:
- type: forward
topic: 'logs-unknown'
Name | Notes |
---|---|
|
The actual message sent along from the syslog server |
|
The sender’s hostname, if available. |
|
The logging application, if available, which created the syslog entry |
|
The syslog logging facility, if available, which was used to create the syslog message. For example |
|
The severity of the syslog message, if available. For example: |
The regex
matcher instructs hotdog
to match the field
against the defined
regular expression, which must follow the syntax of the
regex crate.
The matcher supports named groups in the regular expression, which are then exposed to actions such as merge and replace.
🔥
|
Named groups will override any built-in variables at the time of substitution, so be careful you are not naming your groups anything which might overlap with the built-in variable names |
Some actions, such as Replace, can perform variable substitutions on
log line. The variables available are a combination of the built-in variables
listed below, and whatever named groups exist in the regex
field of the
Rules.
Name | Description |
---|---|
|
The original log line message sent along from the syslog sender. |
|
The version of |
|
The ISO-8601 timestamp of when the message was processed. |
Actions determine what hotdog
should do with the given log line when it
receives it.
The forward action implies the Stop action when used, since
the internally tracked output
buffer is flushed when it is sent to Kafka.
The merge
action will only work when the log line is a JSON object. JSON
arrays, or other arbitrary strings will not merge properly, and cause all
subsequent actions for the given rule to be aborted.
Key | Value |
---|---|
|
A YAML map which will be merged with the JSON object deserialized from the matched log line. |
actions:
- type: merge
json:
meta:
hotdog:
version: '{{version}}'
timestamp: '{{iso8601}}'
The template
may utilize the matched and built-in variables in
order to generate a modified message. The output is only available to
subsequent actions defined after the replace
action. Subsequent rules in
the chain will not utilize this generated message.
Key | Value |
---|---|
|
A Handlebars-style template which can be used to output a modified message. |
- regex: '^hello\s+(?P<name>\w+)?'
actions:
- type: replace
template: |
Why hello there {{name}}!
hotdog
is designed to emit Statsd metrics to the statsd endpoint configured
in the Metrics section. Each metric will be prefixed under hotdog.*
.
Key | Description |
---|---|
|
Gauge tracking the number of connections |
|
Counter tracking the number of lines received by |
|
Counter tracking the number of messages submitted to Kafka |
|
Counter tracking the number of messages submitted to each Kafka topic |
|
Timer which tracks the amount of time it takes to actually write messages to Kafka |
|
Counters which count the number of different errors encountered while sending messages to Kafka. The types of possible metric names depends on the RDKafkaError enumeration from the underlying library. |
|
Number of the log lines received which could not be parsed as RFCC 5424 syslog lines. |
|
Count tracking the number of log lines which were dropped due to a full internal queue, Typically indicates an issue between |
|
Number of lines dropped because the could not be sent into the internal queue. |
|
Number of lines dropped because the configured dynamic topic could not be parsed properly (typically indicates a configuration error). |
|
Count of lines which could not have a merge action applied as configured due to a configuration error |
|
Count of lines received for a merge action which were not JSON, and therefore could not be merged. |
Hotdog is tested against the latest Rust stable. A simple cargo build
should
compile a working hotdog
binary for your platform.
On Linux systems it is easy to test with:
logger --server 127.0.0.1 -T -P 1514 "hello world"
logger --server 127.0.0.1 -T -P 1514 -f example.log
For TLS connections, you can use the openssl
s_client
command:
echo '<13>1 2020-04-18T15:16:09.956153-07:00 coconut tyler - - [timeQuality tzKnown="1" isSynced="1" syncAccuracy="505061"] hello world' | openssl s_client -connect localhost:6514
hotdog
was originally motivated by challenges with
rsyslog, a desire for a simple
configuration, and the need for built-in metrics.
Some other similar projects which can be used to get logs into Kafka: