1

У меня есть структура папок в /var /log, как это:

.
├── customers
│   ├── core00001
│   │   ├── 2016.07.21
│   │   │   ├── apache.log
│   │   │   └── error.log
│   │   └── 2016.07.22
│   │       ├── apache.log
│   │       └── error.log
│   ├── core00002
│   │   ├── 2016.07.21
│   │   │   ├── apache.log
│   │   │   └── error.log
│   │   └── 2016.07.22
│   │       ├── apache.log
│   │       └── error.log
│   ├── dashboard001
│   │   ├── 2016.07.21
│   │   │   ├── dash.log
│   │   │   └── error.log
│   │   └── 2016.07.22
│   │       ├── dash.log
│   │       └── error.log
│   └── dashboard002
│       ├── 2016.07.21
│       │   ├── dash.log
│       │   └── error.log
│       └── 2016.07.22
│           ├── dash.log
│           └── error.log
└── servers
    ├── server01
    │   ├── 2016.07.21
    │   │   ├── access.log
    │   │   └── system.log
    │   └── 2016.07.22
    │       ├── access.log
    │       └── system.log
    └── server02
        ├── 2016.07.21
        │   ├── access.log
        │   └── system.log
        └── 2016.07.22
            ├── access.log
            └── system.log

С этими папками мне нужно сделать какую-то ротацию логов. Это не реальная ротация журналов, но мне нужно архивировать и удалять файлы через определенное количество дней. Я думал о создании файла конфигурации, в котором я могу указать количество дней после того, как файл должен быть заархивирован, и количество дней после того, как файл и пустая папка должны быть удалены.

Ядра и серверы могут увеличиваться, и имена файлов журнала могут быть добавлены с каждым сервером. По этой причине я подумал об использовании файла конфигурации со скриптом bash, чтобы я мог добавить имена здесь.

Моя первая идея файла конфигурации выглядит следующим образом:

Zip;Delete;Main;Sub;App

7;365;/customers;core*;/apache.log
7;365;/customers;core*;/error.log

7;180;/customers;dash*;/dash.log
7;180;/customers;dash*;/error.log

28;365;/servers;server*;/access.log
14;365;/servers;server*;/error.log

Моя проблема заключается в том, что я не знаю, как это сделать без посторонней помощи.

Я уже пытался создать цикл, в котором будет читаться файл конфигурации, но тогда будет прочитана только 1 строка, и скрипт остановится.

#!/bin/bash
configfile="/etc/customlogrotate/logrotation.conf"
logbasefolder="/var/log"

echo " " > log.txt
echo " " >> log.txt
echo "Starting logrotation script" >> log.txt

while IFS=';' read -r daysafterzip daystosave sectionfolder logfilename
do
echo "$daysafterzip $daystosave $logbasefolder$sectionfolder$logfilename" >> log.txt

cd $logbasefolder

done < "$configfile"

Редактировать: Спасибо за ответы. Наконец-то мне удалось заставить его работать с переменной $ logfile.

Теперь я использую этот скрипт (без переменной logfile, потому что все работает на данный момент):

#!/bin/bash
# This file is managed by Ansible - Contact SysAdmin for changes!!
# file: roles/syslog-ng/templates/logrotation.sh.j2

configfile="/etc/customlogrotate/logrotation.conf"
logbasefolder="/var/log"

# Move to logbasefolder
cd $logbasefolder

