Skip to content

Commit

Permalink
Fix bug where it was attempting to use a null parent span (#314)
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-richardson authored Sep 13, 2024
1 parent 80c0661 commit 6ffc8f6
Showing 1 changed file with 58 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,38 +58,42 @@ public TeamCityBuildListener(
public void buildStarted(@NotNull SRunningBuild build) {
if (!nodesService.getCurrentNode().isMainNode()) return;

var rootBuildInChain = getRootBuildInChain(build);
try (var ignored1 = CloseableThreadContext.put("teamcity.build.id", String.valueOf(build.getBuildId()))) {
LOG.debug(String.format("Build started method triggered for '%s', id %d", getBuildName(build), build.getBuildId()));

try (var ignored2 = CloseableThreadContext.put("teamcity.root.build.id", String.valueOf(rootBuildInChain.getId()))) {

var otelHelper = otelHelperFactory.getOTELHelper(rootBuildInChain);
if (otelHelper.isReady()) {
var rootBuildInChainId = rootBuildInChain.getId();
LOG.debug(String.format("Root build of build id %d is %d", build.getBuildId(), rootBuildInChainId));

Span rootSpan = otelHelper.getOrCreateParentSpan(String.valueOf(rootBuildInChainId));
buildStorageManager.saveTraceId(build, rootSpan.getSpanContext().getTraceId());

var span = ensureSpansExistLinkingToRoot(otelHelper, build.getBuildPromotion(), rootBuildInChain);

try (Scope ignored3 = rootSpan.makeCurrent()) {
setSpanBuildAttributes(otelHelper, build, span, getBuildName(build), BUILD_SERVICE_NAME);
span.addEvent(PluginConstants.EVENT_STARTED);
LOG.debug(String.format("%s event added to span for build '%s', id %d", PluginConstants.EVENT_STARTED, getBuildName(build), build.getBuildId()));
} catch (Exception e) {
LOG.error("Exception in Build Start caused by: " + e + e.getCause() +
", with message: " + e.getMessage() +
", and stacktrace: " + Arrays.toString(e.getStackTrace()));
if (span != null) {
span.setStatus(StatusCode.ERROR, PluginConstants.EXCEPTION_ERROR_MESSAGE_DURING_BUILD_START + ": " + e.getMessage());
try {
var rootBuildInChain = getRootBuildInChain(build);
try (var ignored1 = CloseableThreadContext.put("teamcity.build.id", String.valueOf(build.getBuildId()))) {
LOG.debug(String.format("Build started method triggered for '%s', id %d", getBuildName(build), build.getBuildId()));

try (var ignored2 = CloseableThreadContext.put("teamcity.root.build.id", String.valueOf(rootBuildInChain.getId()))) {

var otelHelper = otelHelperFactory.getOTELHelper(rootBuildInChain);
if (otelHelper.isReady()) {
var rootBuildInChainId = rootBuildInChain.getId();
LOG.debug(String.format("Root build of build id %d is %d", build.getBuildId(), rootBuildInChainId));

Span rootSpan = otelHelper.getOrCreateParentSpan(String.valueOf(rootBuildInChainId));
buildStorageManager.saveTraceId(build, rootSpan.getSpanContext().getTraceId());

var span = ensureSpansExistLinkingToRoot(otelHelper, build.getBuildPromotion(), rootBuildInChain);

try (Scope ignored3 = rootSpan.makeCurrent()) {
setSpanBuildAttributes(otelHelper, build, span, getBuildName(build), BUILD_SERVICE_NAME);
span.addEvent(PluginConstants.EVENT_STARTED);
LOG.debug(String.format("%s event added to span for build '%s', id %d", PluginConstants.EVENT_STARTED, getBuildName(build), build.getBuildId()));
} catch (Exception e) {
LOG.error("Exception in Build Start caused by: " + e + e.getCause() +
", with message: " + e.getMessage() +
", and stacktrace: " + Arrays.toString(e.getStackTrace()));
if (span != null) {
span.setStatus(StatusCode.ERROR, PluginConstants.EXCEPTION_ERROR_MESSAGE_DURING_BUILD_START + ": " + e.getMessage());
}
}
} else {
LOG.info(String.format("Build start triggered for '%s', id %d and plugin not ready. This build will not be traced.", getBuildName(build), build.getBuildId()));
}
} else {
LOG.info(String.format("Build start triggered for '%s', id %d and plugin not ready. This build will not be traced.", getBuildName(build), build.getBuildId()));
}
}
} catch (Exception e) {
LOG.error("Exception in buildStarted caused by: " + e.getMessage(), e);
}
}

Expand Down Expand Up @@ -155,19 +159,27 @@ private void setSpanBuildAttributes(OTELHelper otelHelper, SRunningBuild build,

@Override
public void buildFinished(@NotNull SRunningBuild build) {
try (var ignored1 = CloseableThreadContext.put("teamcity.build.id", String.valueOf(build.getBuildId()))) {
LOG.debug(String.format("Build finished method triggered for %s", getBuildId(build)));
super.buildFinished(build);
buildFinishedOrInterrupted(build);
try {
try (var ignored1 = CloseableThreadContext.put("teamcity.build.id", String.valueOf(build.getBuildId()))) {
LOG.debug(String.format("Build finished method triggered for %s", getBuildId(build)));
super.buildFinished(build);
buildFinishedOrInterrupted(build);
}
} catch (Exception e) {
LOG.error("Exception in buildFinished caused by: " + e.getMessage(), e);
}
}

@Override
public void buildInterrupted(@NotNull SRunningBuild build) {
try (var ignored1 = CloseableThreadContext.put("teamcity.build.id", String.valueOf(build.getBuildId()))) {
LOG.debug(String.format("Build interrupted method triggered for %s", getBuildId(build)));
super.buildInterrupted(build);
buildFinishedOrInterrupted(build);
try {
try (var ignored1 = CloseableThreadContext.put("teamcity.build.id", String.valueOf(build.getBuildId()))) {
LOG.debug(String.format("Build interrupted method triggered for %s", getBuildId(build)));
super.buildInterrupted(build);
buildFinishedOrInterrupted(build);
}
} catch (Exception e) {
LOG.error("Exception in buildInterrupted caused by: " + e.getMessage(), e);
}
}

Expand Down Expand Up @@ -340,11 +352,20 @@ private void createBlockMessageSpan(BlockLogMessage blockLogMessage, Span buildS
if (parentBlockMessage.getBlockType().equals(DefaultMessagesInfo.BLOCK_TYPE_BUILD)) {
parentSpan = buildSpan;
} else {
parentSpan = blockMessageSpanMap.get(parentBlockMessage.getText() + " " + parentBlockMessage.getFinishDate());
var parentBlockMessageKey = parentBlockMessage.getText() + " " + parentBlockMessage.getFinishDate();
parentSpan = blockMessageSpanMap.get(parentBlockMessageKey);
if (parentSpan == null) {
LOG.warn("Attempted to find span in map using key '" + parentBlockMessageKey + "', but it was not found; using buildspan instead");
parentSpan = buildSpan;
}
}
} else {
parentSpan = buildSpan;
}
if (parentSpan == null) {
LOG.error("Parent span is null; not creating block message spans for '" + blockMessageStepName + "'");
return;
}
var otelHelper = otelHelperFactory.getOTELHelper(getRootBuildInChain(build));
Span childSpan = otelHelper.createTransientSpan(blockMessageStepName, parentSpan, blockLogMessage.getTimestamp().getTime());
otelHelper.addAttributeToSpan(childSpan, PluginConstants.ATTRIBUTE_BUILD_STEP_STATUS, blockLogMessage.getStatus());
Expand Down

0 comments on commit 6ffc8f6

Please sign in to comment.