How to specify the log file for memcached on RHEL / CentOS
I'm running memcached 1.4.5 on RHEL5.5. I installed this using yum which has installed the standard memcached script in /etc/init.d
and the configuration file in /etc/sysconfig/memcached
:
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="256"
OPTIONS=""
Everything is working fine with one exception - I can't figure out how to specify the log file location. I'd like to put the log file in /var/log
but the help nor the manual specify how to do this.
Is it possible to achieve this using the base scripts?
Solution 1:
Modify the OPTIONS line in /etc/sysconfig/memcached
adding ">> /var/log/memcached 2>&1"
on the end. IE
OPTIONS="-vv >> /var/log/memcached 2>&1"
Solution 2:
Using 2>&1 >> logfile
in the OPTIONS or init script is not wise, as the log file will not get reopened when log rotation occurs, assuming of course that you have put something in place for that to occur. The implication of this is that you'll end up with rotated log files (empty, depending on rotation settings) and your actual log data will be written to a file for which no directory entry actually exists, which means that it will get deleted when the file is closed. For the logfile to be closed when intended, and therefore safely rotated, you would have to restart memcached (goodbye cache!).
Instead, use something like the logger(1) command to log to syslog (with a particular facility such as local1, and have your syslog rules route it appropriately (hello timestamps!),
OPTIONS=" 2>&1 | logger -i -p local1.info -t memcached"
A rule to route the messages specially in syslog is optional, but if you're using rsyslog, then this would help:
local1.debug /var/log/memcached/memcached.log
Don't forget a logrotate rule, and because you're using logger, you don't need to worry about closing any log files, because syslog will do that for you.
# cat /etc/logrotate.d/memcached
/var/log/memcached/memcached.log {
daily
rotate 3
dateext
missingok
create 0640 root root
compress
delaycompress
postrotate
#/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
/bin/kill -HUP `cat /var/run/syslogd.pid`
endscript
}
FWIW, the situtation is different for EL7 (systemd) systems
For systemd systems, it will take care of collecting the output of stderr and logging that, so if you just include -v
(still very quiet) or -vv
(too verbose), then you can query those logs with journalctl:
# journalctl --since '2012-01-01' _SYSTEMD_UNIT=memcached.service
-- Logs begin at Fri 2015-07-10 11:00:21 NZST, end at Mon 2015-08-03 23:36:49 NZST. --
Aug 03 23:36:49 HOSTNAME memcached[4318]: slab class 17: chunk size 3632 perslab 288
Aug 03 23:36:49 HOSTNAME memcached[4318]: slab class 18: chunk size 4544 perslab 230
...
Aug 03 23:36:49 HOSTNAME memcached[4318]: slab class 42: chunk size 1048576 perslab 1
Aug 03 23:36:49 HOSTNAME memcached[4318]: <26 server listening (auto-negotiate)
Aug 03 23:36:49 HOSTNAME memcached[4318]: <27 send buffer was 212992, now 268435456
Aug 03 23:36:49 HOSTNAME memcached[4318]: <27 server listening (udp)
Aug 03 23:36:49 HOSTNAME memcached[4318]: <27 server listening (udp)
Aug 03 23:36:49 HOSTNAME memcached[4318]: <27 server listening (udp)
Aug 03 23:36:49 HOSTNAME memcached[4318]: <27 server listening (udp)
Although you don't find these logs existing anywhere under /var/log/; the logs are held in a binary format so you can use journalctl --output json ...
if you wanted. See /etc/systemd/journald.conf for more information.
From beginning to end (albeit for RHEL7 / systemd servers)
# cat /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 127.0.0.1 -vv"
# cat /usr/lib/systemd/system/memcached.service
[Unit]
Description=Memcached
Before=httpd.service
After=network.target
[Service]
Type=simple
EnvironmentFile=-/etc/sysconfig/memcached
ExecStart=/usr/bin/memcached -u $USER -p $PORT -m $CACHESIZE -c $MAXCONN $OPTIONS
[Install]
WantedBy=multi-user.target
# cat /etc/systemd/system/memcached.service.d/local.conf
[Service]
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=memcached
SyslogFacility=local1
SyslogLevel=debug
SyslogLevelPrefix=false
# systemctl daemon-reload
# systemctl restart memcached.service
# systemctl status memcached
memcached.service - Memcached
Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled)
Drop-In: /etc/systemd/system/memcached.service.d
└─local.conf <---------- NOTE
Active: active (running) since Tue 2015-08-04 01:07:50 NZST; 7s ago
Main PID: 3842 (memcached)
CGroup: /system.slice/memcached.service
└─3842 /usr/bin/memcached -u memcached -p 11211 -m 64 -c 1024 -l 127.0.0.1 -vv
...
// Note: rsyslogd uses its imjournal module to read logs from journald;
// make sure you have this configured if you've brought your rsyslog
// config from a previous version of RHEL
# echo "local1.debug /var/log/memcached/memcached.log" >> /etc/rsyslog.d/memcached.conf
# mkdir /var/log/memcached
# systemctl restart rsyslog.service
# systemctl status rsyslog.service
// Don't forget log rotation
# cat /etc/logrotate.d/memcached
/var/log/memcached/memcached.log {
daily
rotate 3
dateext
missingok
create 0640 root root
compress
delaycompress
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
Solution 3:
Memcached doesn't provide a commandline option for log file location. On Ubuntu, there's a wrapper script called start-memcached which parses an /etc/memcached.conf which contains a logfile parameter. Unfortunately, this doesn't seem to exist on CentOS/RHEL. I think you'd have to modify the init script to accomplish what you want. It does seem to be a bit of an oversight - a quick googling shows that other people have this problem too, so maybe its something they'll fix soon (or have fixed already and I'm not aware of). Or you could try the startup scripts from Ubuntu.