Skip to content
Merged
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
18 changes: 16 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@

Changes by Version
==================
Release Notes.

8.10.0
------------------

* [Important] Namespace represents a subnet, such as kubernetes namespace, or 172.10.*.*. Make namespace concept as a
part of service naming format.
* [Important] Add cluster concept, also as a part of service naming format. The cluster name would be
1. Add as {@link #SERVICE_NAME} suffix.
2. Add as exit span's peer, ${CLUSTER} / original peer
3. Cross Process Propagation Header's value addressUsedAtClient[index=8] (Target address of this request used on the
client end).
* Support Undertow thread pool metrics collecting.
* Support Tomcat thread pool metric collect.
* Remove plugin for ServiceComb Java Chassis 0.x
Expand All @@ -21,10 +28,17 @@ Release Notes.
* Renamed graphql-12.x-plugin to graphql-12.x-15.x-plugin and graphql-12.x-scenario to graphql-12.x-15.x-scenario.
* Add graphql-16plus plugin.
* [Test] Support to configure plugin test base images.
* [Breaking Change] Remove deprecated `agent.instance_properties` configuration.
Recommend `agent.instance_properties_json`.
* The namespace and cluster would be reported as instance properties, keys are `namespace` and `cluster`. Notice, if
instance_properties_json includes these two keys, they would be overrided by the agent core.
* [Breaking Change] Remove the namespace from `cross process propagation` key.

#### Documentation
* Add link about java agent injector.

* Add link about java agent injector.
* Update configurations doc, remove `agent.instance_properties[key]=value`.
* Update configurations doc, add `agent.cluster` and update `agent.namespace`.

