Batch mode and load balancing

Starting with version 3.18, you can send multiple log messages in a single HTTP request if the destination HTTP server supports that.

Batch size

The batch-bytes(), batch-lines(), and batch-timeout() options of the destination determine how many log messages AxoSyslog sends in a batch. The batch-lines() option determines the maximum number of messages AxoSyslog puts in a batch in. This can be limited based on size and time:

  • AxoSyslog sends a batch every batch-timeout() milliseconds, even if the number of messages in the batch is less than batch-lines(). That way the destination receives every message in a timely manner even if suddenly there are no more messages.

  • AxoSyslog sends the batch if the total size of the messages in the batch reaches batch-bytes() bytes.

To increase the performance of the destination, increase the number of worker threads for the destination using the workers() option, or adjust the batch-bytes(), batch-lines(), batch-timeout() options.

Formatting the batch

By default, AxoSyslog separates the log messages of the batch with a newline character. You can specify a different delimiter by using the delimiter() option.

If the target application or server requires a special beginning or ending to recognize batches, use the body-prefix() and body-suffix() options to add a beginning and ending to the batch. For example, you can use these options to create JSON-encoded arrays as POST payloads, which is required by a number of REST APIs. The body of a batch HTTP request looks like this:

   value of body-prefix() option
    log-line-1 (as formatted in the body() option)
    log-line-2 (as formatted in the body() option)
    ....
    log-line-n (the number of log lines is batch-lines(), or less if batch-timeout() has elapsed or the batch would be longer than batch-bytes())
    value of body-suffix() option

Example: HTTP batch mode

The following destination sends log messages to an Elasticsearch server using the bulk API. A batch consists of 100 messages, or a maximum of 512 kilobytes, and is sent every 10 seconds (10000 milliseconds).

   destination d_http {
        http(url("http://your-elasticsearch-server/_bulk")
            method("POST")
            batch-lines(100)
            batch-bytes(512Kb)
            batch-timeout(10000)
            headers("Content-Type: application/x-ndjson")
            body-suffix("\n")
            body('{ "index":{} }
                 $(format-json --scope rfc5424 --key ISODATE)')
        );
    };

Load balancing between multiple servers

Starting with version 3.19, you can specify multiple URLs, for example, url("site1" "site2"). In this case, AxoSyslog sends log messages to the specified URLs in a load-balance fashion. This means that AxoSyslog sends each message to only one URL. For example, you can use this to send the messages to a set of ingestion nodes or indexers of your SIEM solution if a single node cannot handle the load. Note that the order of the messages as they arrive on the servers can differ from the order AxoSyslog has received them, so use load-balancing only if your server can use the timestamp from the messages. If the server uses the timestamp when it receives the messages, the order of the messages will be incorrect.

Starting with version AxoSyslog version 3.22, you can use any of the following formats to specify multiple URLs:

   url("server1", "server2", "server3"); # comma-separated strings
    url("server1" "server2" "server3"); # space-separated strings
    url("server1 server2 server3"); # space-separated within a single string

Example: HTTP load balancing

The following destination sends log messages to an Elasticsearch server using the bulk API, to 3 different ingest nodes. Each node is assigned a separate worker thread. A batch consists of 100 messages, or a maximum of 512 kilobytes, and is sent every 10 seconds (10000 milliseconds).

   destination d_http {
        http(url("http://your-elasticsearch-server/_bulk" "http://your-second-ingest-node/_bulk" "http://your-third-ingest-node/_bulk")
            method("POST")
            batch-lines(100)
            batch-bytes(512Kb)
            batch-timeout(10000)
            workers(3)
            headers("Content-Type: application/x-ndjson")
            body-suffix("\n")
            body('{ "index":{} }
                 $(format-json --scope rfc5424 --key ISODATE)')
            persist-name("d_http-load-balance")
        );
    };

If you are using load-balancing (that is, you have configured multiple servers in the url() option), increase the number of worker threads at least to the number of servers. For example, if you have set three URLs (url("site1", "site2", "site3")), set the workers() option to 3 or more.

Templates in the url()

Available in AxoSyslog version 4.5.0 and later.

In AxoSyslog, a template can only be resolved on a single message, because the same template might have different resolutions on different messages. As a batch consists of multiple messages, it’s not trivial to decide which message should be used for the resolution.

When batching is enabled and multiple workers are configured, it’s important to add only those messages to a batch which generate identical URLs. To achieve this, set the worker-partition-key() option with a template that contains all the templates used in the url() option, otherwise messages will be mixed.

For security reasons, all the templated contents in the url() option are URL-encoded automatically. The following parts of the URL cannot be templated:

  • scheme
  • host
  • port
  • user
  • password