<div dir="ltr">Dear syslog-ng users,<br><br><div>We are pleased to announce that the 4.1.0 version of syslog-ng has been released, and it is now available on GitHub:</div><div><br></div><div><a href="https://github.com/syslog-ng/syslog-ng/releases/tag/syslog-ng-4.1.0">https://github.com/syslog-ng/syslog-ng/releases/tag/syslog-ng-4.1.0</a></div><div><div class="gmail-markdown-body gmail-my-3"><h1>4.1.0</h1>
<h2>Highlights</h2>
<h3>PROXY protocol v2 support (<a href="https://github.com/syslog-ng/syslog-ng/pull/4211">#4211</a>)</h3>
<p>We've added support for PROXY protocol v2 (<code>transport(proxied-tcp)</code>), a protocol<br>
used by network load balancers, such as Amazon Elastic Load Balancer and<br>
HAProxy, to carry original source/destination address information, as described<br>
in <a href="https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt" rel="nofollow">https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt</a></p>
<h3>Metrics revised</h3>
<h4>Prometheus metric format (<a href="https://github.com/syslog-ng/syslog-ng/pull/4325">#4325</a>)</h4>
<p>A new metric system has been introduced to syslog-ng, where metrics are<br>
identified by names and partitioned by labels, which is similar to the<br>
<a href="https://prometheus.io/docs/concepts/data_model/" rel="nofollow">Prometheus data model</a>.</p>
<p>The <code>syslog-ng-ctl stats prometheus</code> command can be used to query syslog-ng<br>
metrics in a format that conforms to the Prometheus text-based exposition<br>
format.</p>
<p><code>syslog-ng-ctl stats prometheus --with-legacy-metrics</code> displays legacy metrics<br>
as well. Legacy metrics do not follow Prometheus' metric and label conventions.</p>
<h4>Classification (metadata-based metrics) (<a href="https://github.com/syslog-ng/syslog-ng/pull/4318">#4318</a>)</h4>
<p><code>metrics-probe()</code>, a new parser has also been added, which counts messages<br>
passing through based on the metadata of each message. The parser creates<br>
labeled metrics based on the fields of the message.</p>
<p>Both the key and labels can be set in the config, the values of the labels can<br>
be templated. E.g.:</p>
<div class="gmail-snippet-clipboard-content gmail-notranslate gmail-position-relative gmail-overflow-auto"><pre class="gmail-notranslate"><code>parser p_metrics_probe {
  metrics-probe(
    key("custom_key")  # adds "syslogng_" prefix => "syslogng_custom_key"
    labels(
      "custom_label_name_1" => "foobar"
      "custom_label_name_2" => "${.custom.field}"
    )
  );
};
</code></pre></div>
<p>With this config, it creates counters like these:</p>
<div class="gmail-snippet-clipboard-content gmail-notranslate gmail-position-relative gmail-overflow-auto"><pre class="gmail-notranslate"><code>syslogng_custom_key{custom_label_name_1="foobar", custom_label_name_2="bar"} 1
syslogng_custom_key{custom_label_name_1="foobar", custom_label_name_2="foo"} 1
syslogng_custom_key{custom_label_name_1="foobar", custom_label_name_2="baz"} 3
</code></pre></div>
<p>The minimal config creates counters with the key<br>
<code>syslogng_classified_events_total</code> and labels <code>app</code>, <code>host</code>, <code>program</code> and<br>
<code>source</code>. E.g.:</p>
<div class="gmail-snippet-clipboard-content gmail-notranslate gmail-position-relative gmail-overflow-auto"><pre class="gmail-notranslate"><code>parser p_metrics_probe {
  metrics-probe();
};
</code></pre></div>
<p>With this config, it creates counters like these:</p>
<div class="gmail-snippet-clipboard-content gmail-notranslate gmail-position-relative gmail-overflow-auto"><pre class="gmail-notranslate"><code>syslogng_classified_events_total{app="example-app", host="localhost", program="baz", source="s_local_1"} 3
syslogng_classified_events_total{app="example-app", host="localhost", program="bar", source="s_local_1"} 1
syslogng_classified_events_total{app="example-app", host="localhost", program="foo", source="s_local_1"} 1
</code></pre></div>
<h4>Named log paths (path ingress/egress metrics) (<a href="https://github.com/syslog-ng/syslog-ng/pull/4344">#4344</a>)</h4>
<p>It is also possible to create named log paths, for example:</p>
<div class="gmail-snippet-clipboard-content gmail-notranslate gmail-position-relative gmail-overflow-auto"><pre class="gmail-notranslate"><code>log top-level {
    source(s_local);

    log inner-1 {
        filter(f_inner_1);
        destination(d_local_1);
    };

    log inner-2 {
        filter(f_inner_2);
        destination(d_local_2);
    };
};
</code></pre></div>
<p>Each named log path counts its ingress and egress messages:</p>
<div class="gmail-snippet-clipboard-content gmail-notranslate gmail-position-relative gmail-overflow-auto"><pre class="gmail-notranslate"><code>syslogng_log_path_ingress{id="top-level"} 114
syslogng_log_path_ingress{id="inner-1"} 114
syslogng_log_path_ingress{id="inner-2"} 114
syslogng_log_path_egress{id="top-level"} 103
syslogng_log_path_egress{id="inner-1"} 62
syslogng_log_path_egress{id="inner-2"} 41
</code></pre></div>
<p>Note that the egress statistics only count the messages which have been have not<br>
been filtered out from the related log path, it does care about whether there<br>
are any destinations in it or that any destination delivers or drops the<br>
message.</p>
<p>The above three features are experimental; the output of <code>stats prometheus</code><br>
(names, labels, etc.) and the metrics created by <code>metrics-probe()</code> and named log<br>
paths may change in the next 2-3 releases.</p>
<h2>Features</h2>
<ul><li>
<p><code>$(format-date)</code>: add a new template function to format time and date values</p>
<p><code>$(format-date [options] format-string [timestamp])</code></p>
<p><code>$(format-date)</code> takes a timestamp in the DATETIME representation and<br>
formats it according to an strftime() format string.  The DATETIME<br>
representation in syslog-ng is a UNIX timestamp formatted as a decimal<br>
number, with an optional fractional part, where the seconds and the<br>
fraction of seconds are separated by a dot.</p>
<p>If the timestamp argument is missing, the timestamp of the message is<br>
used.</p>
<p>Options:<br>
<code>--time-zone <TZstring></code> -- override timezone of the original timestamp<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4202">#4202</a>)</p>
</li><li>
<p><code>syslog-parser()</code> and all syslog related sources: accept unquoted RFC5424<br>
SD-PARAM-VALUEs instead of rejecting them with a parse error.</p>
<p><code>sdata-parser()</code>: this new parser allows you to parse an RFC5424 style<br>
structured data string. It can be used to parse this relatively complex<br>
format separately.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4281">#4281</a>)</p>
</li><li>
<p><code>system()</code> source: the <code>system()</code> source was changed on systemd platforms to<br>
fetch journal messages that relate to the current boot only (e.g.  similar<br>
to <code>journalctl -fb</code>) and to ignore messages generated in previous boots,<br>
even if those messages were succesfully stored in the journal and were not<br>
picked up by syslog-ng.  This change was implemented as the journald access<br>
APIs work incorrectly if time goes backwards across reboots, which is an<br>
increasingly frequent event in virtualized environments and on systems that<br>
lack an RTC.  If you want to retain the old behaviour, please bypass the<br>
<code>system()</code> source and use <code>systemd-journal()</code> directly, where this option<br>
can be customized. The change is not tied to <code>@version</code> as we deemed the new<br>
behaviour fixing an actual bug. For more information consult <a class="gmail-issue-link gmail-js-issue-link" href="https://github.com/syslog-ng/syslog-ng/issues/2836">#2836</a>.</p>
<p><code>systemd-journald()</code> source: add <code>match-boot()</code> and <code>matches()</code> options to<br>
allow you to constrain the collection of journal records to a subset of what<br>
is in the journal. <code>match-boot()</code> is a yes/no value that allows you to fetch<br>
messages that only relate to the current boot. <code>matches()</code> allows you to<br>
specify one or more filters on journal fields.</p>
<p>Examples:</p>
<div class="gmail-snippet-clipboard-content gmail-notranslate gmail-position-relative gmail-overflow-auto"><pre class="gmail-notranslate"><code>source s_journal_current_boot_only {
  systemd-source(match-boot(yes));
};

source s_journal_systemd_only {
  systemd-source(matches(
    "_COMM" => "systemd"
    )
  );
};
</code></pre></div>
<p>(<a href="https://github.com/syslog-ng/syslog-ng/pull/4245">#4245</a>)</p>
</li><li>
<p><code>date-parser()</code>: add <code>value()</code> parameter to instruct <code>date-parser()</code> to store<br>
the resulting timestamp in a name-value pair, instead of changing the<br>
timestamp value of the LogMessage.</p>
<p><code>datetime</code> type representation: typed values in syslog-ng are represented as<br>
strings when stored as a part of a log message.  syslog-ng simply remembers<br>
the type it was stored as.  Whenever the value is used as a specific type in<br>
a type-aware context where we need the value of the specific type, an<br>
automatic string parsing takes place.  This parsing happens for instance<br>
whenever syslog-ng stores a datetime value in MongoDB or when<br>
<code>$(format-date)</code> template function takes a name-value pair as parameter.<br>
The datetime() type has stored its value as the number of milliseconds since<br>
the epoch (1970-01-01 00:00:00 GMT).  This has now been enhanced by making<br>
it possible to store timestamps up to nanosecond resolutions along with an<br>
optional timezone offset.</p>
<p><code>$(format-date)</code>: when applied to name-value pairs with the <code>datetime</code> type,<br>
use the timezone offset if one is available.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4319">#4319</a>)</p>
</li><li>
<p><code>stats</code>: Added <code>syslog-stats()</code> global <code>stats()</code> group option.</p>
<p>E.g.:</p>
<div class="gmail-snippet-clipboard-content gmail-notranslate gmail-position-relative gmail-overflow-auto"><pre class="gmail-notranslate"><code>options {
  stats(
    syslog-stats(no);
  );
};
</code></pre></div>
<p>It changes the behavior of counting messages based on different syslog-proto fields,<br>
like <code>SEVERITY</code>, <code>FACILITY</code>, <code>HOST</code>, etc...</p>
<p>Possible values are:</p>
<ul><li><code>yes</code> => force enable</li><li><code>no</code> => force disable</li><li><code>auto</code> => let <code>stats(level())</code> decide (old behavior)<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4337">#4337</a>)</li></ul>
</li><li>
<p><code>kubernetes</code> source: Added <code>key-delimiter()</code> option.</p>
<p>Some metadata fields can contain <code>.</code>-s in their name. This does not work<br>
with syslog-ng-s macros, which by default use <code>.</code> as a delimiter. The added<br>
<code>key-delimiter()</code> option changes this behavior by storing the parsed<br>
metadata fields with a custom delimiter. In order to reach the fields, the<br>
accessor side has to use the new delimiter format, e.g. <code>--key-delimiter</code><br>
option in <code>$(format-json)</code>.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4213">#4213</a>)</p>
</li></ul>
<h2>Bugfixes</h2>
<ul><li>
<p>Fix conditional evaluation with a dangling filter</p>
<p>We've fixed a bug that caused conditional evaluation (if/else/elif) and certain logpath flags (<code>final</code>, <code>fallback</code>)<br>
to occasionally malfunction. The issue only happened in certain logpath constructs; examples can be found in the<br>
PR description.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4058">#4058</a>)</p>
</li><li>
<p><code>python</code>: Fixed a bug, where <code>PYTHONPATH</code> was ignored with <code>python3.11</code>.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4298">#4298</a>)</p>
</li><li>
<p><code>disk-buffer</code>: Fixed disk-queue file becoming corrupt when changing <code>disk-buf-size()</code>.</p>
<p><code>syslog-ng</code> now continues with the originally set <code>disk-buf-size()</code>.<br>
Note that changing the <code>disk-buf-size()</code> of an existing disk-queue was never supported,<br>
but could cause errors, which are fixed now.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4308">#4308</a>)</p>
</li><li>
<p><code>dqtool</code>: fix <code>dqtool assign</code><br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4355">#4355</a>)</p>
</li><li>
<p><code>example-diskq-source</code>: Fixed failing to read the disk-queue content in some cases.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4308">#4308</a>)</p>
</li><li>
<p><code>default-network-drivers()</code>: Added support for the <code>log-iw-size()</code> option with a default value of 1000.<br>
Making it possible to adjust the <code>log-iw-size()</code> for the TCP/TLS based connections, when changing the <code>max-connections()</code> option.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4328">#4328</a>)</p>
</li><li>
<p><code>apache-accesslog-parser()</code>: fix rawrequest escaping binary characters<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4303">#4303</a>)</p>
</li><li>
<p><code>dqtool</code>: Fixed <code>dqtool cat</code> failing to read the content in some cases.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4308">#4308</a>)</p>
</li><li>
<p>Fixed a rare main loop related crash on FreeBSD.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4262">#4262</a>)</p>
</li><li>
<p>Fix a warning message that was displayed incorrectly:<br>
"The actual number of worker threads exceeds the number of threads estimated at startup."<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4282">#4282</a>)</p>
</li><li>
<p>Fix minor memory leak related to tznames<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4334">#4334</a>)</p>
</li></ul>
<h2>Packaging</h2>
<ul><li><code>dbparser</code>: libdbparser.so has been renamed to libcorrelation.so.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4294">#4294</a>)</li><li><code>systemd-journal</code>: Fixed a linker error, which occurred, when building with <code>--with-systemd-journal=optional</code>.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4304">#4304</a>)<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4302">#4302</a>)</li></ul>
<h2>Notes to developers</h2>
<ul><li><code>LogThreadedSourceDriver</code> and <code>Fetcher</code>: implement source-side batching<br>
support on the input path by assigning a thread_id to dynamically spawned<br>
input threads (e.g. those spawned by LogThreadedSourceDriver) too.  To<br>
actually improve performance the source driver should disable automatic<br>
closing of batches by setting <code>auto_close_batches</code> to FALSE and calling<br>
log_threaded_source_close_batch() explicitly.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/3969">#3969</a>)</li></ul>
<h2>Other changes</h2>
<ul><li>
<p>stats related options: The stats related options have been groupped to a new <code>stats()</code> block.</p>
<p>This affects the following global options:</p>
<ul><li><code>stats-freq()</code></li><li><code>stats-level()</code></li><li><code>stats-lifetime()</code></li><li><code>stats-max-dynamics()</code></li></ul>
<p>These options have been kept for backward compatibility, but they have been deprecated.</p>
<p>Migrating from the old stats options to the new ones looks like this.</p>
<div class="gmail-snippet-clipboard-content gmail-notranslate gmail-position-relative gmail-overflow-auto"><pre class="gmail-notranslate"><code>@version: 4.0

options {
    stats-freq(1);
    stats-level(1);
    stats-lifetime(1000);
    stats-max-dynamics(10000);
};
</code></pre></div>
<div class="gmail-snippet-clipboard-content gmail-notranslate gmail-position-relative gmail-overflow-auto"><pre class="gmail-notranslate"><code>@version: 4.1

options {
    stats(
        freq(1)
        level(1)
        lifetime(1000)
        max-dynamics(10000)
    );
};
</code></pre></div>
<p><strong>Breaking change</strong><br>
For more than a decade <code>stats()</code> was a deprecated alias to <code>stats-freq()</code>, now it is used as the name<br>
of the new block. If you have been using <code>stats(xy)</code>, use <code>stats(freq(xy))</code> instead.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4337">#4337</a>)</p>
</li><li>
<p><code>kubernetes</code> source: Improved error logging, when the pod was unreachable through the python API.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4305">#4305</a>)</p>
</li><li>
<p>APT repository: Added .gz, .xz and .bz2 compression to the Packages file.<br>
(<a href="https://github.com/syslog-ng/syslog-ng/pull/4313">#4313</a>)</p>
</li></ul>
<h2>Credits</h2>
<p>syslog-ng is developed as a community project, and as such it relies<br>
on volunteers, to do the work necessarily to produce syslog-ng.</p>
<p>Reporting bugs, testing changes, writing code or simply providing<br>
feedback are all important contributions, so please if you are a user<br>
of syslog-ng, contribute.</p>
<p>We would like to thank the following people for their contribution:</p>
<p>Attila Szakacs, Balazs Scheidler, Bálint Horváth, Gergo Ferenc Kovacs,<br>
Hofi, László Várady, Ronny Meeus, Szilard Parrag</p></div></div></div>