Skip to content

Commit d53f04b

Browse files
Add Caffeine plugin as optional (#743)
1 parent b0d5bc1 commit d53f04b

File tree

31 files changed

+1158
-15
lines changed

31 files changed

+1158
-15
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
build:
4343
name: Java ${{ matrix.java-version }} / ${{ matrix.os }}
4444
runs-on: ${{ matrix.os }}-latest
45-
timeout-minutes: 60
45+
timeout-minutes: 90
4646
needs: [ license ]
4747
strategy:
4848
fail-fast: true

.github/workflows/codeql.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ jobs:
5454
java-version: 17
5555

5656
- name: Initialize CodeQL
57-
uses: github/codeql-action/init@v1
57+
uses: github/codeql-action/init@v3
5858
with:
5959
languages: ${{ matrix.language }}
6060

6161
- run: ./mvnw -q -Dmaven.test.skip=true clean install || ./mvnw -q -Dmaven.test.skip=true clean install
6262

6363
- name: Perform CodeQL Analysis
64-
uses: github/codeql-action/analyze@v1
64+
uses: github/codeql-action/analyze@v3

.github/workflows/plugins-jdk17-test.1.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ jobs:
6363
- c3p0-0.9.0.x-0.9.1.x-scenario
6464
- c3p0-0.9.2.x-0.10.x-scenario
6565
- spring-scheduled-6.x-scenario
66+
- caffeine-3.x-scenario
6667
steps:
6768
- uses: actions/checkout@v2
6869
with:

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Release Notes.
2525
Plugin, Kotlin Coroutine Plugin, and Spring Gateway Plugin
2626
* Change context and parent entry span propagation mechanism from gRPC ThreadLocal context to SkyWalking native dynamic
2727
field as new propagation mechanism, to better support async scenarios.
28+
* Add Caffeine plugin as optional.
2829

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

apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,4 +259,5 @@ public class ComponentsDefine {
259259

260260
public static final OfficialComponent SOLON_MVC = new OfficialComponent(158, "SolonMVC");
261261

262+
public static final OfficialComponent CAFFEINE = new OfficialComponent(160, "Caffeine");
262263
}

apm-sniffer/config/agent.config

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,7 @@ plugin.solon.http_params_length_threshold=${SW_PLUGIN_SOLON_HTTP_PARAMS_LENGTH_T
332332
plugin.solon.include_http_headers=${SW_PLUGIN_SOLON_INCLUDE_HTTP_HEADERS:}
333333
# Define the max length of collected HTTP body. The default value(=0) means not collecting.
334334
plugin.solon.http_body_length_threshold=${SW_PLUGIN_SOLON_HTTP_BODY_LENGTH_THRESHOLD:0}
335+
# Specify which command should be converted to write operation
336+
plugin.caffeine.operation_mapping_write=${SW_PLUGIN_CAFFEINE_OPERATION_MAPPING_WRITE:put,putAll,remove,clear}
337+
# Specify which command should be converted to read operation
338+
plugin.caffeine.operation_mapping_read=${SW_PLUGIN_CAFFEINE_OPERATION_MAPPING_READ:getIfPresent,getAllPresent,computeIfAbsent}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one or more
4+
~ contributor license agreements. See the NOTICE file distributed with
5+
~ this work for additional information regarding copyright ownership.
6+
~ The ASF licenses this file to You under the Apache License, Version 2.0
7+
~ (the "License"); you may not use this file except in compliance with
8+
~ the License. You may obtain a copy of the License at
9+
~
10+
~ http://www.apache.org/licenses/LICENSE-2.0
11+
~
12+
~ Unless required by applicable law or agreed to in writing, software
13+
~ distributed under the License is distributed on an "AS IS" BASIS,
14+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
~ See the License for the specific language governing permissions and
16+
~ limitations under the License.
17+
~
18+
-->
19+
20+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
21+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
22+
<modelVersion>4.0.0</modelVersion>
23+
<parent>
24+
<groupId>org.apache.skywalking</groupId>
25+
<artifactId>optional-plugins</artifactId>
26+
<version>9.4.0-SNAPSHOT</version>
27+
</parent>
28+
29+
<artifactId>apm-caffeine-3.x-plugin</artifactId>
30+
<packaging>jar</packaging>
31+
<name>caffeine-3.x-plugin</name>
32+
33+
<properties>
34+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
35+
<caffeine.version>3.1.8</caffeine.version>
36+
</properties>
37+
38+
<dependencies>
39+
<dependency>
40+
<groupId>com.github.ben-manes.caffeine</groupId>
41+
<artifactId>caffeine</artifactId>
42+
<version>${caffeine.version}</version>
43+
<scope>provided</scope>
44+
</dependency>
45+
</dependencies>
46+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.plugin.caffeine.v3;
20+
21+
import java.lang.reflect.Method;
22+
import org.apache.skywalking.apm.agent.core.context.ContextManager;
23+
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
24+
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
25+
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
26+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
27+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
28+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
29+
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
30+
31+
import static org.apache.skywalking.apm.plugin.caffeine.v3.CaffeineOperationTransform.transformOperation;
32+
33+
abstract public class AbstractCaffeineInterceptor implements InstanceMethodsAroundInterceptor {
34+
35+
protected AbstractSpan generateSpanInfo(String methodName) {
36+
AbstractSpan span = ContextManager.createLocalSpan("Caffeine/" + methodName);
37+
span.setComponent(ComponentsDefine.CAFFEINE);
38+
Tags.CACHE_TYPE.set(span, ComponentsDefine.CAFFEINE.getName());
39+
Tags.CACHE_CMD.set(span, methodName);
40+
transformOperation(methodName).ifPresent(op -> Tags.CACHE_OP.set(span, op));
41+
SpanLayer.asCache(span);
42+
return span;
43+
}
44+
45+
@Override
46+
public void beforeMethod(final EnhancedInstance objInst,
47+
final Method method,
48+
final Object[] allArguments,
49+
final Class<?>[] argumentsTypes,
50+
final MethodInterceptResult result) throws Throwable {
51+
}
52+
53+
@Override
54+
public Object afterMethod(final EnhancedInstance objInst,
55+
final Method method,
56+
final Object[] allArguments,
57+
final Class<?>[] argumentsTypes,
58+
final Object ret) throws Throwable {
59+
ContextManager.stopSpan();
60+
return ret;
61+
}
62+
63+
@Override
64+
public void handleMethodException(final EnhancedInstance objInst,
65+
final Method method,
66+
final Object[] allArguments,
67+
final Class<?>[] argumentsTypes,
68+
final Throwable t) {
69+
ContextManager.activeSpan().log(t);
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.plugin.caffeine.v3;
20+
21+
import java.lang.reflect.Method;
22+
import java.util.stream.Collectors;
23+
import java.util.stream.StreamSupport;
24+
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
25+
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
26+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
27+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
28+
29+
public class CaffeineIterableInterceptor extends AbstractCaffeineInterceptor {
30+
31+
@Override
32+
public void beforeMethod(final EnhancedInstance objInst,
33+
final Method method,
34+
final Object[] allArguments,
35+
final Class<?>[] argumentsTypes,
36+
final MethodInterceptResult result) throws Throwable {
37+
AbstractSpan span = generateSpanInfo(method.getName());
38+
if (allArguments != null && allArguments.length > 0) {
39+
String keys = StreamSupport
40+
.stream(((Iterable<?>) allArguments[0]).spliterator(), false)
41+
.map(String::valueOf)
42+
.collect(Collectors.joining(","));
43+
Tags.CACHE_KEY.set(span, keys);
44+
}
45+
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.plugin.caffeine.v3;
20+
21+
import java.lang.reflect.Method;
22+
import java.util.Map;
23+
import java.util.stream.Collectors;
24+
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
25+
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
26+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
27+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
28+
29+
public class CaffeineMapInterceptor extends AbstractCaffeineInterceptor {
30+
31+
@Override
32+
public void beforeMethod(final EnhancedInstance objInst,
33+
final Method method,
34+
final Object[] allArguments,
35+
final Class<?>[] argumentsTypes,
36+
final MethodInterceptResult result) throws Throwable {
37+
AbstractSpan span = generateSpanInfo(method.getName());
38+
if (allArguments != null && allArguments.length > 0) {
39+
String keys = ((Map<?, ?>) allArguments[0])
40+
.keySet().stream().map(String::valueOf)
41+
.collect(Collectors.joining(","));
42+
Tags.CACHE_KEY.set(span, keys);
43+
}
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.plugin.caffeine.v3;
20+
21+
import java.util.Optional;
22+
23+
public class CaffeineOperationTransform {
24+
25+
public static Optional<String> transformOperation(String cmd) {
26+
if (CaffeinePluginConfig.Plugin.Caffeine.OPERATION_MAPPING_READ.contains(cmd)) {
27+
return Optional.of("read");
28+
}
29+
if (CaffeinePluginConfig.Plugin.Caffeine.OPERATION_MAPPING_WRITE.contains(cmd)) {
30+
return Optional.of("write");
31+
}
32+
return Optional.empty();
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.plugin.caffeine.v3;
20+
21+
import java.util.Arrays;
22+
import java.util.HashSet;
23+
import java.util.Set;
24+
import org.apache.skywalking.apm.agent.core.boot.PluginConfig;
25+
26+
/**
27+
* Operation represent a cache span is "write" or "read" action , and "op"(operation) is tagged with key "cache.op"
28+
* usually This config term define which command should be converted to write Operation .
29+
*
30+
* @see org.apache.skywalking.apm.agent.core.context.tag.Tags#CACHE_OP
31+
* @see CaffeineOperationTransform#transformOperation(String)
32+
*/
33+
public class CaffeinePluginConfig {
34+
public static class Plugin {
35+
@PluginConfig(root = CaffeinePluginConfig.class)
36+
public static class Caffeine {
37+
public static Set<String> OPERATION_MAPPING_WRITE = new HashSet<>(Arrays.asList(
38+
"put",
39+
"putAll",
40+
"remove",
41+
"clear"
42+
));
43+
public static Set<String> OPERATION_MAPPING_READ = new HashSet<>(Arrays.asList(
44+
"getIfPresent",
45+
"getAllPresent",
46+
"computeIfAbsent"
47+
));
48+
}
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.plugin.caffeine.v3;
20+
21+
import java.lang.reflect.Method;
22+
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
23+
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
24+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
25+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
26+
27+
public class CaffeineStringInterceptor extends AbstractCaffeineInterceptor {
28+
29+
@Override
30+
public void beforeMethod(final EnhancedInstance objInst,
31+
final Method method,
32+
final Object[] allArguments,
33+
final Class<?>[] argumentsTypes,
34+
final MethodInterceptResult result) throws Throwable {
35+
AbstractSpan span = generateSpanInfo(method.getName());
36+
if (allArguments != null && allArguments.length > 0 && allArguments[0] instanceof String) {
37+
Tags.CACHE_KEY.set(span, allArguments[0].toString());
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)