Skip to content

Commit 6e70dde

Browse files
committed
cxf plugin for client
1 parent 538aa30 commit 6e70dde

File tree

16 files changed

+749
-35
lines changed

16 files changed

+749
-35
lines changed

‎plugins/cxf/.gitignore‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/target/
2+
/.settings/
3+
/.classpath
4+
/.project

‎plugins/cxf/clover.license‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
RMRqrdbgbKFhbaVnDxHUdDQvrOQXxIBklnvcmahheubVC
2+
mh2KM35CLkwUHS4DH7QVhxy52J5hnWbyEm6Cyd3KkF<mV
3+
RmmnSVOqOMnOnMMrmMqwXomoroNrqPNRrPSsWwtUxXuUU
4+
sRONqpnmqmUUnqonmstsmmmmmUUnqonmstsmmmmmUUGfk
5+
mlfkqUUnmmmm

‎plugins/cxf/pom.xml‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<parent>
5+
<groupId>com.navercorp.pinpoint</groupId>
6+
<artifactId>pinpoint</artifactId>
7+
<relativePath>../..</relativePath>
8+
<version>1.6.0-SNAPSHOT</version>
9+
</parent>
10+
11+
<artifactId>pinpoint-cxf-plugin</artifactId>
12+
<name>pinpoint-cxf-plugin</name>
13+
<packaging>jar</packaging>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>com.navercorp.pinpoint</groupId>
18+
<artifactId>pinpoint-bootstrap-core</artifactId>
19+
<scope>provided</scope>
20+
</dependency>
21+
22+
<dependency>
23+
<groupId>org.apache.cxf</groupId>
24+
<artifactId>cxf-rt-frontend-jaxws</artifactId>
25+
<scope>provided</scope>
26+
</dependency>
27+
<dependency>
28+
<groupId>org.apache.cxf</groupId>
29+
<artifactId>cxf-rt-transports-http</artifactId>
30+
<scope>provided</scope>
31+
</dependency>
32+
</dependencies>
33+
34+
</project>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* Copyright 2014 NAVER Corp.
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
package com.navercorp.pinpoint.plugin.cxf;
16+
17+
import java.security.ProtectionDomain;
18+
19+
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass;
20+
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException;
21+
import com.navercorp.pinpoint.bootstrap.instrument.Instrumentor;
22+
import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformCallback;
23+
import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformTemplate;
24+
import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformTemplateAware;
25+
import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin;
26+
import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext;
27+
28+
/**
29+
* @author barney
30+
*
31+
*/
32+
public class CxfPlugin implements ProfilerPlugin, TransformTemplateAware {
33+
34+
private TransformTemplate transformTemplate;
35+
36+
@Override
37+
public void setup(ProfilerPluginSetupContext context) {
38+
CxfPluginConfig config = new CxfPluginConfig(context.getConfig());
39+
40+
if(config.isClientProfile()) {
41+
addCxfClient();
42+
}
43+
44+
}
45+
46+
private void addCxfClient() {
47+
transformTemplate.transform("org.apache.cxf.frontend.ClientProxy", new TransformCallback() {
48+
49+
@Override
50+
public byte[] doInTransform(Instrumentor instrumentor, ClassLoader classLoader, String className,
51+
Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer)
52+
throws InstrumentException {
53+
InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer);
54+
55+
target.getDeclaredMethod("invokeSync", "java.lang.reflect.Method", "org.apache.cxf.service.model.BindingOperationInfo", "java.lang.Object[]")
56+
.addInterceptor("com.navercorp.pinpoint.plugin.cxf.interceptor.CxfClientInvokeSyncMethodInterceptor");
57+
58+
return target.toBytecode();
59+
}
60+
});
61+
}
62+
63+
@Override
64+
public void setTransformTemplate(TransformTemplate transformTemplate) {
65+
this.transformTemplate = transformTemplate;
66+
}
67+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* Copyright 2014 NAVER Corp.
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
package com.navercorp.pinpoint.plugin.cxf;
16+
17+
import java.util.Arrays;
18+
19+
import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig;
20+
21+
/**
22+
* @author barney
23+
*
24+
*/
25+
public class CxfPluginConfig {
26+
27+
private final boolean clientProfile;
28+
29+
private final String[] clientHiddenParams;
30+
31+
public CxfPluginConfig(ProfilerConfig src) {
32+
this.clientProfile = src.readBoolean("profiler.cxf.client", false);
33+
this.clientHiddenParams = getStringArray(src.readString("profiler.cxf.client.hiddenParams", ""));
34+
}
35+
36+
public boolean isClientProfile() {
37+
return clientProfile;
38+
}
39+
40+
public String[] getClientHiddenParams() {
41+
return clientHiddenParams;
42+
}
43+
44+
private String[] getStringArray(String value) {
45+
if (value == null || value.length() <= 0) {
46+
return null;
47+
}
48+
String[] split = value.split(",");
49+
String[] array = new String[split.length];
50+
for (int i = 0; i < split.length; i++) {
51+
array[i] = split[i].trim();
52+
}
53+
return array;
54+
}
55+
56+
@Override
57+
public String toString() {
58+
StringBuilder builder = new StringBuilder();
59+
builder.append("CxfPluginConfig [clientProfile=");
60+
builder.append(clientProfile);
61+
builder.append(", clientHiddenParams=");
62+
builder.append(Arrays.toString(clientHiddenParams));
63+
builder.append("]");
64+
return builder.toString();
65+
}
66+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Copyright 2014 NAVER Corp.
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
package com.navercorp.pinpoint.plugin.cxf;
16+
17+
import com.navercorp.pinpoint.common.trace.AnnotationKey;
18+
import com.navercorp.pinpoint.common.trace.AnnotationKeyFactory;
19+
import com.navercorp.pinpoint.common.trace.AnnotationKeyProperty;
20+
import com.navercorp.pinpoint.common.trace.ServiceType;
21+
import com.navercorp.pinpoint.common.trace.ServiceTypeFactory;
22+
import com.navercorp.pinpoint.common.trace.ServiceTypeProperty;
23+
24+
/**
25+
* @author barney
26+
*
27+
*/
28+
public interface CxfPluginConstants {
29+
30+
ServiceType CXF_CLIENT_SERVICE_TYPE = ServiceTypeFactory.of(9080, "CXF_CLIENT", ServiceTypeProperty.RECORD_STATISTICS);
31+
32+
AnnotationKey CXF_OPERATION = AnnotationKeyFactory.of(200, "cxf.operation", AnnotationKeyProperty.VIEW_IN_RECORD_SET);
33+
AnnotationKey CXF_ARGS = AnnotationKeyFactory.of(201, "cxf.args", AnnotationKeyProperty.VIEW_IN_RECORD_SET);
34+
35+
String CXF_CLIENT_SCOPE = "CxfClientScope";
36+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.navercorp.pinpoint.plugin.cxf;
2+
3+
import com.navercorp.pinpoint.common.trace.TraceMetadataProvider;
4+
import com.navercorp.pinpoint.common.trace.TraceMetadataSetupContext;
5+
6+
public class CxfPluginTraceMetadataProvider implements TraceMetadataProvider {
7+
8+
@Override
9+
public void setup(TraceMetadataSetupContext context) {
10+
context.addServiceType(CxfPluginConstants.CXF_CLIENT_SERVICE_TYPE);
11+
context.addAnnotationKey(CxfPluginConstants.CXF_OPERATION);
12+
context.addAnnotationKey(CxfPluginConstants.CXF_ARGS);
13+
}
14+
15+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/**
2+
* Copyright 2014 NAVER Corp.
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
package com.navercorp.pinpoint.plugin.cxf.interceptor;
16+
17+
import java.util.Arrays;
18+
import java.util.regex.Matcher;
19+
import java.util.regex.Pattern;
20+
21+
import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor;
22+
import com.navercorp.pinpoint.bootstrap.context.SpanEventRecorder;
23+
import com.navercorp.pinpoint.bootstrap.context.Trace;
24+
import com.navercorp.pinpoint.bootstrap.context.TraceContext;
25+
import com.navercorp.pinpoint.bootstrap.context.TraceId;
26+
import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor;
27+
import com.navercorp.pinpoint.bootstrap.interceptor.annotation.Scope;
28+
import com.navercorp.pinpoint.bootstrap.logging.PLogger;
29+
import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory;
30+
import com.navercorp.pinpoint.plugin.cxf.CxfPluginConfig;
31+
import com.navercorp.pinpoint.plugin.cxf.CxfPluginConstants;
32+
33+
/**
34+
* @author barney
35+
*
36+
*/
37+
@Scope(CxfPluginConstants.CXF_CLIENT_SCOPE)
38+
public class CxfClientInvokeSyncMethodInterceptor implements AroundInterceptor {
39+
40+
private final PLogger logger = PLoggerFactory.getLogger(this.getClass());
41+
private final boolean isDebug = logger.isDebugEnabled();
42+
43+
private final TraceContext traceContext;
44+
private final MethodDescriptor descriptor;
45+
private final CxfPluginConfig pluginConfig;
46+
47+
private final Pattern hiddenParamPattern = Pattern.compile("(.*):([0-9]+)");
48+
49+
public CxfClientInvokeSyncMethodInterceptor(TraceContext traceContext, MethodDescriptor descriptor) {
50+
this.traceContext = traceContext;
51+
this.descriptor = descriptor;
52+
this.pluginConfig = new CxfPluginConfig(traceContext.getProfilerConfig());
53+
}
54+
55+
@Override
56+
public void before(Object target, Object[] args) {
57+
if (isDebug) {
58+
logger.beforeInterceptor(target, args);
59+
}
60+
Trace trace = traceContext.currentRawTraceObject();
61+
if (trace == null) {
62+
return;
63+
}
64+
if (!trace.canSampled()) {
65+
if (isDebug) {
66+
logger.debug("Sampling is disabled");
67+
}
68+
return;
69+
}
70+
71+
String endpoint = getDestination(args);
72+
String operation = getOperation(args);
73+
Object[] parameters = getParameters(operation, args);
74+
75+
SpanEventRecorder recorder = trace.traceBlockBegin();
76+
TraceId nextId = trace.getTraceId().getNextTraceId();
77+
recorder.recordNextSpanId(nextId.getSpanId());
78+
recorder.recordServiceType(CxfPluginConstants.CXF_CLIENT_SERVICE_TYPE);
79+
recorder.recordDestinationId(endpoint);
80+
recorder.recordAttribute(CxfPluginConstants.CXF_OPERATION, operation);
81+
recorder.recordAttribute(CxfPluginConstants.CXF_ARGS, Arrays.toString(parameters));
82+
}
83+
84+
private String getDestination(Object[] args) {
85+
String operationInfo = args[1].toString();
86+
int start = operationInfo.indexOf('{');
87+
int end = operationInfo.indexOf('}');
88+
if(start < 0 || end < 0) {
89+
return operationInfo;
90+
}
91+
return operationInfo.substring(start + 1, end);
92+
}
93+
94+
private String getOperation(Object[] args) {
95+
String operationInfo = args[1].toString();
96+
int start = operationInfo.indexOf('{');
97+
if (start < 0) {
98+
return operationInfo;
99+
}
100+
return operationInfo.substring(start, operationInfo.length() - 1);
101+
}
102+
103+
private Object[] getParameters(String operation, Object[] args) {
104+
Object[] orgParams = (args[2] == null) ? null : (Object[]) args[2];
105+
if (orgParams == null) {
106+
return orgParams;
107+
}
108+
109+
String[] hiddenParams = pluginConfig.getClientHiddenParams();
110+
if(hiddenParams == null || hiddenParams.length == 0) {
111+
return orgParams;
112+
}
113+
Object[] params = Arrays.copyOf(orgParams, orgParams.length);
114+
for (String op : hiddenParams) {
115+
Matcher matcher = hiddenParamPattern.matcher(op);
116+
if (matcher.matches()) {
117+
if (operation.equals(matcher.group(1))) {
118+
int idx = Integer.valueOf(matcher.group(2));
119+
if (idx >= params.length) {
120+
continue;
121+
}
122+
params[idx] = "[HIDDEN PARAM]";
123+
}
124+
} else {
125+
if (op.equals(operation)) {
126+
return new Object[] { "HIDDEN " + params.length + " PARAM" };
127+
}
128+
}
129+
}
130+
return params;
131+
}
132+
133+
@Override
134+
public void after(Object target, Object[] args, Object result, Throwable throwable) {
135+
if (isDebug) {
136+
logger.afterInterceptor(target, args);
137+
}
138+
Trace trace = traceContext.currentTraceObject();
139+
if (trace == null) {
140+
return;
141+
}
142+
143+
try {
144+
SpanEventRecorder recorder = trace.currentSpanEventRecorder();
145+
recorder.recordApi(descriptor);
146+
recorder.recordException(throwable);
147+
} finally {
148+
trace.traceBlockEnd();
149+
}
150+
}
151+
152+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
com.navercorp.pinpoint.plugin.cxf.CxfPlugin
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
com.navercorp.pinpoint.plugin.cxf.CxfPluginTraceMetadataProvider

0 commit comments

Comments
 (0)