在Groovy中按块写入输出流

jjjwad0x  于 2022-12-26  发布在  其他
关注(0)|答案(1)|浏览(126)

我获取Jenkins控制台日志并将它们写入输出流,如下所示:

ByteArrayOutputStream stream = new ByteArrayOutputStream()
    currentBuild.rawBuild.getLogText().writeLogTo(0, stream)

然而,这种方法的缺点是writeLogTo()方法被限制为10000行:https://github.com/jenkinsci/stapler/blob/master/core/src/main/java/org/kohsuke/stapler/framework/io/LargeText.java#L572
在这种情况下,如果Jenkins控制台日志超过10000行,则第10000行及以上的数据将丢失,不会写入缓冲区。
我尝试用最简单的方法重写上面的方法,以考虑日志超过10000行的情况。
我觉得我的尝试很复杂,容易出错,有没有更简单的方法来引入新的逻辑?
请注意,下面的代码没有经过测试,这只是我计划如何实现它的草案:

ByteArrayOutputStream stream = new ByteArrayOutputStream()
def log = currentBuild.rawBuild.getLogText()

def offset = 0
def maxNumOfLines = 10000

# get total number of lines in the log
# def totalLines = (still trying to figure out how to get it)
if (totalLines > maxNumOfLines) {
    def numOfExecutions = round(totalLines / maxNumOfLines)
}

for (int i=0; i<numOfExecutions; i++) {
    log.writeLogTo(offset, stream)
    offset += maxNumOfLines
}
wxclj1h5

wxclj1h51#

writeLogTo(long start, OutputStream out)

根据注解,此方法返回开始下一个写操作的偏移量。
代码可能是这样的

def logFile = currentBuild.rawBuild.getLogText()
def start=0
while(logFile.length()>start)
    start=logFile.writeLogTo(start, stream)

stream可以是FileOutputStream,以避免将整个日志读入内存。
还有一种方法readAll()
因此,代码可以像这样简单,以文本形式读取整个日志:

def logText=currentBuild.rawBuild.getLogText().readAll().getText()

或者,如果要将其传输到本地文件:

new File('path/to/file.log').withWriter('UTF-8'){ w->
    w << currentBuild.rawBuild.getLogText().readAll()
}

相关问题