Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a plugin that supports the Solon framework. #697

Merged
merged 44 commits into from
Jun 29, 2024
Merged

Conversation

xsShuang
Copy link
Contributor

@xsShuang xsShuang commented Jun 20, 2024

Add an agent plugin to support


package org.apache.skywalking.apm.plugin.solon;

public class FastPathMatcher {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this? I think we didn't discuss about this part.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore plugin is reading configurations from the agent folder, why do ou need that for Solon?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

solon 不需要他,是我自己想添加这样一个功能。尽管有 trace-ignore-plugin 这个插件,但我认为这个插件是在链路追踪后写入数据时阻止忽略的数据写入,而我希望的是插件在生效时,直接过滤排除的 url 请求地址

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个类用 进行 URL 地址匹配,从而实现排除某些不需要链路追踪 URL 的目的

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep in English in GH discussion.

I don't think ignoring should be implemented by a specific plugin of a specific framework.

Please remove this part.

AFAIK, the existing ignore plugin could collaborate with your plugin automatically.

@wu-sheng
Copy link
Member

Also, I can see you didn't follow the document to add relative plugin tests.

Notice, as we are only hosting your codes, to guarantee it works for end users, we need you to finish plugin tests and verify the data.

@xsShuang
Copy link
Contributor Author

Also, I can see you didn't follow the document to add relative plugin tests.

Notice, as we are only hosting your codes, to guarantee it works for end users, we need you to finish plugin tests and verify the data.

抱歉,我没有linux和mac环境来运行自动化测试,但我编写了我提交插件的测试文件,请问有其他的办法可以进行测试吗?

@wu-sheng
Copy link
Member

Please use English on Github.

You could use VM or something to run the tests.

@wu-sheng
Copy link
Member

Please add it into CI control file to make sure it runnable, and attach your local test results.

Meanwhile please be clear about supported versions in docs and test supported list.

# See the License for the specific language governing permissions and
# limitations under the License.

2.8.3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not support only one version. You could verify all supported versions(patch versions), and list all minor versions, one patch version per minor version(such as 2.8.3 for 2.8.x, 2.7.3 for 2.7.x).

spanLayer: Http
startTime: not null
endTime: not null
componentId: 14
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no Solon component related. What is the meaning of your tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this isn't the final code, I just wanted to get a different computer to continue with the code

@xsShuang
Copy link
Contributor Author

image

@wu-sheng
Copy link
Member

Please follow other comments to fix these

  1. GHA control file needs to add this new test case.
  2. Docs should be updated. changes.md and supported-list.md
  3. Verification version list.

@wu-sheng
Copy link
Member

Any update?

@xsShuang
Copy link
Contributor Author

Any update?

Sorry, it's been a busy day. I'll take care of it tomorrow.

@xsShuang
Copy link
Contributor Author

Please follow other comments to fix these

