AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 646051
Accepted
Andy Joiner
Andy Joiner
Asked: 2014-11-22 02:11:19 +0800 CST2014-11-22 02:11:19 +0800 CST 2014-11-22 02:11:19 +0800 CST

Acronis 命令后查询备份状态

  • 772

我想在备份成功完成时执行一项操作(但不是在失败时)。

  • 有没有办法将备份状态传递给备份后命令?
  • 或者我可以从备份后查询的环境变量?
  • 或者一种查询作业状态的简单方法(可能正在运行多个作业)。
  • 考虑登录事件日志并使用LogParser搜索成功消息。

我目前正在使用电子邮件通知,将电子邮件发送到机器人,机器人从主题中解析出备份状态,然后在备份成功时运行命令。

产品:Acronis Backup & Recovery 10

automation
  • 2 2 个回答
  • 1298 Views

2 个回答

  • Voted
  1. Best Answer
    Cyber
    2015-01-02T22:00:36+08:002015-01-02T22:00:36+08:00

    据我所知,没有一个简单的方法。

    和你一样,我目前收到一封任务后状态电子邮件;但是,我想将该信息的子集放入仪表板系统中。我刚刚编写了一个 python (3.4) 脚本来从 Acronis 日志中提取信息并写入日志文件。我也增加了有条件地执行命令的能力。(我在批处理文件中完成了这部分,但是可以修改 python 脚本以执行命令......从而消除对批处理文件的需要。)

    通过一些轻微的修改/定制,这应该适合你。

    概念

    • Acronis 命令后操作启动批处理文件
    • ...启动一个 python 脚本
    • ...解析 Acronis 日志,检测成功或失败(除其他外),并返回错误代码
    • ...由批处理文件捕获
    • ...然后根据成功或失败有条件地执行操作

    注意事项

    • python 脚本将读取最后修改的日志文件,因此并发 Acronis 操作可能很冒险。
    • python 脚本仅读取文件名以星期几开头的日志文件。(即它将忽略任何“console_xxxxx.log”[和类似的]日志。但这就是我们想要的。)
    • 我是一名开发人员,但这是我第一次尝试 python,所以它可能不是很漂亮。

    要求

    • Python 3.4 安装在环境 PATH 中,并与 .py 文件相关联
    • untanglepython包已安装(pip install untangle)

    脚步

    1. 创建以下批处理文件并将其另存为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
      )
      
    2. 创建以下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)
      
    3. 使用以下对话框设置配置 Acronis 以将批处理文件 ( acronis.cmd) 作为命令后操作运行:

      • 命令:C:/path/to/acronis.cmd
      • 工作目录:(C:/path/to批处理文件的位置)
      • 参数:(留空)
      • [ ] 在命令执行完成之前不要执行操作
      • [x] 如果用户命令失败则中止操作

    编辑:选中“不执行操作...”复选框可能会产生 XML 解析错误,因为日志文件可能尚未刷新。

    • 2
  2. Andy Joiner
    2015-01-03T02:38:36+08:002015-01-03T02:38:36+08:00
    1. 请参阅 Cyber​​ 的综合答案- 这是我推荐的路线。

    2. 在 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.%'
    
    • 1

相关问题

  • 虚拟化自动化

  • Mac OS X 的无人值守安装

  • 您如何处理服务器上的更新?

  • 即将过期的非活动用户帐户

  • 自动化服务器部署

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve