Skip to content

Commit

Permalink
Merge pull request #735 from gunlee01/feature/spring-reactive-coroutine
Browse files Browse the repository at this point in the history
Feature/spring reactive coroutine
  • Loading branch information
gunlee01 authored Aug 18, 2020
2 parents 3b63aa3 + fe2a143 commit d225bdd
Show file tree
Hide file tree
Showing 69 changed files with 4,306 additions and 361 deletions.
54 changes: 52 additions & 2 deletions scouter.agent.java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@
<include name="scouter/xtra/redis/*.class" />
</fileset>
</jar>
<jar destfile="${project.build.directory}/${scouter.reactive.jar}">
<fileset dir="${project.build.outputDirectory}">
<include name="scouter/xtra/reactive/*.class" />
</fileset>
</jar>
<jar destfile="${project.build.directory}/${scouter.java8.jar}">
<fileset dir="${project.build.outputDirectory}">
<include name="scouter/xtra/java8/*.class" />
</fileset>
</jar>
</target>
</configuration>
<goals>
Expand All @@ -101,6 +111,8 @@
<include name="${scouter.tools.jar}" />
<include name="${scouter.kafka.jar}" />
<include name="${scouter.redis.jar}" />
<include name="${scouter.reactive.jar}" />
<include name="${scouter.java8.jar}" />
</fileset>
<zipfileset src="${final.jar.name}" />

Expand All @@ -121,6 +133,8 @@
<delete file="${project.build.directory}/${scouter.tools.jar}" />
<delete file="${project.build.directory}/${scouter.kafka.jar}" />
<delete file="${project.build.directory}/${scouter.redis.jar}" />
<delete file="${project.build.directory}/${scouter.reactive.jar}" />
<delete file="${project.build.directory}/${scouter.java8.jar}" />

