I have a setup which can be summarized as follow:
service --> syslog-ng relay --> syslog-ng server
On the syslog-ng
server, I would have the log organized as follow:
/var/log/ ----> syslog-ng server local log files...
\--> ${FROM_HOST}/
\---> Syslog-ng relay host log files...
\---> ${HOST}/
\---> Service log files...
- Logs generated locally on the
syslog-ng
server located in their default location, /var/log. - Logs generated on a relay in a subdirectory bearing the relay name, /var/log/${FROM_HOST}.
- Logs generated by a service in a subdirectory of its associated relay, /var/log/${FROM_HOST}/${HOST}
I created the following configuration on the syslog-ng
server host:
@version: 3.7
@include "scl.conf"
options {
dns-cache-hosts("/etc/hosts");
keep-hostname(yes);
use-dns(persist_only);
};
...(removed)...
# syslog-ng server local logs, works fine.
log {
source(local_src);
local_file();
};
# syslog-ng relays, never matches.
log {
source(remote_src);
filter { host("${HOST_FROM}", type(string)); };
local_file(subdir("${HOST_FROM}/"));
};
# Services, works fine but also matches syslog-ng relays.
log {
source(remote_src);
filter { not host("${HOST_FROM}", type(string)); };
local_file(subdir("${HOST_FROM}/$(sanitize $HOST)/"));
};
For information local_file()
is a custom log block taking as parameter the subdirectory where to store logs entries.
The host()
filter is described as comparing its parameter with ${HOST}. My idea was there to use this to check ${HOST} (the author of the syslog message) and ${HOST_FROM} (the last hop of the syslog message):
- If they are equal, the message has been generated by the
syslog-ng
relay. - If they are different, the message has been generated by a service.
However, the test host("${HOST_FROM}", type(string))
always fails, even though the generated path does not show any difference between the values of ${HOST} and ${HOST_FROM} (for instance, given a relay named therelay, relays logs will be stored below /var/log/therelay/therelay/ (expansion of /var/log/${HOST_FROM}/$(sanitize $HOST)/).
I tried to remove sanitization, to interpret the pattern as a regexp instead of a raw string, add .*
at the beginning and the end of the pattern while a regexp, remade all these tests while replacing host("${HOST_FROM}")
by match("${HOST_FROM}", value(HOST))
, but nothing seems to work.
Actually, even host("${HOST}")
(comparing ${HOST} with itself) seems to never match.
Replacing the filter with filter { host(".*"); };
however correctly forces this entry to match.
Is this the expected behavior? How can I compare the content of ${HOST} and ${HOST_FROM}?