| #!/usr/bin/env bash | |
| # Licensed to the Apache Software Foundation (ASF) under one | |
| # or more contributor license agreements. See the NOTICE file | |
| # distributed with this work for additional information | |
| # regarding copyright ownership. The ASF licenses this file | |
| # to you under the Apache License, Version 2.0 (the | |
| # "License"); you may not use this file except in compliance | |
| # with the License. You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, | |
| # software distributed under the License is distributed on an | |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| # KIND, either express or implied. See the License for the | |
| # specific language governing permissions and limitations | |
| # under the License. | |
| set -euo pipefail | |
| readonly DIRECTORY="${AIRFLOW_HOME:-/usr/local/airflow}" | |
| readonly RETENTION_DAYS="${AIRFLOW__LOG_RETENTION_DAYS:-15}" | |
| readonly RETENTION_MINUTES="${AIRFLOW__LOG_RETENTION_MINUTES:-0}" | |
| readonly FREQUENCY="${AIRFLOW__LOG_CLEANUP_FREQUENCY_MINUTES:-15}" | |
| readonly MAX_PERCENT="${AIRFLOW__LOG_MAX_SIZE_PERCENT:-0}" | |
| trap "exit" INT TERM | |
| MAX_SIZE_BYTES="${AIRFLOW__LOG_MAX_SIZE_BYTES:-0}" | |
| if [[ "$MAX_SIZE_BYTES" -eq 0 && "$MAX_PERCENT" -gt 0 ]]; then | |
| total_space=$(df -k "${DIRECTORY}"/logs 2>/dev/null | tail -1 | awk '{print $2}' || echo "0") | |
| MAX_SIZE_BYTES=$(( total_space * 1024 * MAX_PERCENT / 100 )) | |
| echo "Computed MAX_SIZE_BYTES from ${MAX_PERCENT}% of disk: ${MAX_SIZE_BYTES} bytes" | |
| fi | |
| readonly MAX_SIZE_BYTES | |
| readonly EVERY=$((FREQUENCY*60)) | |
| echo "Cleaning logs every $EVERY seconds" | |
| if [[ "$MAX_SIZE_BYTES" -gt 0 ]]; then | |
| echo "Max log size limit: $MAX_SIZE_BYTES bytes" | |
| fi | |
| retention_days="${RETENTION_DAYS}" | |
| while true; do | |
| total_retention_minutes=$(( (retention_days * 1440) + RETENTION_MINUTES )) | |
| echo "Trimming airflow logs older than ${total_retention_minutes} minutes." | |
| find "${DIRECTORY}"/logs \ | |
| -type d -name 'lost+found' -prune -o \ | |
| -type f -mmin +"${total_retention_minutes}" -name '*.log' -print0 | \ | |
| xargs -0 rm -f || true | |
| if [[ "$MAX_SIZE_BYTES" -gt 0 && "$retention_days" -ge 0 ]]; then | |
| current_size=$(df -k "${DIRECTORY}"/logs 2>/dev/null | tail -1 | awk '{print $3}' || echo "0") | |
| current_size=$(( current_size * 1024 )) | |
| if [[ "$current_size" -gt "$MAX_SIZE_BYTES" ]]; then | |
| retention_days=$((retention_days - 1)) | |
| echo "Size ($current_size bytes) exceeds limit ($MAX_SIZE_BYTES bytes). Reducing retention to ${retention_days} days." | |
| continue | |
| fi | |
| fi | |
| find "${DIRECTORY}"/logs -type d -empty -delete || true | |
| retention_days="${RETENTION_DAYS}" | |
| seconds=$(( $(date -u +%s) % EVERY)) | |
| (( seconds < 1 )) || sleep $((EVERY - seconds - 1)) | |
| sleep 1 | |
| done |