Put `Agent-Version` property reading in premain stage to avoid deadlock when use `jarsigner`. (#437)

This commit is contained in:
codePig 2023-01-06 19:08:41 +08:00 committed by GitHub
parent 3ff8c23d0a
commit 9d03d56778
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 37 deletions

View File

@ -23,7 +23,7 @@ Release Notes.
* Add support for KafkaClients 3.x.
* Support to customize the collect period of JVM relative metrics.
* Upgrade netty-codec-http2 to 4.1.86.Final.
* Move `Agent-Version` property reading away from the class loading stage to avoid deadlock when use `jarsigner`.
* Put `Agent-Version` property reading in the premain stage to avoid deadlock when using `jarsigner`.
#### Documentation

View File

@ -178,6 +178,11 @@ public class Config {
* Private key file. If ssl_cert_chain and ssl_key exist, will enable mTLS for gRPC channel.
*/
public static String SSL_KEY_PATH;
/**
* Agent version. This is set by the agent kernel through reading MANIFEST.MF file in the skywalking-agent.jar.
*/
public static String VERSION = "UNKNOWN";
}
public static class OsInfo {

View File

@ -23,11 +23,16 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Enumeration;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
import org.apache.skywalking.apm.agent.core.boot.AgentPackagePath;
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
@ -98,6 +103,8 @@ public class SnifferConfigInitializer {
configureLogger();
LOGGER = LogManager.getLogger(SnifferConfigInitializer.class);
setAgentVersion();
if (StringUtil.isEmpty(Config.Agent.SERVICE_NAME)) {
throw new ExceptionInInitializerError("`agent.service_name` is missing.");
} else {
@ -202,6 +209,34 @@ public class SnifferConfigInitializer {
}
}
/**
* Set agent version(Described in MANIFEST.MF)
*/
private static void setAgentVersion() {
try {
Enumeration<URL> resources = SnifferConfigInitializer.class.getClassLoader().getResources(JarFile.MANIFEST_NAME);
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
LOGGER.info("SnifferConfigInitializer url:{}", url.toString());
try (InputStream is = url.openStream()) {
if (is != null) {
Manifest manifest = new Manifest(is);
Attributes mainAttribs = manifest.getMainAttributes();
String projectName = mainAttribs.getValue("Implementation-Vendor-Id");
if (projectName != null) {
if ("org.apache.skywalking".equals(projectName)) {
Config.Agent.VERSION = mainAttribs.getValue("Implementation-Version");
break;
}
}
}
}
}
} catch (Exception e) {
LOGGER.warn("Can't read version from MANIFEST.MF in the agent jar");
}
}
/**
* Load the specified config file or default config file
*

View File

@ -26,46 +26,14 @@ import io.grpc.ClientInterceptors;
import io.grpc.ForwardingClientCall;
import io.grpc.Metadata;
import io.grpc.MethodDescriptor;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
import org.apache.skywalking.apm.agent.core.conf.Config;
/**
* Add agent version(Described in MANIFEST.MF) to the connection establish stage.
*/
public class AgentIDDecorator implements ChannelDecorator {
private static final ILog LOGGER = LogManager.getLogger(AgentIDDecorator.class);
private static Metadata.Key<String> AGENT_VERSION_HEAD_HEADER_NAME;
private String version = "UNKNOWN";
public AgentIDDecorator() {
try {
Enumeration<URL> resources = AgentIDDecorator.class.getClassLoader().getResources(JarFile.MANIFEST_NAME);
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
try (InputStream is = url.openStream()) {
if (is != null) {
Manifest manifest = new Manifest(is);
Attributes mainAttribs = manifest.getMainAttributes();
String projectName = mainAttribs.getValue("Implementation-Vendor-Id");
if (projectName != null) {
if ("org.apache.skywalking".equals(projectName)) {
version = mainAttribs.getValue("Implementation-Version");
}
}
}
}
}
AGENT_VERSION_HEAD_HEADER_NAME = Metadata.Key.of("Agent-Version", Metadata.ASCII_STRING_MARSHALLER);
} catch (Exception e) {
LOGGER.warn("Can't read version from MANIFEST.MF in the agent jar");
}
}
private static final Metadata.Key<String> AGENT_VERSION_HEAD_HEADER_NAME = Metadata.Key.of("Agent-Version", Metadata.ASCII_STRING_MARSHALLER);
@Override
public Channel build(Channel channel) {
@ -76,7 +44,7 @@ public class AgentIDDecorator implements ChannelDecorator {
return new ForwardingClientCall.SimpleForwardingClientCall<REQ, RESP>(channel.newCall(method, options)) {
@Override
public void start(Listener<RESP> responseListener, Metadata headers) {
headers.put(AGENT_VERSION_HEAD_HEADER_NAME, version);
headers.put(AGENT_VERSION_HEAD_HEADER_NAME, Config.Agent.VERSION);
super.start(responseListener, headers);
}