Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Logrotate] Add log rotate configuration #15116

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
12 changes: 12 additions & 0 deletions files/build_templates/init_cfg.json.j2
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@
"logout": ""
}
},
"LOGGING": {
"debug": {
"frequency": "daily",
"max_number": 20,
"size": 10
},
"syslog": {
"frequency": "daily",
"max_number": 10,
"size": 16
}
},
"SYSTEM_DEFAULTS" : {
{%- if include_mux == "y" %}
"mux_tunnel_egress_acl": {
Expand Down
2 changes: 1 addition & 1 deletion files/build_templates/sonic_debian_extension.j2
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ echo "system-health.service" | sudo tee -a $GENERATED_SERVICE_FILE

# Copy logrotate.d configuration files
sudo cp -f $IMAGE_CONFIGS/logrotate/logrotate.d/* $FILESYSTEM_ROOT/etc/logrotate.d/
sudo cp $IMAGE_CONFIGS/logrotate/rsyslog.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/
sudo cp -f $IMAGE_CONFIGS/logrotate/templates/* $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/
sudo cp $IMAGE_CONFIGS/logrotate/logrotate-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM
sudo cp $IMAGE_CONFIGS/logrotate/logrotate-config.sh $FILESYSTEM_ROOT/usr/bin/
sudo mkdir -p $FILESYSTEM_ROOT/etc/systemd/system/logrotate.timer.d
Expand Down
46 changes: 45 additions & 1 deletion files/image_config/logrotate/logrotate-config.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,48 @@
#!/bin/bash

sonic-cfggen -d -t /usr/share/sonic/templates/rsyslog.j2 -a "{\"var_log_kb\":$(df -k /var/log | sed -n 2p | awk '{ print $2 }') }" > /etc/logrotate.d/rsyslog
VAR_LOG_SIZE=$(df -k /var/log | sed -n 2p | awk '{ print $2 }')

# Adjust NUM_LOGS_TO_ROTATE to reflect number of common log files (auth, cron,
# teamd, telemetry, etc.) to rotate.
NUM_LOGS_TO_ROTATE=8

# Detect common log files (auth, cron, teamd, telemetry, etc.) size. 720M is
# required to hold extra space to rotate all files (16M each) two times.
if [[ "$VAR_LOG_SIZE" < "204800" ]]; then
LOG_FILE_ROTATE_SIZE_MB=1
elif [[ "$VAR_LOG_SIZE" < "409600" ]]; then
LOG_FILE_ROTATE_SIZE_MB=2
else
LOG_FILE_ROTATE_SIZE_MB=16
fi

# Reserve space for btmp, wtmp, dpkg.log, monit.log, etc., as well as logs that
# should be disabled, just in case they get created and rotated
RESERVED_SPACE_KB=4096

# Limit usable space to 90 to define percentage of the partition minus the
# reserved space for other logs
USABLE_SPACE_KB=$(((VAR_LOG_SIZE * 90 / 100) - RESERVED_SPACE_KB))

# Set our threshold so as to maintain enough space to write all logs from empty
# to full. Most likely, some logs will have non-zero size when this is called,
# so this errs on the side of caution, giving us a bit of a cushion if a log
# grows quickly and passes its rotation size. USABLE_SPACE_KB should be at least
# twice as big as THRESHOLD_KB value.
THRESHOLD_KB=$((USABLE_SPACE_KB - \
(LOG_FILE_ROTATE_SIZE_MB * 1024 * 2 * NUM_LOGS_TO_ROTATE)))
fastiuk marked this conversation as resolved.
Show resolved Hide resolved

# Append data to template
APPEND_DATA="{\"max_logs_size_kb\":$THRESHOLD_KB,
\"common_file_size_mb\":\"$LOG_FILE_ROTATE_SIZE_MB\"}"

# Generic log files
sonic-cfggen -d -t /usr/share/sonic/templates/logrotate-common.j2 \
-a "$APPEND_DATA" > /etc/logrotate.d/rsyslog

# Specific log files
sonic-cfggen -d -t /usr/share/sonic/templates/logrotate-debug.j2 \
-a "$APPEND_DATA" > /etc/logrotate.d/debug

sonic-cfggen -d -t /usr/share/sonic/templates/logrotate-syslog.j2 \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was not required previously. Why is this required now. Isn't rsyslog enough?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rsyslog was split into common and per-logfile config.
And the reason why it was done like that, because once config file will be generated, you can use to rotate corresponding log file manually, and not all files together.

-a "$APPEND_DATA" > /etc/logrotate.d/syslog
Original file line number Diff line number Diff line change
@@ -1,3 +1,44 @@
{% macro postrotate_action() -%}
if [ -f /var/run/rsyslogd.pid ]; then
/bin/kill -HUP $(cat /var/run/rsyslogd.pid)
fi
{%- endmacro -%}

{% macro postrotate() -%}
postrotate
{{ postrotate_action() }}
endscript
{%- endmacro -%}

{% macro disk_percentage_treshold_rotation() -%}
firstaction
# Add threshold
THRESHOLD_KB={{ max_logs_size_kb }}

# First, delete any *.1.gz files that might be left around from a prior incomplete
# logrotate execution, otherwise logrotate will fail to do its job
find /var/log/ -name '*.1.gz' -type f -exec rm -f {} +

while true; do
USED_KB=$(du -s /var/log | awk '{ print $1; }')

if [ $USED_KB -lt $THRESHOLD_KB ]; then
break
else
OLDEST_ARCHIVE_FILE=$(find /var/log -type f -printf '%T+ %p\n' | grep -E '.+\.[0-9]+(\.gz)?$' | sort | awk 'NR == 1 {print $2}')

if [ -z "$OLDEST_ARCHIVE_FILE" ]; then
logger -p syslog.err -t "logrotate" "No archive file to delete -- potential for filling up /var/log partition!"
break
fi

logger -p syslog.info -t "logrotate" "Deleting archive file $OLDEST_ARCHIVE_FILE to free up space"
rm -rf "$OLDEST_ARCHIVE_FILE"
fi
done
endscript
{%- endmacro -%}

# These logs should no longer get created. However, in case they do get created,
# we should keep them to a small size and rotate them also.
/var/log/mail.info
Expand All @@ -8,7 +49,6 @@
/var/log/kern.log
/var/log/user.log
/var/log/lpr.log
/var/log/debug
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of differentiating debug message alone through separate configuration?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use the debug file separately, so we need to have a separation. By default that file has the same configuration as it had before.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion we need separate file only if debugs are much more and require special attention. I don't think that's the case in sonic as we have all debug logs as part of syslog itself and I am not sure if debug file is used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't want to rotate it, you just don't configure it. For the rest of people who want to use debug file and rotate they can configure it in the DB and rotate.

/var/log/messages
{
size 10k
Expand All @@ -18,16 +58,11 @@
compress
delaycompress
sharedscripts
postrotate
if [ -f /var/run/rsyslogd.pid ]; then
/bin/kill -HUP $(cat /var/run/rsyslogd.pid)
fi
endscript
{{ postrotate() }}
}

/var/log/auth.log
/var/log/cron.log
/var/log/syslog
/var/log/teamd.log
/var/log/telemetry.log
/var/log/gnmi.log
Expand All @@ -37,68 +72,14 @@
/var/log/swss/swss*.rec
/var/log/swss/responsepublisher.rec
{
{% if var_log_kb <= 204800 %}
size 1M
{% elif var_log_kb <= 409600 %}
size 2M
{% else %}
size 16M
{% endif %}
size {{ ((common_file_size_mb | float) * 1024 * 1024) | int }}
rotate 5000
missingok
notifempty
compress
delaycompress
nosharedscripts
firstaction
# Adjust NUM_LOGS_TO_ROTATE to reflect number of log files that trigger this block specified above
NUM_LOGS_TO_ROTATE=8

# Adjust LOG_FILE_ROTATE_SIZE_KB to reflect the "size" parameter specified above, in kB
{% if var_log_kb <= 204800 %}
LOG_FILE_ROTATE_SIZE_KB=1024
{% elif var_log_kb <= 409600 %}
LOG_FILE_ROTATE_SIZE_KB=2048
{% else %}
LOG_FILE_ROTATE_SIZE_KB=16384
{% endif %}

# Reserve space for btmp, wtmp, dpkg.log, monit.log, etc., as well as logs that
# should be disabled, just in case they get created and rotated
RESERVED_SPACE_KB=4096

VAR_LOG_SIZE_KB={{var_log_kb}}

# Limit usable space to 90% of the partition minus the reserved space for other logs
USABLE_SPACE_KB=$(( (VAR_LOG_SIZE_KB * 90 / 100) - RESERVED_SPACE_KB))

# Set our threshold so as to maintain enough space to write all logs from empty to full
# Most likely, some logs will have non-zero size when this is called, so this errs on the side
# of caution, giving us a bit of a cushion if a log grows quickly and passes its rotation size
THRESHOLD_KB=$((USABLE_SPACE_KB - (NUM_LOGS_TO_ROTATE * LOG_FILE_ROTATE_SIZE_KB * 2)))

# First, delete any *.1.gz files that might be left around from a prior incomplete
# logrotate execution, otherwise logrotate will fail to do its job
find /var/log/ -name '*.1.gz' -type f -exec rm -f {} +

while true; do
USED_KB=$(du -s /var/log | awk '{ print $1; }')

if [ $USED_KB -lt $THRESHOLD_KB ]; then
break
else
OLDEST_ARCHIVE_FILE=$(find /var/log -type f -printf '%T+ %p\n' | grep -E '.+\.[0-9]+(\.gz)?$' | sort | awk 'NR == 1 {print $2}')

if [ -z "$OLDEST_ARCHIVE_FILE" ]; then
logger -p syslog.err -t "logrotate" "No archive file to delete -- potential for filling up /var/log partition!"
break
fi

logger -p syslog.info -t "logrotate" "Deleting archive file $OLDEST_ARCHIVE_FILE to free up space"
rm -rf "$OLDEST_ARCHIVE_FILE"
fi
done
endscript
{{ disk_percentage_treshold_rotation() }}
postrotate
if [ $(echo $1 | grep -c "/var/log/swss/") -gt 0 ]; then
# for multi asic platforms, there are multiple orchagents
Expand All @@ -118,9 +99,7 @@
pgrep -x orchagent | xargs /bin/kill -HUP 2>/dev/null || true
fi
else
if [ -f /var/run/rsyslogd.pid ]; then
/bin/kill -HUP $(cat /var/run/rsyslogd.pid)
fi
{{ postrotate_action() }}
fi
endscript
}
28 changes: 28 additions & 0 deletions files/image_config/logrotate/templates/logrotate-debug.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{% from "logrotate-common.j2" import postrotate with context %}
{% from "logrotate-common.j2"
import disk_percentage_treshold_rotation with context -%}

{% set debug = (LOGGING | d({})).get('debug', {}) -%}
{% set frequency = debug.frequency | d('daily') -%}
{% set max_number = debug.max_number | d(1) -%}

{% if debug.disk_percentage and not debug.size -%}
{% set size_mb = (max_logs_size_kb | int) *
(debug.disk_percentage | float) / 100 / 1024 -%}
{% else -%}
{% set size_mb = (debug.size | d(0.001)) | float -%}
{%- endif %}
{% set size = (size_mb * 1024 * 1024) | int %}
/var/log/debug
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this log file is used at all on SONiC?

{
{{ frequency }}
size {{ size }}
rotate {{ max_number }}
missingok
notifempty
compress
delaycompress
nosharedscripts
{{ disk_percentage_treshold_rotation() }}
{{ postrotate() }}
}
28 changes: 28 additions & 0 deletions files/image_config/logrotate/templates/logrotate-syslog.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{% from "logrotate-common.j2" import postrotate with context %}
{% from "logrotate-common.j2"
import disk_percentage_treshold_rotation with context -%}

{% set syslog = (LOGGING | d({})).get('syslog', {}) -%}
{% set frequency = syslog.frequency | d('daily') -%}
{% set max_number = syslog.max_number | d(5000) -%}

{% if syslog.disk_percentage and not syslog.size -%}
fastiuk marked this conversation as resolved.
Show resolved Hide resolved
{% set size_mb = (max_logs_size_kb | int) *
(syslog.disk_percentage | float) / 100 / 1024 -%}
{% else -%}
{% set size_mb = (syslog.size | d(common_file_size_mb)) | float -%}
{%- endif %}
{% set size = (size_mb * 1024 * 1024) | int -%}
/var/log/syslog
{
{{ frequency }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify what does this frequency control? The frequency of logrotate itself is being controlled by timer. Why is frequency needed here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size {{ size }}
rotate {{ max_number }}
missingok
notifempty
compress
delaycompress
nosharedscripts
{{ disk_percentage_treshold_rotation() }}
{{ postrotate() }}
}
2 changes: 2 additions & 0 deletions src/sonic-yang-models/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ def run(self):
'./yang-models/sonic-interface.yang',
'./yang-models/sonic-kdump.yang',
'./yang-models/sonic-kubernetes_master.yang',
'./yang-models/sonic-logging.yang',
'./yang-models/sonic-loopback-interface.yang',
'./yang-models/sonic-lossless-traffic-pattern.yang',
'./yang-models/sonic-mgmt_interface.yang',
Expand Down Expand Up @@ -240,6 +241,7 @@ def run(self):
'./cvlyang-models/sonic-interface.yang',
'./cvlyang-models/sonic-kdump.yang',
'./cvlyang-models/sonic-kubernetes_master.yang',
'./cvlyang-models/sonic-logging.yang',
'./cvlyang-models/sonic-loopback-interface.yang',
'./cvlyang-models/sonic-mgmt_interface.yang',
'./cvlyang-models/sonic-mgmt_port.yang',
Expand Down
8 changes: 8 additions & 0 deletions src/sonic-yang-models/tests/files/sample_config_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -2775,6 +2775,14 @@
"grpc_ssl_credential": "azureclient.ms"
}
},
"LOGGING": {
"debug": {
"disk_percentage": "46.0",
"frequency": "daily",
"max_number": "100",
"size": "20.0"
}
},
"BANNER_MESSAGE": {
"global": {
"state": "enabled",
Expand Down
53 changes: 53 additions & 0 deletions src/sonic-yang-models/tests/yang_model_tests/tests/logging.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"LOGGING_NAME_TEST": {
"desc": "Valid log file name test"
},
"LOGGING_INVALID_NAME_TEST": {
"desc": "Invalid log file name test",
"eStrKey": "Pattern"
},
"LOGGING_DISK_PERCENTAGE_TEST": {
"desc": "Valid disk percentage test"
},
"LOGGING_INVALID_DISK_PERCENTAGE_TEST": {
"desc": "Invalid disk percentage test",
"eStrKey": "Range"
},
"LOGGING_INVALID_DISK_PERCENTAGE_TEST_2": {
"desc": "Invalid disk percentage test 2",
"eStrKey": "Range"
},
"LOGGING_FREQUENCY_TEST": {
"desc": "Valid rotation frequency test"
},
"LOGGING_INVALID_FREQUENCY_TEST": {
"desc": "Invalid rotation frequency test",
"eStrKey": "Pattern"
},
"LOGGING_INVALID_FREQUENCY_TEST_2": {
"desc": "Invalid rotation frequency test 2",
"eStrKey": "Pattern"
},
"LOGGING_MAX_NUMBER_TEST": {
"desc": "Valid rotation max number test"
},
"LOGGING_INVALID_MAX_NUMBER_TEST": {
"desc": "Invalid rotation max number test",
"eStrKey": "Range"
},
"LOGGING_INVALID_MAX_NUMBER_TEST_2": {
"desc": "Invalid rotation max number test 2",
"eStrKey": "Range"
},
"LOGGING_SIZE_TEST": {
"desc": "Rotation file size test"
},
"LOGGING_INVALID_SIZE_TEST": {
"desc": "Invalid rotation file size test",
"eStrKey": "Range"
},
"LOGGING_INVALID_SIZE_TEST_2": {
"desc": "Invalid rotation file size test 2",
"eStrKey": "Range"
}
}
Loading
Loading