# Loop all options from the configfile
while IFS=';' read -r daystozip daystodelete sectionfolder subsectionfolder logfilename
do

        datetozip=`date -d "$daystozip days ago" +%Y%m%d`
        datetodelete=`date -d "$daystodelete days ago" +%Y%m%d`

        cd $logbasefolder$sectionfolder

        for hostfolder in $subsectionfolder/
        do
                cd $hostfolder

                # loop trough all date folder in hostfolder
                for datefolder in [0-9][0-9][0-9][0-9].[0-9][0-9].[0-9][0-9]
                do
                        # remove dashes from datefolder
                        datefoldershort=`echo "$datefolder" | tr -d .`

                        # check if logfile is to be deleted based on date
                        if test "$datefoldershort" -lt "$datetodelete"
                        then
                                cd $datefolder

                                # search folder for logfilename and delete it
                                for filetodelete in $logfilename.gz
                                do
                                        #Put script for deletion here    
                                done

                                # move back one folder to continue the list
                                cd ..

                        # check if logfile is to be zipped based on date
                        elif test "$datefoldershort" -lt "$datetozip"
                        then
                                cd $datefolder
                                # search folder for logfilename and zip it
                                for filetozip in $logfilename
                                do
                                        gzip ${logfilename:1}
                                done
                               # move back one folder to continue the list
                                cd ..
                        fi
                done

                # move back one folder to continue the list
                cd ..
        done
done < "$configfile"

С этим configfile:

11;14;/customers;core*;/apache.log
10;13;/customers;core*;/custom.log
9;12;/customers;core*;/system.log
11;14;/customers;srv*;/error.log
8;9;/customers;srv*;/system.log

Еще раз спасибо!!

2 ответа2

0

Я думаю, что вам, возможно, придется пойти по этому поводу немного по-другому (но я могу ошибаться). Из того, что я могу сказать, вам может понадобиться что-то, что вы можете автоматизировать (например, использовать что-то вроде crontab). Это означает:

  • либо вы пишете скрипт, который пересекает все папки ниже "/var/log/", затем читает имя каждого файла, проверяет расписание архивации для этого типа файла, затем проверяет, когда этот конкретный файл был заархивирован последним, и действует соответствующим образом. ;
  • или вы немного облегчаете свою жизнь, создавая ряд сценариев, предназначенных для определенной цели, и настраивая cronjobs для каждого.

Лично я бы предпочел второй вариант. Он гораздо более модульный, и, как только вы его установите, его, вероятно, также будет проще поддерживать. Все это будет выглядеть примерно так:

  • Скрипт1: zip всех клиентов /* /* log; установите cron для запуска каждые 7 дней
  • Скрипт2: zip all server /* /access.log; запускать cron каждые 28 дней
  • Скрипт3: zip all server /* /error.log; крон каждые 14 дней
  • Script4: удалить все файлы, которые нужно удалить через 365 дней; установите cron соответственно
  • Script5: удалить все файлы, которые нужно удалить через 180 дней; установите cron соответственно

Звучит более утомительно и сложно, чем должно быть на самом деле, модульно, легко обслуживается и настраивается

Надеюсь это поможет. JW

0

Сценарий работает, как вы ожидаете, но он меняет каталог, в который записывает log.txt .

Первоначально сценарий выполняет запись в log.txt в текущем каталоге, но сценарий изменяет свой каталог. Команда cd $logbasefolder изменяет текущий каталог, поэтому скрипт начинает записывать log.txt в один каталог, но после команды cd вместо этого он записывает log.txt в $logbasefolder .

Устраните проблему, используя переменную для записи пути к log.txt (возможны $PWD или $HOME ), или используйте pushd и popd для обмена каталогами между исходным каталогом и $logbasefolder . Например:

#!/bin/bash
configfile="/etc/customlogrotate/logrotation.conf"
logbasefolder="/var/log"
logfile="$PWD/log.txt"

echo " " > $logfile
echo " " >> $logfile
echo "Starting logrotation script" >> $logfile

while IFS=';' read -r daysafterzip daystosave sectionfolder logfilename
do

echo "$daysafterzip $daystosave $logbasefolder$sectionfolder$logfilename" >> $logfile

# alternative method to $logfile variable:
# pushd $logbasefolder > /dev/null
#  zip and delete files ...
# popd > /dev/null
cd $logbasefolder   # remove with pushd and popd

done < "$configfile"

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .