Moving Home Assistant LogsStop eating my SD card
“Read only file system” “No disk available” Most of us have been there at some time or another. Impatience or ignorance of knowing not shutting down a Raspberry Pi properly can chew up a SD card. Another lesser known issue is that SD cards have a limited lifespan; they only get a certain number of write cycles before they stop working. It’s like that Eddie Murphy movie where he’s only got a limited number of words he can say and they’re counted by leaves on a tree.
Because of this write-intensive stuff like logs and databases a card can get worn out far before it should due to excessive writes. There’s hope! You can use a USB drive and redirect all of this write-heavy activity there and your SD card will be safe.
First you need to figure out where Linux thinks the USB drive lives; in my case it was /dev/sda. Plug your drive into your Pi and then run the following command: (Thanks to Tinkerer for the better than ‘figure it out’ solution)
sudo dmesg|tail -n 20|grep sd
You’ll get output that will look something like:
[ 3.773637] sd 0:0:0:0: [sda] 62333952 512-byte logical blocks: (31.9 GB/29.7 GiB) [ 3.783125] sd 0:0:0:0: [sda] Write Protect is off [ 3.791694] sd 0:0:0:0: [sda] Mode Sense: 0b 00 00 08 [ 3.792618] sd 0:0:0:0: [sda] No Caching mode page found [ 3.801020] sd 0:0:0:0: [sda] Assuming drive cache: write through [ 3.817186] sda: sda1 sda2
Next you’ll create a mount point somewhere on the file system that you’ll use to mount the USB disk.
sudo mkdir /mnt/usb-disk
Now you’ll use the mount commad to mount the usb disk to the directory
sudo mount /dev/sda /mnt/usb-disk
We’ll want to make this permanent so we’ll have to add an fstab entry for it. First we’ll need to figure out what filesystem type to use. We’ll use fdisk to list out our disks
sudo fdisk -l
Find the part where your drive is and it should look something like this:
Disk /dev/sda: 7.5 GiB, 8053063680 bytes, 15728640 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x6f20736b
If the Disklabel type: says dos it’s FAT32. Otherwise it should spell out what the type is.
sudo vim /etc/fstab
You’ll add a new line in the file replacing my example values with your actual values:
/dev/sda /mnt/usb-disk fat32 auto
The goal here is to move the commonly written stuff to the USB drive to reduce writes to the SD card we’ll move the home-assistant.log and the database to the drive. Shut down home assistant before doing this stuff.
mv /home/homeassistant/.homeassistant/home-assistant.log /mnt/usb-disk/ mv /home/homeassistant/.homeassistant/home-assistant_v2.db /mnt/usb-disk
The files are now on the drive but we have to make sure that home assistant can write to them. We’ll create a symbolic link from the Home Assistant config directory to the USB disk
ln -s /home/homeassistant/.homeassistant/home-assistant.log /mnt/usb-disk/home-assistant.log ln -s /home/homeassistant/.homeassistant/home-assistant_v2.db /mnt/usb-disk/home-assistant_v2.db
Restart home assistant and make sure everything’s working appropriately. If not, check your permissions on the files on your USB drive. They should be owned by the user that you run Home Assistant as.
sudo systemctl restart home-assistant.service
The logging is a bit trickier. We’ll need to modify the systemd unit for home assistant and add a new configuration file for journalctl. The venv install method already makes sure that the log messages from home assistant are tagged with the identifier ‘hass’. You can check your syslog by editing /var/log/syslog and look for home assistant messages. If they’re already tagged at the beginning with something that looks like Oct 20 06:25:28 ubuntu hass: you can skip modifying the system unit. To modify the system unit you just need to edit the file:
sudo vim /etc/systemd/system/home-assistant.service
and add (or modify) the following
This tells it to redirect standard output to the syslog file and to tag the messages with hass.
Make sure to reload the system unit.
sudo systemctl daemon-reload
Now we need to configure journalctl to split those messages out to a different log location. Create a hass config for journalctl:
sudo vim /etc/rsyslog.d/hass.conf
enter the following and save the file
if $programname == 'hass' then /mnt/usb-disk/hass-syslog.log
sudo systemctl restart rsyslog
check to make sure it’s logging appropriately
tail -f /mnt/usb-disk/hass-syslog.log
Everything should be logging and using files on your external drive which should greatly prolong the life of your SD card. Happy automating!