Logging to Systemd with Artifactory
By default, Artifactory sends it's log messages to
$ARTIFACTORY_HOME/logs/artifactory.log. This is fine, but it's handy to also send the log files to the system log. This is expecially true if you use a modern linux that runs systemd, as systemd provides the journalctl utility to display and filter logs.
Jfrog has this page about logging to syslog, and the information there is generally correct. However, it's not complete. The following is my complete guide to sending artifactory logs to syslog.
Artifactory uses the java logging tool logback, which supports sending logs to syslog. That should work fine, but there's one annoying catch: logback does not support unix sockets. It only supports udp sockets. That means you have to have some sort of network listener set up to receive syslog messages, even when your syslog is on the same server.
Fortunately, you can use socat as a minimal listener and forwarder. You actually could use netcat, but socat is better for some reason (I think maybe because it can accept multiple incoming streams?)
Create Systemd configuration
I found some excellent info about how to both set up the listener and do some post-processing to clean up the logs. That example covers more ground than I cared about, so I took the basic idea and ran with it.
Create the file
[Unit] Before=artifactory.service Description=localhost syslog relay [Service] ExecStart=/bin/sh -c 'socat -u UDP-RECV:514,range=127.0.0.1/32 STDOUT | /usr/local/bin/syslog-formatter.sh' Restart=on-success User=root
Note that this is sort of secure because of the
range restriction to only accept connections from localhost. However, for real security you should also make sure the firewall on your server is blocking UDP port 514 from outside connections too.
Note also that the ExecStart is wrapped in
/bin/sh. That's because although ExecStart lines look like they are invoked with the shell, they aren't. They are more like a bare
execve call, which just execs the first argument and then feeds the following arguments to the resulting process. That means for example that you can't use shell pipes in ExecStart.
/usr/local/bin/syslog-formatter.sh as follows:
#!/usr/bin/env bash # Pretty up the logback output by removing the date, time, etc. and # then send it to systemd. Otherwise a lot of info is duplicated. sed -u -e "s/^ *<.* \[/[/" | systemd-cat -t artifactory
don't forget to chmod that file to 755 and make sure it's owned by root.
It's nice to use systemd-cat because you can supply the log name via the
-t switch, which makes your logs more readable.
Now you can fire up the listener with
systemctl start syslogRelay.service. Test the listener by sending some udp data to port 514:
echo "hi there" | nc -u localhost 514
(you have to hit ctrl-c to exit that command)
journalctl -u artifactory as root to see if the message made it in to the log. If it didn't work, check journalctl for error messages, and run
systemctl status syslogRelay to see why the syslogRelay service isn't running.
Now we are in the home stretch. We've got a working listener on the box, so all we need to do now is modify the artifactory configuration. Open up the file
$ARTIFACTORY_HOME/etc/logback.xml and add an additional appender in the
configuration section. It should look like this:
<appender name="SYSLOG" class="ch.qos.logback.classic.net.SyslogAppender"> <syslogHost>localhost</syslogHost> <facility>SYSLOG</facility> <suffixPattern>[%thread] %logger %msg\n</suffixPattern> </appender>
\n at the end of the log line! If you don't add that, some artifactory log messages will spew out in super long lines and be impossible to read.
Finally, in the
root section, tell logback to actually use your new appender:
That's it! Logback will automatically re-read it's configuration file and start sending logs to systemd. Don't worry, it will still send the logs to the standard
artifactory.log file as well (as long as you don't remove that appender from
You can also issue a
systemctl restart artifactory if you want to immedieately generate some artifactory log output.
Well, that's about all there is to putting artifactory logs in to systemd. It's annoying that logback's lack of support for unix sockets forces you to run a mini syslog server, but it does work. I hope some of you find this helpful.