fix: 计划任务增加日志备份 (#2595)

Refs #2008
This commit is contained in:
ssongliu 2023-10-20 11:32:45 +08:00 committed by GitHub
parent a5c0e41bda
commit 7a1d4345fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 108 additions and 3 deletions

View File

@ -69,6 +69,8 @@ func (u *CronjobService) HandleJob(cronjob *model.Cronjob) {
messageItem, err = u.handleSystemClean()
message = []byte(messageItem)
u.HandleRmExpired("LOCAL", "", "", cronjob, nil)
case "log":
record.File, err = u.handleSystemLog(*cronjob, record.StartTime)
}
if err != nil {
@ -593,3 +595,99 @@ func (u *CronjobService) handleSnapshot(cronjob *model.Cronjob, startTime time.T
func (u *CronjobService) handleSystemClean() (string, error) {
return NewISettingService().SystemCleanForCronjob()
}
func (u *CronjobService) handleSystemLog(cronjob model.Cronjob, startTime time.Time) (string, error) {
websites, err := websiteRepo.List()
if err != nil {
return "", err
}
backup, err := backupRepo.Get(commonRepo.WithByID(uint(cronjob.TargetDirID)))
if err != nil {
return "", err
}
pathItem := path.Join(global.CONF.System.BaseDir, "1panel/tmp/log", startTime.Format("20060102150405"))
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
if err != nil {
return "", err
}
webItem := path.Join(nginxInstall.GetPath(), "www/sites")
for _, website := range websites {
dirItem := path.Join(pathItem, "website", website.Alias)
if _, err := os.Stat(dirItem); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(dirItem, os.ModePerm); err != nil {
return "", err
}
}
itemDir := path.Join(webItem, website.Alias, "log")
logFiles, _ := os.ReadDir(itemDir)
if len(logFiles) != 0 {
for i := 0; i < len(logFiles); i++ {
if !logFiles[i].IsDir() {
_ = cpBinary([]string{path.Join(itemDir, logFiles[i].Name())}, dirItem)
}
}
}
itemDir2 := path.Join(global.CONF.System.Backup, "log/website", website.Alias)
logFiles2, _ := os.ReadDir(itemDir2)
if len(logFiles2) != 0 {
for i := 0; i < len(logFiles2); i++ {
if !logFiles2[i].IsDir() {
_ = cpBinary([]string{path.Join(itemDir2, logFiles2[i].Name())}, dirItem)
}
}
}
}
systemLogDir := path.Join(global.CONF.System.BaseDir, "1panel/log")
systemDir := path.Join(pathItem, "system")
if _, err := os.Stat(systemDir); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(systemDir, os.ModePerm); err != nil {
return "", err
}
}
systemLogFiles, _ := os.ReadDir(systemLogDir)
if len(systemLogFiles) != 0 {
for i := 0; i < len(systemLogFiles); i++ {
if !systemLogFiles[i].IsDir() {
_ = cpBinary([]string{path.Join(systemLogDir, systemLogFiles[i].Name())}, systemDir)
}
}
}
loginLogFiles, _ := os.ReadDir("/var/log")
loginDir := path.Join(pathItem, "login")
if _, err := os.Stat(loginDir); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(loginDir, os.ModePerm); err != nil {
return "", err
}
}
if len(loginLogFiles) != 0 {
for i := 0; i < len(loginLogFiles); i++ {
if !loginLogFiles[i].IsDir() && (strings.HasPrefix(loginLogFiles[i].Name(), "secure") || strings.HasPrefix(loginLogFiles[i].Name(), "auth.log")) {
_ = cpBinary([]string{path.Join("/var/log", loginLogFiles[i].Name())}, loginDir)
}
}
}
fileName := fmt.Sprintf("system_log_%s.tar.gz", startTime.Format("20060102150405"))
if err := handleTar(pathItem, pathItem, fileName, ""); err != nil {
return "", err
}
client, err := NewIBackupService().NewClient(&backup)
if err != nil {
return "", err
}
targetPath := "log/" + fileName
if len(backup.BackupPath) != 0 {
targetPath = strings.TrimPrefix(backup.BackupPath, "/") + "/log/" + fileName
}
if _, err = client.Upload(path.Join(pathItem, fileName), targetPath); err != nil {
return "", err
}
u.HandleRmExpired(backup.Type, backup.BackupPath, "", &cronjob, client)
return targetPath, nil
}

View File

@ -733,6 +733,7 @@ const message = {
taskType: 'Cronjob type',
record: 'Records',
shell: 'Shell script',
log: 'Backup logs',
containerCheckBox: 'In container (no need to enter the container command)',
containerName: 'Container name',
ntp: 'Time synchronization',

View File

@ -705,6 +705,7 @@ const message = {
taskType: '任務類型',
record: '報告',
shell: 'Shell 腳本',
log: '日誌備份',
containerCheckBox: '在容器中執行無需再輸入進入容器命令',
containerName: '容器名稱',
ntp: '時間同步',

View File

@ -706,6 +706,7 @@ const message = {
taskType: '任务类型',
record: '报告',
shell: 'Shell 脚本',
log: '日志备份',
containerCheckBox: '在容器中执行无需再输入进入容器命令',
containerName: '容器名称',
ntp: '时间同步',

View File

@ -28,6 +28,7 @@
<el-option value="ntp" :label="$t('cronjob.ntp')" />
<el-option value="cutWebsiteLog" :label="$t('cronjob.cutWebsiteLog')" />
<el-option value="clean" :label="$t('setting.diskClean')" />
<el-option value="log" :label="$t('cronjob.log')" />
</el-select>
<el-tag v-else>{{ $t('cronjob.' + dialogData.rowData!.type) }}</el-tag>
</el-form-item>
@ -176,7 +177,7 @@
<el-select class="selectClass" v-model="dialogData.rowData!.targetDirID">
<div v-for="item in backupOptions" :key="item.label">
<el-option
v-if="item.label !== $t('setting.LOCAL') || dialogData.rowData!.type !== 'snapshot'"
v-if="item.label !== $t('setting.LOCAL') || (dialogData.rowData!.type !== 'snapshot' && dialogData.rowData!.type !== 'log')"
:value="item.value"
:label="item.label"
/>
@ -195,7 +196,7 @@
</span>
</el-form-item>
<el-form-item
v-if="dialogData.rowData!.targetDirID !== localDirID && dialogData.rowData!.type !== 'snapshot'"
v-if="dialogData.rowData!.targetDirID !== localDirID && dialogData.rowData!.type !== 'snapshot' && dialogData.rowData!.type !== 'log'"
>
<el-checkbox v-model="dialogData.rowData!.keepLocal">
{{ $t('cronjob.saveLocal') }}
@ -454,12 +455,14 @@ const changeType = () => {
dialogData.value.rowData.hour = 2;
dialogData.value.rowData.minute = 30;
break;
case 'clean':
case 'website':
dialogData.value.rowData.specType = 'perWeek';
dialogData.value.rowData.week = 1;
dialogData.value.rowData.hour = 1;
dialogData.value.rowData.minute = 30;
break;
case 'log':
case 'snapshot':
dialogData.value.rowData.specType = 'perWeek';
dialogData.value.rowData.week = 1;
@ -531,7 +534,8 @@ function isBackup() {
dialogData.value.rowData!.type === 'website' ||
dialogData.value.rowData!.type === 'database' ||
dialogData.value.rowData!.type === 'directory' ||
dialogData.value.rowData!.type === 'snapshot'
dialogData.value.rowData!.type === 'snapshot' ||
dialogData.value.rowData!.type === 'log'
);
}