Home > Mobile >  Writing to output stream in chunks in Groovy
Writing to output stream in chunks in Groovy

Time:12-22

I'm getting Jenkins console logs and writing them into an output stream like this:

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

However, the downside of this approach is that writeLogTo() method is limited to 10000 lines: https://github.com/jenkinsci/stapler/blob/master/core/src/main/java/org/kohsuke/stapler/framework/io/LargeText.java#L572

In this case, if Jenkins console log is more than a 10000 lines then the data from line 10000 and up is lost and not written into a buffer.

I'm trying to re-write the above approach in the most easiest way to account for cases when the log has more than 10000 lines.

I feel like my attempt is very complicated and error-prone. Is there an easier way to introduce a new logic?

Please note that the code below is not tested, this is just a draft of how I'm planning to implement it:

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
}

CodePudding user response:

writeLogTo(long start, OutputStream out)

According to comments this method returns the offset to start the next write operation.

Seems code could be like this

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

stream could be a FileOutputStream to avoid reading whole log into memory.

There is another method readAll()

So, the code could be simple as this to read whole log as text:

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

Or if you want to transfer it to a local file:

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