Snakemake 在使用重试时覆盖规则的日志文件 - 使它追加的惯用方式?

问题描述 投票:0回答:2

我有一个 Snakemake 工作流程,其中一条规则似乎随机失败。我正在使用 Snakemake 7.7.0 并使用

retries
指令为规则设置重试。该命令打印到 stdout 和 stderr,我想将两者附加到日志文件,保留失败尝试的输出,以便我可以跟踪失败。我所拥有的简化版本如下:

rule flaky_rule:
    input:
        infile = "{sample}/foo.txt"
    output:
        outfile = "{sample}/bar.txt"
    retries: 3
    log:
        flaky_rule_log = "{sample}/logs/flaky_rule.log"
    shell:  
        """
        flaky_script -i "{input.infile}" -o "{output.outfile}" >> "{log.flaky_rule_log}" 2>&1 
        """

但是,当我运行它并且规则失败并重新运行时,日志文件似乎被覆盖了。目前,我的解决方法是改为在

params
指令中设置日志文件,但这当然会让我被 linter 告知,因为我“没有设置日志文件”并且对我来说有点老套。有没有更惯用的方法来做到这一点(在这个版本或更高版本中)?

logging snakemake
2个回答
0
投票

可能太复杂而且不是很惯用,但无论如何这里有一个选项。将您的命令作为 python 子进程运行,分析输出并在多次重试后决定要做什么。例如:

rule flaky_rule:
    input:
        infile = "{sample}/foo.txt"
    output:
        outfile = "{sample}/bar.txt"
    params:
        retries = 3
    log:
        flaky_rule_log = "{sample}/logs/flaky_rule.log"
    run:
        import subprocess

        for retry in range(0, params.retries):
            p = subprocess.Popen('flacky_script {input} {output} >> "{log.flaky_rule_log}" 2>&1', 
                stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
            stdout, stderr = p.communicate()
            if p.returncode == 0:
                break
        if p.returncode != 0:
            raise Exception('Failed after %s retries' % params.retries)

0
投票

这是基于对相关问题的回答的变体。这个想法是将日志文件的路径指定为资源。这意味着

snakemake
不会自动清除它(在某些情况下这可能是不可取的,因此请谨慎使用):

rule flaky_rule:
    input:
        infile = "{sample}/foo.txt"
    output:
        outfile = "{sample}/bar.txt"
    resources:
        flaky_rule_log = lambda wildcards, attempt: f"{wildcards.sample}/logs/flaky_rule_attempt{attempt}.log"
    retries: 3        
    shell:  
        """
        flaky_script -i "{input.infile}" -o "{output.outfile}" >> "{resources.flaky_rule_log}" 2>&1 
        """

如果

params
logs
支持
attempt
就好了,但现在这仍然是一个悬而未决的问题.

© www.soinside.com 2019 - 2024. All rights reserved.