How to get build log in context provider?

How can I obtain the build logs in a context provider? I’ve tried building the URL to the build log but when I access it, it requires login so it doesn’t seem to be the most elegant way.

Nothing seems to be exposed in the context object provided.

1 Like

Hi,
at the moment i’m facing the same problem.

The only thing i’ve found is

resultsSummary.getImmutablePlan().getBuildLogger().getBuildLog().toString()

within the ContextManager, but unfortunately this just seems to be the Bamboo log about activities of the plan, not about the actual build process.

I neither find any documentation about that, nor something useful in javadocs.
It would be really nice to get an answer on this. :slightly_smiling_face:

The build logs are actually stored on disk, and they are retrieved via the BuildLogFileAccessorFactory class. This should be available in your ContextProvider via dependency injection, or via the ComponentAccessor. Be aware that you need either the PlanKey and the build number or the PlanResultKey to invoke the createBuildLogFileAccessor() method.

This will give you access to a BuildLogFileAccessor implementation, which has the required methods for reading lines.

You should download the Bamboo sources and search for viewBuildLog.ftl and ViewBuildLogs.java

2 Likes

So i was able to use BuildLogFileAccessor now to get the content of build_logs for plans.
Within my test project (a simple script with some output) those build_logs are only created when i trigger a build through a new commit, not by a manual run. And even worse: they still do not contain the desired output. There is only one line:

simple 22-Jan-2020 14:38:14 Change detection found 1 change, starting build TEST-TEST-4

BuildLogFileAccessor gives me the content of the file target/bamboo/home/xml-data/builds/plan-3178497/download-data/build_logs/plan-3178497-4.log. But the content I’m looking for is saved under target/bamboo/home/xml-data/builds/plan-3178497-JOB1/download-data/build_logs/plan-3178497-JOB1-4.log.
How can i access this file instead of the one above? Source code says, that the constructor for using a direct file path is deprecated and for tests only, and furthermore there is no Factory-method for that. How do i pass in the very job i’m interested in?

Turns out that i was confused by all the different types of available ResultSummary objects (as there is no documentation about it, which makes it really hard for beginners). The following is now working for me:

I use a ResultsSummaryManager, which i let import by Spring, to get a ChainResultsSummary object. From that i was able to traverse through all stages and jobs and get their logs as described by @remie. I append some example code below if someone else needs a quick hint on how to use all those result objects.

    public String getLogs(){
        try{
            String answer = "";
            answer += "<h2>Playground</h2>";

            ChainResultsSummary chainResults = resultsSummaryManager.getLastResultsSummary(plan.getKey(), ChainResultsSummary.class);

            for(ChainStageResult stageResult: chainResults.getStageResults()) {
                answer += "<h3>Stage: " + stageResult.getName() + "</h3>";
                for (BuildResultsSummary buildResult : stageResult.getBuildResults()) {
                    answer += "<h4>Build Number: " + buildResult.getBuildNumber() + "</h4>";
                    for (LogEntry entry : retrieveBuildLogs(buildResult)) {
                        answer += "<p>" + entry.getLog() + "</p>";
                    }
                }
            }
            return answer;
        } catch (Exception e) {
            log.error("Failed to load build logs for build " + resultsSummary.getPlanKey() + "-" + (resultsSummary != null ? resultsSummary.getBuildNumber() : null), e);
        }
        return "<i>Error: Couldn't access logs. Check bamboo's log output for details!</i>";
    }

    private List<LogEntry> retrieveBuildLogs(BuildResultsSummary buildResultsSummary){
        try {
            final BuildLogFileAccessor fileAccessor = buildLogFileAccessorFactory.createBuildLogFileAccessor(buildResultsSummary.getPlanKey(), buildResultsSummary.getBuildNumber());
            return fileAccessor.getLastNLogsOfType(1000, Lists.newArrayList(BuildOutputLogEntry.class, ErrorLogEntry.class));
        } catch (FileNotFoundException e) {
            log.warn("Failed to load build log as file doesn't exist yet key -" + buildResultsSummary.getBuildNumber());
        } catch (Exception e) {
            log.error("Failed to load build logs for build key -" + buildResultsSummary.getBuildNumber(), e);
        }
        return Collections.emptyList();
    }

@remie thank you for your assistance.

3 Likes