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

fix redis trace plugin #550

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Just-CJ
Copy link

@Just-CJ Just-CJ commented Oct 29, 2024

Motivation:

修复redis-plugin目前无法正常打印日志的问题

Modification:

参考datasource-plugin中RedisSofaTracer中增加了startTrace和endTrace方法,并在RedisActionWrapperHelper中进行调用

Result:

Fixes #503.

Summary by CodeRabbit

  • New Features
    • Enhanced tracing capabilities with new methods for starting and ending traces.
    • Added constants for defining specific tags in tracing operations.
  • Improvements
    • Simplified span management in tracing operations, reducing complexity.
    • Improved error handling and logging during tracing operations.

Copy link

coderabbitai bot commented Oct 29, 2024

Walkthrough

The changes in this pull request focus on simplifying the tracing mechanism in the RedisActionWrapperHelper and enhancing the RedisSofaTracer class. The modifications include the removal of Span object handling from method signatures and the introduction of new methods for starting and ending traces. This results in a more streamlined approach to tracing operations, with the RedisSofaTracer now capable of managing tracing spans more effectively through newly added constants and methods.

Changes

File Change Summary
.../RedisActionWrapperHelper.java Removed Span handling from multiple method signatures and simplified span management logic.
.../RedisSofaTracer.java Added new constants (COMMAND, COMPONENT_NAME, DB_TYPE) and methods (startTrace, endTrace) for enhanced tracing functionality.

Assessment against linked issues

