Skip to content

feat: OpenTelemetry standard attributes#4456

Open
pablocarle wants to merge 44 commits intov3.x.xfrom
reboot/feat/otel-standard
Open

feat: OpenTelemetry standard attributes#4456
pablocarle wants to merge 44 commits intov3.x.xfrom
reboot/feat/otel-standard

Conversation

@pablocarle
Copy link
Contributor

@pablocarle pablocarle commented Jan 16, 2026

Description

Implementation of required / additional / recommended properties for base signals from APIML OpenTelemetry implementation with defaults.

Linked to # (issue)
Part of the # (epic)

Type of change

  • feat: New feature (non-breaking change which adds functionality)

Checklist:

  • My code follows the style guidelines of this project
  • PR title conforms to commit message guideline ## Commit Message Structure Guideline
  • I have commented my code, particularly in hard-to-understand areas. In JS I did provide JSDoc
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • The java tests in the area I was working on leverage @nested annotations
  • Any dependent changes have been merged and published in downstream modules

Pablo Carle added 8 commits January 16, 2026 16:57
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
@EvaJavornicka EvaJavornicka moved this from New to In Progress in API Mediation Layer Backlog Management Jan 21, 2026
…andard

Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
pablocarle

This comment was marked as off-topic.

pablocarle and others added 9 commits January 22, 2026 14:19
Signed-off-by: Richard Salac <richard.salac@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
wip
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
…andard

Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
pablocarle and others added 6 commits January 27, 2026 15:06
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
@pablocarle pablocarle marked this pull request as ready for review January 28, 2026 09:39
Comment on lines +81 to +86
assertEquals("zos", attributes.get(stringKey("os.type")));
assertEquals("STC1111", attributes.get(stringKey("process.zos.jobid")));
assertEquals("ZWE1AG", attributes.get(stringKey("process.zos.jobname")));
assertEquals("gateway", attributes.get(stringKey("service.name")));
assertEquals("apiml:apiml1:40985", attributes.get(stringKey("service.namespace")));
assertNotNull(attributes.get(stringKey("service.version")));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The os.name is set before but not validated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean? This validates the attributes we set, os.name is part of the default implementation. If we want to test those I'd add them to the default integration test, otherwise we'd be testing a feature of the core library

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On line 60 the os.name is set in the static initializer (and then again in BeforeAll on line 68), and populated to resource attributes on line 123. But never asserted. Hence you assert os.type. I thought this is to test overrides - what happens if we set a property automatically discovered by the OpenTelemetry SDK

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

os.name is set simply to force the use of the Zos spring bean. In this case sure, I can set any otel. resource property and assert it. I'll add one or two to cover for it, but we are basically using Spring's default for those

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are absolutely right and I missed that it is set to trigger the z/os attributes provider.

}

public Map<String, Object> get() {
return Map.of(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we somehow get the address space id?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not with this interface, needs research

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any progress? Does maybe launcher provides it? If not just leave a note it and close the conversation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really, I don't see in the launcher code that refers to the address space ID. It's only using USS environment variables to control some address space related things.
We should create a work item to follow up on this if we deem it important.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

Pablo Carle added 4 commits February 3, 2026 09:36
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
Pablo Carle added 2 commits February 4, 2026 10:08
Signed-off-by: Pablo Carle <pablo.carle@broadcom.com>
@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 4, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
47.5% Coverage on New Code (required ≥ 80%)
23.8% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

}

public Map<String, Object> get() {
return Map.of(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any progress? Does maybe launcher provides it? If not just leave a note it and close the conversation

private String generateServiceNamespace(Map<String,Object> zosAttributes) {
return "apiml:" + generateServiceName(zosAttributes);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it makes sense when it is only service name with a prefix. Then it has no additional value over the service name in therm of identifying the installation.

Optional.ofNullable(zosAttributes.get(ZOS_USER_ID)).map(String::valueOf)
.ifPresent(zosUserId -> attributesBuilder.put("process.zos.userid", zosUserId));

return attributesBuilder.build();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I got the impression that you prefer the lpar+port over the uuid.

private final ZosSystemInformation zosSystemInformation;

@Value("${otel.resource.attributes.deployment.environment.name:#{null}}")
private String environmentName;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should remove it form here.

Comment on lines +119 to +122
Optional.ofNullable(zosAttributes.get(ZOS_JOB_ID))
.map(String::valueOf)
.filter(StringUtils::isNotBlank)
.ifPresent(zosJobId -> attributesBuilder.put(ZosAttributes.ZOS_JOBID, zosJobId));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constant naming is confusing: ZOS_JOB_ID vs ZOS_JOBID
and similarly for some others

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can rename them, but they are different values anyway, one is zos.jobid from the system information and the other one is process.zos.jobid for the target OpenTelemetry attribute

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is confusing, as you say they mean something totally different and yet named so similarly. Maybe "OTEL_ZOS_JOBNAME" or "OtelZosAttributes.ZOS_JOBNAME"?

Comment on lines +92 to +117
if (StringUtils.isBlank(sysplexName)) {
var sysplexName = zosAttributes.get(ZOS_SYSPLEX);
if (sysplexName != null && StringUtils.isNotBlank(sysplexName.toString())) {
log.debug("zos.sysplex.name not provided in configuration, using system-obtained {}", sysplexName);
} else {
log.debug("zos.sysplex.name not provided in configuration. Could not determine name from system");
}
}

if (StringUtils.isBlank(lparName)) {
var lparName = zosAttributes.get(ZOS_SYSNAME);
if (lparName != null && StringUtils.isNotBlank(lparName.toString())) {
log.debug("mainframe.lpar.name not provided in configuration, using system-obtained {}", lparName);
} else {
log.debug("mainframe.lpar.name not provided in configuration. Could not determine name from system");
}
}

if (StringUtils.isBlank(smfId)) {
var smfId = zosAttributes.get(ZOS_SYSCLONE);
if (smfId != null && StringUtils.isNotBlank(smfId.toString())) {
log.debug("zos.smf.id not provided in configuration, using system-obtained {}", smfId);
} else {
log.debug("zos.smf.id not provided in configuration. Could not determine ID from system");
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are checked for value but never set to the attributes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added these only to show in the logs if such overrides are happening, if there's no value in the logs we can remove it. We don't need to explicitly set them because they are otel.* properties which are automatically picked up by OpenTelemetry implementation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regardless it is configured or discovered, they are not set in resource attributes and are not present in the exported data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

2 participants