Save logs to a file

Hi guys.
I'm facing strange issues with my router and it becomes unreachable from time to time. So I have to restart it and after there are no OpenWRT logs.
According this article https://openwrt.org/docs/guide-user/base-system/log.essentials
I created 2 lines

   option log_file '/mnt/sda2/logs.log'
   option log_remote '0'

in a /etc/config/system file. Restarted services service log restart && service system restart and now there are logs on my USB drive.
But they exist like a 2 hours and after that, they will be overwritten by a new records.
In my example I'm getting logs.log file with records during last hour. And also there is logs.log.old where I can find one more hour of logs.

Could you please explain, how can I store all logs from router's boot and till current time?

Thanks in advance.

Try:

option log_type file
1 Like

Do you know if that's documented in the wiki? I couldn't find a good reference for the logging options there.

Best I could find was this post Log options in /etc/config/system

1 Like

It's documented here: https://openwrt.org/docs/guide-user/base-system/system_configuration

2 Likes

Aah, thanks, that's pretty solid.

We really need to figure out how to get the wiki search fixed. It almost never gives up anything other than a billion ToH entries which are rarely useful, so I fall back on external searches and those are often hit'n'miss.

2 Likes

I doubt you will find anything useful for the problem more than two hours back anyway.

You can use the option log_type, but that will only do a file sooner or later with one trillion lines and then the USB flash is full.

The option to use is log_size and set it to about 1000 to 2000, that will give you with the rotation 1-2month of circulating logs.

1 Like

Thank you, guys for helping me. Now my logging is configured as

        option log_file '/mnt/sda1/logs/syslog.log'
        option log_size '1024'
        option log_remote '0'
        option log_type 'file'

So I'll wait a couple of days and take a look how many days will fit in a log_size '1024'. After I'll get back here.

If log_type is file, as mentioned in the wiki, the file will grow without an upper boundary, as in, it will just keep appending new lines to the end of the file. log_size is therefore, ignored.

1 Like

For now it looks like that
-rw------- 1 root root 443.3K Oct 9 12:08 syslog.log
-rw------- 1 root root 1.0M Oct 8 15:00 syslog.log.old

syslog.log.old stores logs from Sun Oct 6 21:54:27 till Tue Oct 8 15:00:00
syslog.log stores logs from Tue Oct 8 15:02:00 till Wed Oct 9 11:06:00
So I have logs for almost 3 days. And that was my goal.

At the same time, OpenWRT interface Status - Logs gives me all records from
Mon Oct 7 18:59:10 till Wed Oct 9 11:06:00

I hope, that when syslog.log will reach 1M size, an old one syslog.log.old will be overwritten. But let's wait a couple of days. I'll get back and will update that topic.

So, it's not ignoring the value from log_size? The wiki makes no mention of logd renaming the log files at certain boundaries. Or maybe log_size is causing the log_type option to be ignored. I'll have to check the code later.

Yep, log_size works. For now there are 2 files
-rw------- 1 root root 628.2K Oct 9 16:01 syslog.log
-rw------- 1 root root 1.0M Oct 8 15:00 syslog.log.old
so it was my goal.

Thanks to all for helping me. And many-many thanks to @Cthulhu88 and @flygarn12.
I think we can assume that my problem is resolved.

1 Like

The wiki is wrong/outdated; log_type isn't even used:

start_service_file()
{
        PIDCOUNT="$(( ${PIDCOUNT} + 1))"
        local pid_file="/var/run/logread.${PIDCOUNT}.pid"

        [ "$2" = 0 ] || {
                echo "validation failed"
                return 1
        }
        [ -z "${log_file}" ] && return

        [ "$_BOOT" = "1" ] &&
                [ "$(procd_get_mountpoints "${log_file}")" ] && return 0

        mkdir -p "$(dirname "${log_file}")"

        procd_open_instance logfile
        procd_set_param command "$PROG" -f -F "$log_file" -p "$pid_file"
        [ -n "${log_size}" ] && procd_append_param command -S "$log_size"
        procd_close_instance
}

The renaming to *.old happens at logread.c -> log_notify:

if ((log_type == LOG_FILE) && log_size && (!stat(log_file, &s)) && (s.st_size > log_size)) {
      char *old = malloc(strlen(log_file) + 5);

      close(sender.fd);
      if (old) {
              sprintf(old, "%s.old", log_file);
              rename(log_file, old);
              free(old);
      }
      sender.fd = open(log_file, O_CREAT | O_WRONLY | O_APPEND, 0600);
      if (sender.fd < 0) {
              fprintf(stderr, "failed to open %s: %m\n", log_file);
              exit(-1);
      }
}

And yes, it only backs a single .old, the previous one is replaced.

logd: ring buffer in RAM
logread: writes messages stored in the ring buffer to a file

Since they are two different applications, you want to have two different buffer sizes, one for RAM and one for the file (the default behavior is to use log_size for the ring buffer, if log_buffer_size is not defined), so:

option log_buffer_size '64'
option log_size '1024'

This will keep RAM usage to just 64 KB, while renaming your log file to *.old after going over the 1 MB boundary.

1 Like