Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion exporters/otlp/common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ wire {
"opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest",
"opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest",
"opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest",
"opentelemetry.proto.collector.profiles.v1development.ExportProfilesServiceRequest"
"opentelemetry.proto.collector.profiles.v1development.ExportProfilesServiceRequest",
"opentelemetry.proto.processcontext.v1development.ProcessContext"
)

custom {
Expand Down
79 changes: 79 additions & 0 deletions sdk/processcontext/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
plugins {
id("otel.java-conventions")
// id("otel.publish-conventions")

// id("otel.animalsniffer-conventions")
}

description = "OpenTelemetry - ProcessContext SDK"
otelJava.moduleName.set("sdk.processcontext")

dependencies {
api(project(":sdk:common"))
api(project(":exporters:common")) // MessageWriter

annotationProcessor("com.google.auto.value:auto-value")

implementation(project(":exporters:otlp:common"))

testImplementation(project(":sdk:testing"))
testImplementation("io.opentelemetry.proto:opentelemetry-proto")
testImplementation("com.google.protobuf:protobuf-java-util")
}

java {
sourceSets {
create("Java25") {
java {
srcDir("src/main/java25")
}
compileClasspath += sourceSets.main.get().output + sourceSets.main.get().compileClasspath
}
}
toolchain {
languageVersion.set(JavaLanguageVersion.of(25))
}
}

tasks.named<JavaCompile>("compileJava") {
options.release.set(8)
}

tasks.named<JavaCompile>("compileJava25Java") {
options.release.set(25)
}

testing {
sourceSets {
create("Java25Test") {
java {
srcDir("src/test/java25")
}
compileClasspath += sourceSets.test.get().output + sourceSets.test.get().compileClasspath
compileClasspath += sourceSets.main.get().output + sourceSets["Java25"].output
}
}
}

tasks.named<JavaCompile>("compileJava") {
options.release.set(8)
}

tasks.named<JavaCompile>("compileJava25TestJava") {
options.release.set(25)
}

// only test on java 25+
val testJavaVersion = project.findProperty("testJavaVersion") as String?
tasks.test {
enabled = (testJavaVersion != null && Integer.valueOf(testJavaVersion) >= 25)
}

tasks.named<Jar>("jar") {
manifest {
attributes["Multi-Release"] = "true"
}
from(sourceSets.named("Java25").get().output) {
into("META-INF/versions/25")
}
}
1 change: 1 addition & 0 deletions sdk/processcontext/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
otel.release=alpha
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.processcontext;

import io.opentelemetry.sdk.common.Clock;
import io.opentelemetry.sdk.processcontext.data.ProcessContextData;

final class NoopProcessContextPublisher implements ProcessContextPublisher {

@Override
public void publish(ProcessContextData processContextData, Clock clock) {}

@Override
public void close() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.processcontext;

import io.opentelemetry.exporter.internal.marshal.MarshalerUtil;
import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize;
import io.opentelemetry.exporter.internal.marshal.Serializer;
import io.opentelemetry.exporter.internal.otlp.KeyValueMarshaler;
import io.opentelemetry.exporter.internal.otlp.ResourceMarshaler;
import io.opentelemetry.proto.processcontext.v1development.internal.ProcessContext;
import io.opentelemetry.sdk.processcontext.data.ProcessContextData;
import java.io.IOException;

final class ProcessContextMarshaler extends MarshalerWithSize {

private final ResourceMarshaler resourceMarshaler;
private final KeyValueMarshaler[] attributeMarshalers;

static ProcessContextMarshaler create(ProcessContextData processContextData) {
KeyValueMarshaler[] attributeMarshalers =
KeyValueMarshaler.createForAttributes(processContextData.getAttributes());
return new ProcessContextMarshaler(
ResourceMarshaler.create(processContextData.getResource()), attributeMarshalers);
}

private ProcessContextMarshaler(
ResourceMarshaler resourceMarshaler, KeyValueMarshaler[] attributeMarshalers) {
super(calculateSize(resourceMarshaler, attributeMarshalers));
this.resourceMarshaler = resourceMarshaler;
this.attributeMarshalers = attributeMarshalers;
}

@Override
protected void writeTo(Serializer output) throws IOException {
output.serializeMessage(ProcessContext.RESOURCE, resourceMarshaler);
output.serializeRepeatedMessage(ProcessContext.ATTRIBUTES, attributeMarshalers);
}

private static int calculateSize(
ResourceMarshaler resourceMarshaler, KeyValueMarshaler[] attributeMarshalers) {
int size = 0;
size += MarshalerUtil.sizeMessage(ProcessContext.RESOURCE, resourceMarshaler);
size += MarshalerUtil.sizeRepeatedMessage(ProcessContext.ATTRIBUTES, attributeMarshalers);
return size;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.processcontext;

import io.opentelemetry.sdk.common.Clock;
import io.opentelemetry.sdk.processcontext.data.ProcessContextData;
import java.io.IOException;

/**
* Exposes process context information to external readers using the shared memory mechanism
* specified in OTEP-4719.
*
* @see <a
* href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/oteps/profiles/4719-process-ctx.md">OTEP
* 4719</a>
*/
public interface ProcessContextPublisher extends AutoCloseable {

/**
* Called to publish a {@code ProcessContextData}s.
*
* @param processContextData the process Resource descriptor and optional additional metadata.
* @param clock the time source for the publication.
*/
void publish(ProcessContextData processContextData, Clock clock) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.processcontext;

import java.util.logging.Logger;

public class ProcessContextPublisherFactory {

private static final Logger logger =
Logger.getLogger(ProcessContextPublisherFactory.class.getName());

private static final ProcessContextPublisherFactory INSTANCE =
new ProcessContextPublisherFactory();

// effectively a singleton, via the factory INSTANCE - java won't do direct interface type
// singletons :-(
private final ProcessContextPublisher processContextPublisher;

private ProcessContextPublisherFactory() {

ProcessContextPublisher tmp = new NoopProcessContextPublisher();

// The publisher uses linux specific syscalls via panama FFM, requiring a sufficiently recent
// JDK.
boolean available =
System.getProperty("os.name").equalsIgnoreCase("Linux")
&& Integer.parseInt(System.getProperty("java.specification.version")) >= 25;

// off by default until it's considered stable.
boolean enabled =
System.getProperty("otel.processcontext.publish", "false").equalsIgnoreCase("true");

if (available && enabled) {
try {
tmp =
(ProcessContextPublisher)
Class.forName("io.opentelemetry.sdk.processcontext.PanamaProcessContextPublisher")
.getConstructors()[0]
.newInstance((Object[]) null);
} catch (Exception e) {
logger.warning("Failed to init ProcessContextPublisher: " + e.getMessage());
}
}

processContextPublisher = tmp;
}

public static ProcessContextPublisherFactory getInstance() {
return INSTANCE;
}

public ProcessContextPublisher create() {
return processContextPublisher;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.processcontext.data;

import com.google.auto.value.AutoValue;
import javax.annotation.concurrent.Immutable;

/**
* Auto value implementation of {@link ProcessContextData}, which describes a process context.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
@Immutable
@AutoValue
abstract class ImmutableProcessContextData implements ProcessContextData {

ImmutableProcessContextData() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.processcontext.data;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.resources.Resource;
import javax.annotation.concurrent.Immutable;

/**
* Describes a ProcessContext.
*
* @see <a
* href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/oteps/profiles/4719-process-ctx.md#payload-format">
* OTEP-4719 Process Context : Payload</a>
*/
@Immutable
public interface ProcessContextData {

/**
* Returns a new ProcessContextData encapsulating the given Resource and supplemental Attributes.
*
* @return a new ProcessContextData.
*/
@SuppressWarnings("AutoValueSubclassLeaked")
static ProcessContextData create(Resource resource, Attributes attributes) {
return new AutoValue_ImmutableProcessContextData(resource, attributes);
}

/** Returns the resource of this process. */
Resource getResource();

/** Additional attributes that are not part of the Resource. */
Attributes getAttributes();
Comment thread
jhalliday marked this conversation as resolved.
}
Loading
Loading