Я хотел бы выполнить действие, когда резервное копирование завершится успешно (но не при сбое).
В настоящее время я использую уведомление по электронной почте, отправляя электронное письмо боту, который анализирует состояние резервного копирования из темы, а затем запускает команду, если резервное копирование было успешным.
Продукт: Acronis Backup & Recovery 10
Судя по тому, что я видел, нет простого пути.
Как и вы, я в настоящее время получаю электронное письмо о статусе выполнения задачи; однако я хотел бы получить часть этой информации в системе панелей управления. Я просто написал сценарий python (3.4) для извлечения информации из журналов Acronis и записи в файл журнала. Я также добавил возможность условного выполнения команд. (Я сделал эту часть в пакетном файле, но скрипт python можно было изменить для выполнения команд ... тем самым устраняя необходимость в пакетном файле.)
С небольшой модификацией / настройкой это должно сработать для вас.
untangle
установлен пакет python (pip install untangle
)Создайте следующий командный файл и сохраните его как acronis-last-log.cmd
. Измените применимые команды для условного выполнения действий.
@echo off
REM Filename: acronis-last-log.cmd
acronis-last-log.py
if ERRORLEVEL 1 (
echo This statement is executed whenever the Acronis task FAILS
echo Insert any action here within the if-clause
) else (
echo This statement is executed whenever the Acronis task SUCCEEDS
echo Insert any action here within the else-clause
)
Создайте следующий скрипт python и сохраните его как acronis-last-log.py
и поместите его в ту же папку, что и командный файл. Обязательно посетите CONFIGURATION VARIABLES
раздел, чтобы изменить любые пути или параметры. Примечание. При этом создается файл журнала на основе имени задачи, который перезаписывается каждый раз при выполнении задачи Acronis. Чтобы отключить файл журнала, закомментируйте with open(...) as outFile
и print(..., file=outFile)
строк, не забывая при необходимости корректировать отступы кода. Чтобы изменить путь к журналу, отредактируйте outputPath
переменная.
# Filename:
# acronis-last-log.py
#
# Description:
# Process an Acronis log file and print out relevant output in a formatted string.
#
# Rules:
# 1. if any log entry is greater than ACRONIS_LOG_INFO, report that the task has failed.
# - This is how the Acronis emails work. Warnings will cause the "failed" summary
import glob
import os
import sys
import textwrap
import time
import untangle # to install: pip install untangle
########## CONSTANTS DECONSTRUCTED FROM ACRONIS LOGS ###########################
# log module that provides the overall task status
ACRONIS_STATUS_MODULE = 316
# Acronis log error levels ("levels")
# (0 and 1 are dummy entries that don't seem to exist within the logs)
ACRONIS_LOG_DUMMY0 = 0
ACRONIS_LOG_DUMMY1 = 1
ACRONIS_LOG_INFO = 2
ACRONIS_LOG_WARNING = 3
ACRONIS_LOG_ERROR = 4
# Error level descriptions
# descriptions for printing, indexed by the above constants
# padded to 7 characters long for alignment
ERROR_LEVEL_DESCRIPTIONS = ["DUMMY0 ", "DUMMY1 ", "INFO ", "WARNING", "ERROR "]
########## CONFIGURATION VARIABLES #############################################
# showSubMessages
# show auxiliary messages that meet the error level threshold (set below)
# True: show subMessages
# False: only show the overall exit error level (module 316)
showSubMessages = True
# logPath
# path to Acronis log files (default: C:\ProgramData\Acronis\TrueImageHome\Logs)
logPath = r'C:\ProgramData\Acronis\TrueImageHome\Logs'
# outputPath
# path to where this script will output
outputPath = r'.'
# debug
# turn debugging on? (default: False)
debug = False
# minLevelToDisplay
# minimum error level to display (default: ACRONIS_LOG_WARNING)
minLevelToDisplay = ACRONIS_LOG_WARNING
# maxLevelToDisplay
# maximum error level to display (default: ACRONIS_LOG_ERROR)
maxLevelToDisplay = ACRONIS_LOG_ERROR
########## HELPER FUNCTIONS ####################################################
def logDescription(errorLevel):
"""Return a log description based on Acronis error level."""
return ERROR_LEVEL_DESCRIPTIONS[errorLevel]
########## FUNCTIONS ###########################################################
def process(logFile):
"""Process an Acronis log file and print out relevant output in a formatted string.
with !showSubMessages, just a single line is printed:
yyyy-mm-dd hh:mm:ss ERRORLEVEL [AcronisTask] Summary
e.g.
2014-12-25 14:16:40 WARNING [MyBackupTask] execution failed
with showSubMessages, multiple will be printed:
yyyy-mm-dd hh:mm:ss ERRORLEVEL [AcronisTask] Summary
ERRORLEVEL SubMessage 1
ERRORLEVEL SubMessage 2
ERRORLEVEL SubMessage n
e.g.
2014-12-25 14:16:40 ERROR [MyBackupTask] execution failed
ERROR The quotas are violated.
ERROR Cannot perform this operation in quiet mode. (0x103F1) Tag = 0x1D8EAB676A3F6BAA Target drive is running out of space. (0x4001D) Tag = 0x1D8EAB676A3F6BAB
WARNING Terminated by user.
WARNING Batch operation has been terminated by user.
Note: the first ERRORLEVEL printed (the one between the timestamp and [AcronisTask])
will be the highest error level in the log
"""
# store the highest error level
highestLevel = ACRONIS_LOG_DUMMY0
subMessages = []
success = False
try:
xmlDocument = untangle.parse(logFile)
# read task_name
taskName = xmlDocument.log['task_name']
# open output file
with open(outputPath + r"\acronis-" + taskName + ".log", 'w') as outFile:
if debug:
print("Debug mode enabled. Processing", logFile)
print("Debug mode enabled. Processing", logFile, file=outFile)
# for each log event
for event in xmlDocument.log.event:
# read attributes
eventId = int(event['id'])
eventLevel = int(event['level'])
eventModule = int(event['module'])
eventCode = int(event['code'])
eventTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(event['time'])))
eventMessage = event['message']
# strip unicode characters out (yes, it happens for some INFO messages annotating user responses)
eventMessage = eventMessage.encode('ascii', 'ignore').decode('ascii', 'ignore')
# set highestLevel
if eventLevel > highestLevel:
highestLevel = eventLevel
# add subMessages, if they fit into the level threshold
if (eventLevel >= minLevelToDisplay) and \
(eventLevel <= maxLevelToDisplay):
subMessages.append([logDescription(eventLevel), eventMessage])
# create summary message for top line
summary = "execution failed"
# determine success
if highestLevel <= ACRONIS_LOG_INFO:
summary = "completed successfully"
success = True
# print the summary message
if (highestLevel >= minLevelToDisplay) and \
(highestLevel <= maxLevelToDisplay):
print(eventTime, logDescription(highestLevel), "[" + taskName + "]", summary)
print(eventTime, logDescription(highestLevel), "[" + taskName + "]", summary, file=outFile)
# print subMessages, maybe
if showSubMessages:
for message in subMessages:
# do some fancy textwrapping here, because sometimes there are really long messages that wrap in the wrong places
# and a hanging indent is prettier
print(' '*(len(eventTime)+1) + message[0], textwrap.fill(message[1], 160, subsequent_indent=' '*30)) #30 = len("YYYY-MM-DD HH:MM:SS ERRCODE ") + 2 for indenting
print(' '*(len(eventTime)+1) + message[0], textwrap.fill(message[1], 160, subsequent_indent=' '*30), file=outFile) #30 = len("YYYY-MM-DD HH:MM:SS ERRCODE ") + 2 for indenting
except:
if debug:
# probably want to catch the error in debug...
raise
else:
print("Generic Error with file <" + logFile + ">.")
# return success flag
return success
########## ENTRY POINT #########################################################
if __name__ == "__main__":
# only grab files named with a day of week
# so, ignore non-compliant (won't parse) logs
# - console*,
# - monitor.log,
# - afcdpsrv.log
# - NSB*.log (non-stop backup)
logFiles = [f for f in glob.iglob(logPath + "\*.log") \
if "Sunday" in f or \
"Monday" in f or \
"Tuesday" in f or \
"Wednesday" in f or \
"Thursday" in f or \
"Friday" in f or \
"Saturday" in f]
# sort by modified date (descending)
logFiles.sort(key=os.path.getmtime, reverse=True)
# get the most recent
newestFile = logFiles[0]
# process newest file
success = process(newestFile)
# for testing purposes...
# process all log files
#for logFile in logFiles:
# process(logFile)
# return with exit code 0 if success (no warnings or errors), otherwise 1
sys.exit(0 if success else 1)
Настройте Acronis для запуска командного файла (acronis.cmd
) как пост-командное действие со следующими настройками диалогового окна:
C:/path/to/acronis.cmd
C:/path/to
(расположение командного файла)Редактировать: оставив флажок "Не выполнять операции ..." проверил может привести к ошибкам синтаксического анализа XML, поскольку файл журнала еще не был очищен.
См. Всеобъемлющий ответ - этот маршрут я бы порекомендовал.
До публикации Cyber у меня был некоторый успех с LogParser, так как я хотел отслеживать 2 задания резервного копирования.
Предостережение это LogParser решение подвержено ложным срабатываниям (например, если одно задание выполнялось дважды, а другое не выполнялось, вы получите те же результаты, что и оба задания).
Acronis 10, похоже, не публикует достаточно подробностей в журналах Windows, чтобы можно было однозначно идентифицировать успешные или даже начинающиеся задания.
чек-acronis-backup.bat
"C:\Program Files (x86)\Log Parser 2.2\LogParser.exe" -i:evt file:check-acronis-backup.sql > check-acronis-backup.out
type check-acronis-backup.out
grep "Elements output: 2" check-acronis-backup.out
if %ERRORLEVEL%==0 goto ReportSuccess
GOTO End
:ReportSuccess
call report-success acronis
:End
проверьте-acronis-backup.sql
SELECT
TOP 10 SourceName, TimeGenerated, EventCategory, Message
FROM Application
WHERE TimeGenerated > TO_TIMESTAMP(SUB(TO_INT(SYSTEM_TIMESTAMP()), 90000)) --90000 = 60*60*25
AND SourceName = 'Acronis Backup Recovery 10'
AND EventCategory = 144
AND Message like '%Task _Full backup_ completed successfully.%'