All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/120?closed=1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
package org.apache.skywalking.apm.agent.core.conf;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.apache.skywalking.apm.agent.core.logging.core.LogLevel;
import org.apache.skywalking.apm.agent.core.logging.core.LogOutput;
Expand All @@ -37,17 +35,46 @@ public class Config {

public static class Agent {
/**
* Namespace isolates headers in cross process propagation. The HEADER name will be `HeaderName:Namespace`.
* Namespace represents a subnet, such as kubernetes namespace, or 172.10.*.*.
*
* @since 8.10.0 namespace would be added as {@link #SERVICE_NAME} suffix.
*
* Removed namespace isolating headers in cross process propagation. The HEADER name was
* `HeaderName:Namespace`.
*/
@Length(20)
public static String NAMESPACE = "";

/**
* Service name is showed in skywalking-ui. Suggestion: set a unique name for each service, service instance
* nodes share the same code
* Service name is showed on the UI. Suggestion: set a unique name for each service, service instance nodes
* share the same code
*
* @since 8.10.0 ${service name} = [${group name}::]${logic name}|${NAMESPACE}|${CLUSTER}
*
* The group name, namespace and cluster are optional. Once they are all blank, service name would be the final
* name.
*/
@Length(50)
public static String SERVICE_NAME = "";

/**
* Cluster defines the physical cluster in a data center or same network segment. In one cluster, IP address
* should be unique identify.
*
* The cluster name would be
*
* 1. Add as {@link #SERVICE_NAME} suffix.
*
* 2. Add as exit span's peer, ${CLUSTER} / original peer
*
* 3. Cross Process Propagation Header's value addressUsedAtClient[index=8] (Target address of this request used
* on the client end).
*
* @since 8.10.0
*/
@Length(20)
public static String CLUSTER = "";

/**
* Authentication active is based on backend setting, see application.yml for more details. For most scenarios,
* this needs backend extensions, only basic match auth provided in default implementation.
Expand All @@ -61,8 +88,8 @@ public static class Agent {
public static int SAMPLE_N_PER_3_SECS = -1;

/**
* If the operation name of the first span is included in this set, this segment should be ignored.
* Multiple values should be separated by `,`.
* If the operation name of the first span is included in this set, this segment should be ignored. Multiple
* values should be separated by `,`.
*/
public static String IGNORE_SUFFIX = ".jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg";

Expand Down Expand Up @@ -103,16 +130,8 @@ public static class Agent {
public volatile static String INSTANCE_NAME = "";

/**
* service instance properties e.g. agent.instance_properties[org]=apache
* Notice it will be overridden by `agent.instance_properties_json `, if the key duplication.
* For example: <code>e.g. agent.instance_properties_json = {"org": "apache-skywalking"}</code>
*/
@Deprecated
public static Map<String, String> INSTANCE_PROPERTIES = new HashMap<>();

/**
* service instance properties in json format.
* e.g. agent.instance_properties_json = {"org": "apache-skywalking"}
* service instance properties in json format. e.g. agent.instance_properties_json = {"org":
* "apache-skywalking"}
*/
public static String INSTANCE_PROPERTIES_JSON = "";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ public class Constants {
public static String LINE_SEPARATOR = System.getProperty("line.separator", "\n");

public static String EMPTY_STRING = "";

public static char SERVICE_NAME_PART_CONNECTOR = '|';
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import org.apache.skywalking.apm.util.PropertyPlaceholderHelper;
import org.apache.skywalking.apm.util.StringUtil;

import static org.apache.skywalking.apm.agent.core.conf.Constants.SERVICE_NAME_PART_CONNECTOR;

/**
* The <code>SnifferConfigInitializer</code> initializes all configs in several way.
*/
Expand Down Expand Up @@ -98,6 +100,15 @@ public static void initializeCoreConfig(String agentOptions) {

if (StringUtil.isEmpty(Config.Agent.SERVICE_NAME)) {
throw new ExceptionInInitializerError("`agent.service_name` is missing.");
} else {
if (StringUtil.isNotEmpty(Config.Agent.NAMESPACE) || StringUtil.isNotEmpty(Config.Agent.CLUSTER)) {
Config.Agent.SERVICE_NAME = StringUtil.join(
SERVICE_NAME_PART_CONNECTOR,
Config.Agent.SERVICE_NAME,
Config.Agent.NAMESPACE,
Config.Agent.CLUSTER
);
}
}
if (StringUtil.isEmpty(Config.Collector.BACKEND_SERVICE)) {
throw new ExceptionInInitializerError("`collector.backend_service` is missing.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@
package org.apache.skywalking.apm.agent.core.context;

import java.util.Iterator;
import org.apache.skywalking.apm.util.StringUtil;

import static org.apache.skywalking.apm.agent.core.conf.Config.Agent.NAMESPACE;

public class CarrierItem implements Iterator<CarrierItem> {
private String headKey;
Expand All @@ -33,11 +30,7 @@ public CarrierItem(String headKey, String headValue) {
}

public CarrierItem(String headKey, String headValue, CarrierItem next) {
if (StringUtil.isEmpty(NAMESPACE)) {
this.headKey = headKey;
} else {
this.headKey = NAMESPACE + "-" + headKey;
}
this.headKey = headKey;
this.headValue = headValue;
this.next = next;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
import org.apache.skywalking.apm.agent.core.profile.ProfileTaskExecutionService;
import org.apache.skywalking.apm.util.StringUtil;

import static org.apache.skywalking.apm.agent.core.conf.Config.Agent.CLUSTER;

/**
* The <code>TracingContext</code> represents a core tracing logic controller. It build the final {@link
* TracingContext}, by the stack mechanism, which is similar with the codes work.
Expand Down Expand Up @@ -322,7 +324,7 @@ public AbstractSpan createLocalSpan(final String operationName) {
* @see ExitSpan
*/
@Override
public AbstractSpan createExitSpan(final String operationName, final String remotePeer) {
public AbstractSpan createExitSpan(final String operationName, String remotePeer) {
if (isLimitMechanismWorking()) {
NoopExitSpan span = new NoopExitSpan(remotePeer);
return push(span);
Expand All @@ -334,6 +336,8 @@ public AbstractSpan createExitSpan(final String operationName, final String remo
if (parentSpan != null && parentSpan.isExit()) {
exitSpan = parentSpan;
} else {
// Since 8.10.0
remotePeer = StringUtil.isEmpty(CLUSTER) ? remotePeer : CLUSTER + "/" + remotePeer;
final int parentSpanId = parentSpan == null ? -1 : parentSpan.getSpanId();
exitSpan = new ExitSpan(spanIdGenerator++, parentSpanId, operationName, remotePeer, owner);
push(exitSpan);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,18 @@ public static List<KeyStringValuePair> parseProperties() {
List<KeyStringValuePair> properties = new ArrayList<>();

if (StringUtil.isNotEmpty(Config.Agent.INSTANCE_PROPERTIES_JSON)) {
Config.Agent.INSTANCE_PROPERTIES.putAll(
GSON.fromJson(
Config.Agent.INSTANCE_PROPERTIES_JSON,
new TypeToken<Map<String, Object>>() {
}.getType()
));
Map<String, String> json = GSON.fromJson(
Config.Agent.INSTANCE_PROPERTIES_JSON,
new TypeToken<Map<String, String>>() {
}.getType()
);
json.forEach(
(key, val) -> properties.add(KeyStringValuePair.newBuilder().setKey(key).setValue(val).build()));
}

Config.Agent.INSTANCE_PROPERTIES.forEach((key, val) -> properties.add(KeyStringValuePair.newBuilder()
.setKey(key)
.setValue(val)
.build()));
properties.add(KeyStringValuePair.newBuilder().setKey("namespace").setValue(Config.Agent.NAMESPACE).build());
properties.add(KeyStringValuePair.newBuilder().setKey("cluster").setValue(Config.Agent.NAMESPACE).build());

return properties;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

package org.apache.skywalking.apm.agent.core.conf;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
Expand All @@ -40,8 +42,12 @@ public class SnifferConfigInitializerTest {
* variables are reverted after the test.
*/
@Rule
public final EnvironmentVariables environmentVariables = new EnvironmentVariables().set("AGENT_SERVICE_NAME", "testAppFromSystemEnv")
.set("AGENT_COLLECTOR_SERVER", "localhost:11111");
public final EnvironmentVariables environmentVariables = new EnvironmentVariables().set(
"AGENT_SERVICE_NAME", "testAppFromSystemEnv")
.set(
"AGENT_COLLECTOR_SERVER",
"localhost:11111"
);

@Test
public void testLoadConfigFromJavaAgentDir() throws AgentPackageNotFoundException, ConfigNotFoundException {
Expand All @@ -66,16 +72,21 @@ public void testLoadConfigFromAgentOptions() throws AgentPackageNotFoundExceptio
@Test
public void testConfigOverriding() throws AgentPackageNotFoundException, ConfigNotFoundException {
System.setProperty("skywalking.agent.service_name", "testAppFromSystem");
System.setProperty("skywalking.agent.instance_properties[key1]", "value1");
System.setProperty("skywalking.agent.instance_properties_json", "{\"key1\": \"value1\", \"key2\": \"value2\"}");
System.setProperty("skywalking.agent.instance_properties[key2]", "value2");
System.setProperty("skywalking.collector.backend_service", "127.0.0.1:8090");
String agentOptions = "agent.service_name=testAppFromAgentOptions,logging.level=debug";
SnifferConfigInitializer.initializeCoreConfig(agentOptions);
assertThat(Config.Agent.SERVICE_NAME, is("testAppFromAgentOptions"));
assertThat(Config.Collector.BACKEND_SERVICE, is("127.0.0.1:8090"));
assertThat(Config.Logging.LEVEL, is(LogLevel.DEBUG));
assertThat(Config.Agent.INSTANCE_PROPERTIES.get("key1"), is("value1"));
assertThat(Config.Agent.INSTANCE_PROPERTIES.get("key2"), is("value2"));
Map<String, String> json = new Gson().fromJson(
Config.Agent.INSTANCE_PROPERTIES_JSON,
new TypeToken<Map<String, String>>() {
}.getType()
);
assertThat(json.get("key1"), is("value1"));
assertThat(json.get("key2"), is("value2"));
}

@Test
Expand All @@ -85,8 +96,14 @@ public void testConfigOverridingFromSystemEnv() throws IllegalAccessException {
properties.put("collector.backend_service", "${AGENT_COLLECTOR_SERVER:127.0.0.1:8090}");
properties.put("logging.level", "INFO");
PropertyPlaceholderHelper placeholderHelper = PropertyPlaceholderHelper.INSTANCE;
properties.put("agent.service_name", placeholderHelper.replacePlaceholders((String) properties.get("agent.service_name"), properties));
properties.put("collector.backend_service", placeholderHelper.replacePlaceholders((String) properties.get("collector.backend_service"), properties));
properties.put(
"agent.service_name",
placeholderHelper.replacePlaceholders((String) properties.get("agent.service_name"), properties)
);
properties.put(
"collector.backend_service",
placeholderHelper.replacePlaceholders((String) properties.get("collector.backend_service"), properties)
);
ConfigInitializer.initialize(properties, Config.class);
assertThat(Config.Agent.SERVICE_NAME, is("testAppFromSystemEnv"));
assertThat(Config.Collector.BACKEND_SERVICE, is("localhost:11111"));
Expand Down
10 changes: 8 additions & 2 deletions apm-sniffer/config/agent.config
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# The service name in UI
# ${service name} = [${group name}::]${logic name}
# The group name is optional only.
agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}

# The agent namespace
agent.namespace=${SW_AGENT_NAMESPACE:}

# The service name in UI
agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}
# The agent cluster
agent.cluster=${SW_AGENT_CLUSTER:}

# The number of sampled traces per 3 seconds
# Negative or zero means off, by default
Expand Down Expand Up @@ -54,6 +59,7 @@ agent.class_cache_mode=${SW_AGENT_CLASS_CACHE_MODE:MEMORY}
# generate an 32-bit uuid. BY Default, SkyWalking uses UUID@hostname as the instance name. Max length is 50(UTF-8 char)
agent.instance_name=${SW_AGENT_INSTANCE_NAME:}

# service instance properties in json format. e.g. agent.instance_properties_json = {"org": "apache-skywalking"}
agent.instance_properties_json=${SW_INSTANCE_PROPERTIES_JSON:}

# How depth the agent goes, when log all cause exceptions.
Expand Down
Loading