<!-- for constant name file -->
<jar destfile="${project.build.directory}/${scouter.agent.file.name}">
Expand Down Expand Up @@ -206,6 +220,9 @@
<compilerVersion>1.6</compilerVersion>
<source>1.6</source>
<target>1.6</target>
<excludes>
<exclude>**/scouter/xtra/reactive/*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
Expand Down Expand Up @@ -340,6 +357,8 @@
<scouter.tools.jar>scouter.tools.jar</scouter.tools.jar>
<scouter.kafka.jar>scouter.kafka.jar</scouter.kafka.jar>
<scouter.redis.jar>scouter.redis.jar</scouter.redis.jar>
<scouter.reactive.jar>scouter.reactive.jar</scouter.reactive.jar>
<scouter.java8.jar>scouter.java8.jar</scouter.java8.jar>

<provided.tools.jar>${project.basedir}/lib/provided/tools.jar</provided.tools.jar>
<java.net.http.jar>${project.basedir}/lib/provided/java.net.http.jar</java.net.http.jar>
Expand Down Expand Up @@ -423,13 +442,37 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.18.RELEASE</version>
<version>5.2.8.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<version>5.2.8.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>3.3.8.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-reactor</artifactId>
<version>1.3.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>1.3.72</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.19.RELEASE</version>
<version>5.2.8.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand All @@ -438,6 +481,13 @@
<version>0.10.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>6.8.10</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2015 the original author or authors.
* @https://github.com/scouter-project/scouter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package reactor.core.publisher;

/**
* @author Gun Lee ([email protected]) on 2020/08/08
*/
public class ScouterOptimizableOperatorProxy {

public static final String EMPTY = "";

public static String nameOnCheckpoint(Object candidate) {
if (candidate instanceof OptimizableOperator) {
OptimizableOperator<?, ?> operator = ((OptimizableOperator<?, ?>) candidate).nextOptimizableSource();
if (operator == null) {
return EMPTY;
}
if (operator instanceof MonoOnAssembly) {
FluxOnAssembly.AssemblySnapshot snapshot = ((MonoOnAssembly) operator).stacktrace;
if (snapshot != null && snapshot.checkpointed) {
return snapshot.cached;
}
} else if (operator instanceof FluxOnAssembly) {
FluxOnAssembly.AssemblySnapshot snapshot = ((FluxOnAssembly) operator).snapshotStack;
if (snapshot != null && snapshot.checkpointed) {
return snapshot.cached;
}
}
}
return EMPTY;
}

public static void appendSources4Dump(Object candidate, StringBuilder builder) {
if (candidate instanceof OptimizableOperator) {
OptimizableOperator<?, ?> operator = ((OptimizableOperator<?, ?>) candidate).nextOptimizableSource();
if (operator == null) {
return;
}
String p1 = operator.toString();
builder.append(" (<-) ").append(p1);
if (p1.startsWith("checkpoint")) {
OptimizableOperator<?, ?> operator2 = operator.nextOptimizableSource();
if (operator2 != null) {
builder.append(" (<-) ").append(operator2.toString());
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public class AgentCommonConstant {
public static final String REQUEST_ATTRIBUTE_CALLER_TRANSFER_MAP = "__scouter__ctm__";
public static final String REQUEST_ATTRIBUTE_ALL_DISPATCHED_TRACE_CONTEXT = "__scouter__adtc__";
public static final String REQUEST_ATTRIBUTE_SELF_DISPATCHED = "__scouter__sd__";
public static final String TRACE_ID = "__scouter__txid__";
public static final String TRACE_CONTEXT = "__scouter__tctx__";
public static final String SUBS_DEPTH = "__scouter__subdepth__";
public static final String SCOUTER_ADDED_FIELD = "__scouter__added__";

public static final String ASYNC_SERVLET_DISPATCHED_PREFIX = "f>";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@
import scouter.agent.asm.ApicallJavaHttpRequestASM;
import scouter.agent.asm.ApicallSpringHandleResponseASM;
import scouter.agent.asm.ApicallSpringHttpAccessorASM;
import scouter.agent.asm.ApicallWebClientInfoASM;
import scouter.agent.asm.ApicallWebClientResponseASM;
import scouter.agent.asm.CapArgsASM;
import scouter.agent.asm.CapReturnASM;
import scouter.agent.asm.CapThisASM;
import scouter.agent.asm.HttpReactiveServiceASM;
import scouter.agent.asm.HttpServiceASM;
import scouter.agent.asm.IASM;
import scouter.agent.asm.InitialContextASM;
Expand All @@ -53,11 +56,16 @@
import scouter.agent.asm.UserTxASM;
import scouter.agent.asm.asyncsupport.AsyncContextDispatchASM;
import scouter.agent.asm.asyncsupport.CallRunnableASM;
import scouter.agent.asm.asyncsupport.CoroutineThreadNameASM;
import scouter.agent.asm.asyncsupport.HystrixCommandASM;
import scouter.agent.asm.asyncsupport.MonoKtASM;
import scouter.agent.asm.asyncsupport.RequestStartAsyncASM;
import scouter.agent.asm.asyncsupport.ThreadASM;
import scouter.agent.asm.asyncsupport.executor.ExecutorServiceASM;
import scouter.agent.asm.asyncsupport.spring.SpringAsyncExecutionASM;
import scouter.agent.asm.asyncsupport.spring.SpringAsyncExecutionAspectSupportDoSubmitASM;
import scouter.agent.asm.elasticsearch.HttpNioEntityASM;
import scouter.agent.asm.elasticsearch.RestClientASM;
import scouter.agent.asm.kafka.KafkaProducerASM;
import scouter.agent.asm.rabbit.RabbitPublisherASM;
import scouter.agent.asm.redis.JedisCommandASM;
Expand Down Expand Up @@ -103,8 +111,16 @@ public void run() {
public static void reload() {
Configure conf = Configure.getInstance();
List<IASM> temp = new ArrayList<IASM>();
temp.add(new ThreadASM());
temp.add(new HttpServiceASM());
temp.add(new ServiceASM());
temp.add(new HttpReactiveServiceASM());
temp.add(new CoroutineThreadNameASM());
temp.add(new MonoKtASM());
temp.add(new ApicallWebClientInfoASM());
temp.add(new ApicallWebClientResponseASM());
temp.add(new HttpNioEntityASM());
temp.add(new RestClientASM());

temp.add(new RequestStartAsyncASM());
temp.add(new AsyncContextDispatchASM());
Expand Down
30 changes: 30 additions & 0 deletions scouter.agent.java/src/main/java/scouter/agent/Configure.java
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ public static final Configure getInstance() {
@ConfigDesc("")
public boolean profile_fullstack_stmt_leak_enabled = false;

@ConfigDesc("Profile elastic search full query.\nIt need more payload and disk usage.")
public boolean elasticsearch_full_query_enabled = false;

//Trace
@ConfigDesc("User ID based(0 : Remote Address, 1 : Cookie, 2 : Scouter Cookie, 2 : Header) \n - able to set value for 1.Cookie and 3.Header \n - refer to 'trace_user_session_key'")
public int trace_user_mode = 2; // 0:Remote IP, 1:JSessionID, 2:Scouter Cookie, 3:Header
Expand Down Expand Up @@ -332,6 +335,8 @@ public static final Configure getInstance() {
public boolean xlog_error_on_apicall_exception_enabled = true;
@ConfigDesc("mark as error on xlog flag if redis error is occured.")
public boolean xlog_error_on_redis_exception_enabled = true;
@ConfigDesc("mark as error on xlog flag if redis error is occured.")
public boolean xlog_error_on_elasticsearch_exception_enabled = true;

//XLog hard sampling options
@ConfigDesc("XLog hard sampling mode enabled\n - for the best performance but it affects all statistics data")
Expand All @@ -343,6 +348,9 @@ public static final Configure getInstance() {
@ConfigDesc("XLog sampling - ignore global consequent sampling. the commencement service's sampling option affects it's children.")
public boolean ignore_global_consequent_sampling = false;

@ConfigDesc("XLog sampling exclude patterns.")
public String xlog_sampling_exclude_patterns = "";

@ConfigDesc("XLog sampling mode enabled")
public boolean xlog_sampling_enabled = false;
@ConfigDesc("XLog sampling but discard profile only not XLog.")
Expand Down Expand Up @@ -701,7 +709,17 @@ public static final Configure getInstance() {
@ConfigDesc("")
public boolean _hook_kafka_enabled = true;
@ConfigDesc("")
public boolean _hook_elasticsearch_enabled = true;
@ConfigDesc("")
public boolean _hook_rabbit_enabled = true;
@ConfigDesc("")
public boolean _hook_reactive_enabled = true;
@ConfigDesc("")
public boolean _hook_coroutine_enabled = true;
@ConfigDesc("")
public boolean _hook_coroutine_debugger_hook_enabled = false;
@ConfigDesc("")
public boolean _hook_thread_name_enabled = false;

@ConfigDesc("")
public String _hook_direct_patch_classes = "";
Expand Down Expand Up @@ -748,6 +766,7 @@ public static final Configure getInstance() {
public boolean _psts_enabled = false;
@ConfigDesc("PSTS(periodical stacktrace step) thread dump Interval(ms) - hard min limit 2000")
public int _psts_dump_interval_ms = 10000;
public boolean _psts_progressive_reactor_thread_trace_enabled = true;

//Summary
@ConfigDesc("Activating summary function")
Expand Down Expand Up @@ -1056,6 +1075,8 @@ private void apply() {
this.profile_fullstack_rs_leak_enabled = getBoolean("profile_fullstack_rs_leak_enabled", false);
this.profile_fullstack_stmt_leak_enabled = getBoolean("profile_fullstack_stmt_leak_enabled", false);

this.elasticsearch_full_query_enabled = getBoolean("elasticsearch_full_query_enabled", false);

this.net_udp_collection_interval_ms = getInt("net_udp_collection_interval_ms", 100);

this.trace_http_client_ip_header_key = getValue("trace_http_client_ip_header_key", "");
Expand Down Expand Up @@ -1088,7 +1109,12 @@ private void apply() {
this._hook_spring_rest_enabled = getBoolean("_hook_spring_rest_enabled", true);
this._hook_redis_enabled = getBoolean("_hook_redis_enabled", true);
this._hook_kafka_enabled = getBoolean("_hook_kafka_enabled", true);
this._hook_elasticsearch_enabled = getBoolean("_hook_elasticsearch_enabled", true);
this._hook_rabbit_enabled = getBoolean("_hook_rabbit_enabled", true);
this._hook_reactive_enabled = getBoolean("_hook_reactive_enabled", true);
this._hook_coroutine_enabled = getBoolean("_hook_coroutine_enabled", true);
this._hook_coroutine_debugger_hook_enabled = getBoolean("_hook_coroutine_debugger_hook_enabled", false);
this._hook_thread_name_enabled = getBoolean("_hook_thread_name_enabled", false);

this._hook_direct_patch_classes = getValue("_hook_direct_patch_classes", "");

Expand All @@ -1106,6 +1132,7 @@ private void apply() {

this._psts_enabled = getBoolean("_psts_enabled", false);
this._psts_dump_interval_ms = getInt("_psts_dump_interval_ms", 10000);
this._psts_progressive_reactor_thread_trace_enabled = getBoolean("_psts_progressive_reactor_dump_enabled", true);

// 웹시스템으로 부터 WAS 사이의 성능과 어떤 웹서버가 요청을 보내 왔는지를 추적하는 기능을 ON/OFF하고
// 관련 키정보를 지정한다.
Expand Down Expand Up @@ -1153,6 +1180,7 @@ private void apply() {
this.xlog_error_on_sqlexception_enabled = getBoolean("xlog_error_on_sqlexception_enabled", true);
this.xlog_error_on_apicall_exception_enabled = getBoolean("xlog_error_on_apicall_exception_enabled", true);
this.xlog_error_on_redis_exception_enabled = getBoolean("xlog_error_on_redis_exception_enabled", true);
this.xlog_error_on_elasticsearch_exception_enabled = getBoolean("xlog_error_on_elasticsearch_exception_enabled", true);

this._log_asm_enabled = getBoolean("_log_asm_enabled", false);
this.obj_type_inherit_to_child_enabled = getBoolean("obj_type_inherit_to_child_enabled", false);
Expand All @@ -1178,6 +1206,8 @@ private void apply() {

this.ignore_global_consequent_sampling = getBoolean("ignore_global_consequent_sampling", false);

this.xlog_sampling_exclude_patterns = getValue("xlog_sampling_exclude_patterns", "");

this.xlog_sampling_enabled = getBoolean("xlog_sampling_enabled", false);
this.xlog_sampling_only_profile = getBoolean("xlog_sampling_only_profile", false);
this.xlog_sampling_step1_ms = getInt("xlog_sampling_step1_ms", 100);
Expand Down
5 changes: 5 additions & 0 deletions scouter.agent.java/src/main/java/scouter/agent/JavaAgent.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ public class JavaAgent {
}

public static void premain(String options, Instrumentation instrum) {
Configure conf = Configure.getInstance();
if (conf._hook_coroutine_debugger_hook_enabled && System.getProperty("kotlinx.coroutines.debug") == null) {
System.setProperty("kotlinx.coroutines.debug", "");
}
preStart(options, instrum, new AgentTransformer());
}

Expand Down Expand Up @@ -95,6 +99,7 @@ private static void addAsyncRedefineClasses() {

redefineClasses.put("java.util.concurrent.AbstractExecutorService");
redefineClasses.put("java.util.concurrent.ThreadPoolExecutor");
redefineClasses.put("java.lang.Thread");

//java.lang.invoke.LambdaMetafactory.*,java.lang.invoke.CallSite.*,
//java.lang.invoke.ConstantCallSite.*,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@
import scouter.agent.asm.util.HookingSet;

import java.util.Map;

import static scouter.agent.AgentCommonConstant.SCOUTER_ADDED_FIELD;

public class AddFieldASM implements IASM, Opcodes {
public final Map<String, String> target = HookingSet.getClassFieldSet(Configure.getInstance().hook_add_fields);
public AddFieldASM() {
target.put("org/springframework/web/reactive/function/client/DefaultClientRequestBuilder$BodyInserterRequest",
SCOUTER_ADDED_FIELD);
}
Configure conf = Configure.getInstance();
public ClassVisitor transform(ClassVisitor cv, String className, ClassDesc classDesc) {
Expand Down
Loading

0 comments on commit d225bdd

Please sign in to comment.