Matlab 2014 console logs to Jenkins console logs

As it appears, using Matlab and Jenkins together will not work properly regarding the console. The console output of Matlab will simply not appear in the console output of jobs in Jenkins. This will make it harder for developer to look for the reasons of failed jobs, due to there is no information about what is going on inside Matlab.

Looking back at how it worked in Matlab 2013 it appears Matlab 2014 stopped putting the console logs to the Standard Output, which is the requirement for Jenkins to transfer these logs. Therefore no Logs from Matlab will appear in the Jenkin Jobs which makes bugtracking often impossible.

The official Support message from Matlab is that “Jenkins Support” was never intended and will not in the future. So in my opinion there is no hope for just waiting for MathWorks to solve this problem. But still, there are workarounds here. The official MathWorks workaround written in C is from 2012 – never tested it but the steps somehow make sense.

As I had to deal with the Problem in Powershell (I think v1.1) I build another workaround. First you have to get the output somehow. When Matlab is starting there is an option to start it with outputting the logs to a specifig logfile:

-nodesktop -nosplash -logfile  $workingDir\matlabExeBuild.log -r `"run(`'$matlabBuildScriptName`');quit;`"

Second, you need to write from this logfile in order to get it in the Standard Output, visible for Jenkins. While getting the content of the logfile, keep in mind that you get it as an array, therefore you have to join these single array fields correctly in order to also display it correctly:

$matlabExeBuildLog = (Get-Content matlabExeBuild.log) -join "`n"
Write-Host $matlabExeBuildLog

The negative side of this solution is that it assumes the logfile is completely written and it therefore will only display the complete logs after Matlab completed the work, due to only using one thread. If inside a Matlab job an error occurs which keeps the job hanging, the output will never be printed, even if the job will be manually aborted.

A solution to this problem can be the “-tail”-parameter in Powershell v3, which makes it possible to print a line of a file in the moment it will be saved there. Still, I have no idea how it will work using only one thread and specifically how this “-tail”-parameter will know when to stop. This could result in an endless loop of checking if there is a new line available.

In my case – which has only Powershell v1.1 available – I ended with a solution with Python.

Right after starting Matlab with the parameter above inside Powershell, I start a Python script (yep, this seems to work)

C:\Python27\python.exe $skript_directory\pythonLogReader.py

which will reads the latest line(s) and just print it (there are a lot of available solutions to read live logs in Python). Still I found no solution where the Python-script does know when to stop. Therefore the Powershell script will hang in an endless loop checking if there is a new line. So I updated the Matlab starting parameters:

-nodesktop -nosplash -logfile  $workingDir\matlabExeBuild.log -r `"run(`'$matlabBuildScriptName`');
fprintf(YOUREACHEDTHEEND); quit;`"

In addition, this is somehow the Python-Script based on the follow.py:

# follow.py
#
# Follow a file like tail -f.

import time
import sys
import os
import os.path

def follow(thefile):
thefile.seek(0,2)
while True:
line = thefile.readline()
if not line:
time.sleep(0.1)
continue
yield line

# Example use
# Note : This example requires the use of an apache log simulator.
#
# Go to the directory run/foo and run the program 'logsim.py' from
# that directory. Run this program as a background process and
# leave it running in a separate window. We'll write program
# that read the output file being generated
#

def openfile(t):
try:
logfile = open("matlabExeBuild.log","r")
loglines = follow(logfile)
for line in loglines:
print line.rstrip()
sys.stdout.flush()
PROCNAME = "matlab"
if "YOUREACHEDTHEEND" in line:
print "Matlab log finished - exiting Python Logreader"
sys.exit()
except IOError as e:
print "I/O error({0}): {1}".format(e.errno, e.strerror)
time.sleep(1)
openfile("ii")
sys.stdout.flush()

if __name__ == '__main__':
openfile("ii")

Every time my Python-script is reading a new line, it tests if it is “YOUREACHEDTHEEND”. If it reached this line, the script knows Matlab is done with the work, I close the script and we have Matlab live logs in Jenkins with Powershell by using a little Python script.