Objective Addressed Explanation
Ensure parent span is linked when starting span (#503)

🐰 In the meadow where the rabbits play,
With tracing logs, we hop all day!
Simplified spans, oh what a sight,
In our code, everything feels right!
With new tags and methods, we trace with glee,
Hopping along, as happy as can be! 🥕✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (3)
sofa-tracer-plugins/sofa-tracer-redis-plugin/src/main/java/com/sofa/alipay/tracer/plugins/spring/redis/tracer/RedisSofaTracer.java (2)

117-132: Remove unnecessary semicolon on line 129.

The implementation correctly addresses the core issue by calling clientSend before creating the span, which fixes the parent span association problem mentioned in issue #503.

Apply this diff to remove the unnecessary semicolon:

            sofaTracerSpan.setTag(Tags.COMPONENT.getKey(), COMPONENT_NAME);
            sofaTracerSpan.setTag(Tags.DB_TYPE.getKey(), DB_TYPE);
-            ;

134-152: Enhance error logging message for better debugging.

The error message in SelfLog could be more descriptive to aid in debugging.

Apply this diff to improve the error message:

-                    SelfLog.errorWithTraceId("redis processed", throwable);
+                    SelfLog.errorWithTraceId("Failed to process Redis trace completion", throwable);

Additionally, consider adding debug logging for cases where the span or trace context is null to help identify potential issues during development.

sofa-tracer-plugins/sofa-tracer-redis-plugin/src/main/java/com/sofa/alipay/tracer/plugins/spring/redis/common/RedisActionWrapperHelper.java (1)

185-187: Consider adding method documentation.

The implementation looks good and aligns with the new tracing approach. Consider adding Javadoc to explain the method's purpose and parameter requirements.

+ /**
+  * Builds and starts a new trace span for Redis operations.
+  *
+  * @param operationName The name of the Redis operation being performed
+  * @param key The key being operated on, can be null
+  */
 public void buildSpan(String operationName, Object key) {
     SofaTracerSpan span = redisSofaTracer.startTrace(operationName);
     span.setTag("key", nullable(key));
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d8053ce and 7aae9bf.

📒 Files selected for processing (2)
  • sofa-tracer-plugins/sofa-tracer-redis-plugin/src/main/java/com/sofa/alipay/tracer/plugins/spring/redis/common/RedisActionWrapperHelper.java (5 hunks)
  • sofa-tracer-plugins/sofa-tracer-redis-plugin/src/main/java/com/sofa/alipay/tracer/plugins/spring/redis/tracer/RedisSofaTracer.java (2 hunks)
🔇 Additional comments (4)
sofa-tracer-plugins/sofa-tracer-redis-plugin/src/main/java/com/sofa/alipay/tracer/plugins/spring/redis/tracer/RedisSofaTracer.java (2)

20-36: LGTM! Well-structured constants for Redis tracing.

The new constants and imports provide clear identification for Redis operations and support the tracing functionality effectively.

Also applies to: 44-46


117-152: Verify the trace linking in integration tests.

The implementation looks solid and addresses the core issues. To ensure everything works as expected:

✅ Verification successful

Based on the code review and test implementation analysis, I can now provide a final response:

Redis tracing implementation is properly tested and verified

The implementation has been verified through:

  • Integration test SofaTracerRedisConnectionTest that exercises the Redis connection with tracing
  • Proper span lifecycle management in RedisSofaTracer with:
    • Parent span association via clientSend()
    • Complete span attributes including component, DB type, and command tags
    • Proper error handling and span completion via clientReceive()

The original review comment's concerns about trace linking have been addressed by the existing implementation and test coverage.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for integration tests that verify parent span association
rg -l "RedisSofaTracer.*test" --type java

# Look for existing Redis trace tests
rg -l "RedisTemplate.*test" --type java

# Check for any existing span verification in tests
ast-grep --pattern 'assert$_($_->getParentSpanId())'

Length of output: 140


Script:

#!/bin/bash
# Look for test files related to Redis tracing
fd -e java test -x grep -l "Redis" {}

# Search for Redis test configurations
fd -e java -e xml test -x grep -l "redis" {}

# Look for Redis tracer usage in tests
rg "new RedisSofaTracer\(" --type java

# Check for span assertions in test files
rg "assert.*Span" --type java

Length of output: 34322


Script:

#!/bin/bash
# Look for Redis integration test content
cat ./tracer-sofa-boot-starter/src/test/java/com/alipay/sofa/tracer/boot/redis/SofaTracerRedisConnectionTest.java

# Search for Redis tracer implementation
cat ./sofa-tracer-plugins/sofa-tracer-redis-plugin/src/main/java/com/sofa/alipay/tracer/plugins/spring/redis/tracer/RedisSofaTracer.java

# Look for Redis span reporter implementations
rg "RedisSpanReport" --type java

Length of output: 9226

sofa-tracer-plugins/sofa-tracer-redis-plugin/src/main/java/com/sofa/alipay/tracer/plugins/spring/redis/common/RedisActionWrapperHelper.java (2)

Line range hint 136-168: LGTM! Proper span lifecycle management implemented.

The implementation correctly handles span activation and closure, with proper error handling and consistent patterns across both Supplier and Runnable variants. This change helps fix the parent span association issue mentioned in #503.


49-50: Verify command parameter validation.

While the tracing implementation looks correct, consider adding validation for the command parameter to prevent potential NPEs and improve robustness.

 public <T> T doInScope(String command, byte[] key, Supplier<T> supplier) {
+    if (command == null || command.trim().isEmpty()) {
+        throw new IllegalArgumentException("Command cannot be null or empty");
+    }
     buildSpan(command, deserialize(key));
     return activateAndCloseSpan(supplier);
 }

Let's verify the command parameter usage across the codebase:

Also applies to: 54-55, 59-60, 64-65, 69-71

Comment on lines +84 to +94
redisSofaTracer.startTrace(operateName);
return supplier.get();
} catch (Throwable t) {
candidateThrowable = t;
throw t;
} finally {
if (candidateThrowable != null) {
span.setTag(Tags.ERROR.getKey(), candidateThrowable.getMessage());
redisSofaTracer.clientReceive(SofaTracerConstant.RESULT_CODE_ERROR);
redisSofaTracer.endTrace(SofaTracerConstant.RESULT_CODE_ERROR,
candidateThrowable.getMessage());
} else {
redisSofaTracer.clientReceive(SofaTracerConstant.RESULT_CODE_SUCCESS);
redisSofaTracer.endTrace(SofaTracerConstant.RESULT_CODE_SUCCESS, null);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider extracting duplicate error handling logic.

The error handling pattern is duplicated across decorate, decorateThrowing, and other methods. Consider extracting this into a reusable method to improve maintainability.

+ private void handleTraceCompletion(Throwable candidateThrowable) {
+     if (candidateThrowable != null) {
+         redisSofaTracer.endTrace(SofaTracerConstant.RESULT_CODE_ERROR,
+             candidateThrowable.getMessage());
+     } else {
+         redisSofaTracer.endTrace(SofaTracerConstant.RESULT_CODE_SUCCESS, null);
+     }
+ }

  public <T> T decorate(Supplier<T> supplier, String operateName) {
      Throwable candidateThrowable = null;
      try {
          redisSofaTracer.startTrace(operateName);
          return supplier.get();
      } catch (Throwable t) {
          candidateThrowable = t;
          throw t;
      } finally {
-         if (candidateThrowable != null) {
-             redisSofaTracer.endTrace(SofaTracerConstant.RESULT_CODE_ERROR,
-                 candidateThrowable.getMessage());
-         } else {
-             redisSofaTracer.endTrace(SofaTracerConstant.RESULT_CODE_SUCCESS, null);
-         }
+         handleTraceCompletion(candidateThrowable);
      }
  }

Also applies to: 102-112, 121-131

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.

sofa-tracer redis plugin未串联父span
1 participant