  1. GHA control file needs to add this new test case.
  2. Docs should be updated. changes.md and supported-list.md
  3. Verification version list.

I have submitted the appropriate documents as per your instructions, please help me to confirm whether it is correct or not, thank you!

@wu-sheng
Copy link
Member

Resolve the conflicts, then I could make CI works to verify.

@wu-sheng
Copy link
Member

Please run tests locally, rather than costing us too much on running repeatedly.

Comment on lines 17 to 28
2.7.0
2.7.1
2.7.2
2.7.3
2.7.4
2.7.5
2.7.6
2.8.0
2.8.1
2.8.2
2.8.3
2.8.4
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't follow my comments. 2.7(per minor version) and 2.8 should keep one version only.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, my English is really bad and I have to rely on translation software, which leads to a lot of places that I can't fully understand.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CN slack is there. If you have doubts, ask there.

- {key: url, value: not null}
- {key: http.method, value: GET}
skipAnalysis: 'false'
- operationName: 'Solon:GET:/testcase/error'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of entry spans have reference verifications, this test scenarios can't prove the tracing continues.

Solon is a RPC framework AFAIK, your test doesn't cover an important part.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I can't fully understand the meaning of automated test scripts. I wrote this script with reference to spring. From the results I get from running it, I think I can get the link tracing information

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If no reference, I can't see how it links.

You should check the segments of traces, and understand the data.

As I have explained, we don't maintain the plugins, but host for you(for example). After this, I can't ask you every time when someone submitted an issue/discussion. So, the best way is, test scenarios themselves can prove it works as expected.

@@ -320,3 +320,15 @@ plugin.nettyhttp.supported_content_types_prefix=${SW_PLUGIN_NETTYHTTP_SUPPORTED_
plugin.rocketmqclient.collect_message_keys=${SW_PLUGIN_ROCKETMQCLIENT_COLLECT_MESSAGE_KEYS:false}
# If set to true, the tags of messages would be collected by the plugin for RocketMQ Java client.
plugin.rocketmqclient.collect_message_tags=${SW_PLUGIN_ROCKETMQCLIENT_COLLECT_MESSAGE_TAGS:false}
# How many parameter characters to keep and send to the OAP backend, -1 save all, 0 save nothing, >0 save specified length of parameter string to the tag. default is 0.
plugin.solon.http_params_length_threshold=${SW_PLUGIN_SOLON_HTTP_PARAMS_LENGTH_THRESHOLD:0}
# How many header characters to keep and send to the OAP backend, -1 save all, 0 save nothing, >0 save specified length of header string to the tag. default is 0.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments/descriptions should be polished. Refer to the above one.

@@ -97,7 +82,7 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) {
Context ctx = (Context) allArguments[0];
if (afterExceptionHandling) {
if (SolonPluginConfig.Plugin.Solon.AFTER_EXCEPTION_HANDLING) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you accept the error unprocessed? I think that is far away of the purpose of tracing. Error codes are important.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no control over when the user handles exceptions

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My question is about this config. Why do we need this config?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This configuration is where I need the user to tell me if he handled the exception, and if he did, I'll set up exception logging for him and use the status code after he handled it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to process that, why don't you create an interceptor for filter(s)? It should be easy too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I spoke with the solon author and he thinks that adding a filter customised for tracking doesn't make sense in the framework and that there should be plugins for that. But I want to make tracking available to users using solon without having to change any code.

Comment on lines 325 to 326
# Define the max length of collected HTTP header. The default value(=0) means not collecting.
plugin.solon.http_headers_length_threshold=${SW_PLUGIN_SOLON_HTTP_HEADERS_LENGTH_THRESHOLD:0}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This config field doesn't exist in the codes. Why it is here?

Comment on lines 327 to 328
# It controls what header data should be collected, values must be in lower case, if empty, collect all. default is empty.
plugin.solon.include_http_headers=${SW_PLUGIN_SOLON_INCLUDE_HTTP_HEADERS:}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, you should not collect all headers. All collected things should be very specific.

Header usually carries auth token, this is auto collecting is dangerous and could cause sensitive data leak.

Comment on lines 333 to 334
# Intercept method name, default is invoke
plugin.solon.intercept_method_name=${SW_PLUGIN_SOLON_INTERCEPT_METHOD_NAME:invoke}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inceptor method should not be defined by the configurations. This is a kind of config abuse.

| `plugin.jedis.trace_redis_parameters` | If set to true, the parameters of Redis commands would be collected by Jedis agent. | SW_PLUGIN_JEDIS_TRACE_REDIS_PARAMETERS | `false` |
| `plugin.jedis.redis_parameter_max_length` | If set to positive number and `plugin.jedis.trace_redis_parameters` is set to `true`, Redis command parameters would be collected and truncated to this length. | SW_PLUGIN_JEDIS_REDIS_PARAMETER_MAX_LENGTH | `128` |
| `plugin.jedis.operation_mapping_write` | Specify which command should be converted to `write` operation | SW_PLUGIN_JEDIS_OPERATION_MAPPING_WRITE | |
| property key | Description | **System Environment Variable** | Default |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are changing the whole file? Please don't do this.

Comment on lines 45 to 51
/**
* intercept method name, default is invoke
*/
public static String INTERCEPT_METHOD_NAME = "invoke";
/**
* is after exception handling, default is false, if true, the plugin will intercept the method after the exception handling
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two don't make sense. And the comments are not helpful.
Even you are not good at English, there are many AI tools could help you polish that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides the comments, I am highly concerned about these two configurations. Please explain more clearly.
I never saw a framework plugin did this. The error code process should be very simple and straight forward.

@wu-sheng
Copy link
Member

Please use v2 plugin APIs for better performance, and don't use runtime context to collaborate inside an interceptor.

next = next.next();
next.setHeadValue(ctx.header(next.getHeadKey()));
}
String operationName = "Solon:" + ctx.method() + ":" + ctx.path();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
String operationName = "Solon:" + ctx.method() + ":" + ctx.path();
String operationName = ctx.method() + ":" + ctx.path();

The operation name of the span should be framework stack irrelevant. And you need to change test cases accordingly.

Comment on lines 68 to 69
if (SolonPluginConfig.Plugin.Solon.HTTP_HEADERS_LENGTH_THRESHOLD > 0 && headerStr.length() > SolonPluginConfig.Plugin.Solon.HTTP_HEADERS_LENGTH_THRESHOLD) {
headerStr = headerStr.substring(0, SolonPluginConfig.Plugin.Solon.HTTP_HEADERS_LENGTH_THRESHOLD);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should control header by key list, because every key has a length limitation by HTTP. Once the number of keys is limited, we don't need to worry about overload.

Copy link
Member

@wu-sheng wu-sheng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks for your patience.

@wu-sheng wu-sheng added this to the 9.3.0 milestone Jun 29, 2024
@wu-sheng wu-sheng merged commit 0fc3cd8 into apache:main Jun 29, 2024
191 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants