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

feat: add path prefix label to obejct storage metrics #4277

Merged
merged 5 commits into from
Jul 5, 2024

Conversation

sunng87
Copy link
Member

@sunng87 sunng87 commented Jul 4, 2024

I hereby agree to the terms of the GreptimeDB CLA.

Refer to a related PR or issue link (optional)

What's changed and what's your intention?

This patch add a path label to object store related prometheus metrics, so that we can observe which path has most writes/reads.

Checklist

  • I have written the necessary rustdoc comments.
  • I have added the necessary unit tests and integration tests.
  • This PR requires documentation updates.

Summary by CodeRabbit

  • New Features
    • Enhanced metrics tracking with more granular insights by including path-specific metrics in monitoring.
  • Improvements
    • Improved function for extracting parent paths from object storage operations, enhancing path management.

@sunng87 sunng87 requested a review from a team as a code owner July 4, 2024 05:51
Copy link
Contributor

coderabbitai bot commented Jul 4, 2024

Walkthrough

The recent changes enhance the object-store module by introducing the extract_parent_path function, which extracts parent paths from object storage operations. Additionally, Prometheus metrics are refined to include path-specific labels, providing more detailed insights into operations based on paths. These changes aim to improve path handling and monitoring granularity inside the module.

Changes

File Path Change Summary
src/object-store/src/util.rs Added extract_parent_path function with tests and refined normalize_path function with additional comments.
src/object-store/src/layers/prometheus.rs Enhancements to Prometheus metrics tracking by adding "path" as a label value in various functions and methods.

Poem

In the forest of code so fine,
Paths converge, metrics align.
Parent paths we now unveil,
Monitoring each with detail.
Prometheus smiles, paths no longer coy,
Every change a tune, coding's joy 🎶.


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>.
    • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @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 as 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.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration 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.

@sunng87 sunng87 requested review from zyy17 and WenyXu July 4, 2024 05:51
@github-actions github-actions bot added the docs-not-required This change does not impact docs. label Jul 4, 2024
Copy link
Contributor

@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: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between ee9a5d7 and 395d1f0.

Files selected for processing (2)
  • src/object-store/src/layers/prometheus.rs (19 hunks)
  • src/object-store/src/util.rs (2 hunks)
Additional comments not posted (9)
src/object-store/src/util.rs (1)

126-142: LGTM! Verify the function usage in the codebase.

The function logic is correct and includes comments explaining its behavior and safety.

However, ensure that the extract_parent_path function is correctly used in the codebase.

src/object-store/src/layers/prometheus.rs (8)

131-145: LGTM! Verify the function usage in the codebase.

The method logic is correct and includes the new path_label parameter for Prometheus metrics.

However, ensure that the create_dir method is correctly used in the codebase.

Verification successful

Verified: The create_dir method is correctly used in the codebase.

The method create_dir in src/object-store/src/layers/prometheus.rs matches the new signature and is correctly used within the file. There are no other instances of create_dir that need updating.

  • src/object-store/src/layers/prometheus.rs: Correct usage of the new create_dir method.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `create_dir` match the new signature.

# Test: Search for the function usage. Expect: Only occurrences of the new signature.
rg --type rust $'create_dir'

Length of output: 1842


288-294: LGTM! Verify the function usage in the codebase.

The method logic is correct and includes the new path_label parameter for Prometheus metrics.

However, ensure that the presign method is correctly used in the codebase.

Verification successful

Verification Successful: The presign method usage matches the new signature.

  • The method definition and its usage are consistent with the new signature.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `presign` match the new signature.

# Test: Search for the function usage. Expect: Only occurrences of the new signature.
rg --type rust $'presign'

Length of output: 247


306-320: LGTM! Verify the function usage in the codebase.

The method logic is correct and includes the new path_label parameter for Prometheus metrics.

However, ensure that the blocking_create_dir method is correctly used in the codebase.

Verification successful

LGTM! The function usage has been verified and is correct.

  • The blocking_create_dir function is only used within the src/object-store/src/layers/prometheus.rs file.
  • There are no other calls to this function elsewhere in the codebase.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `blocking_create_dir` match the new signature.

# Test: Search for the function usage. Expect: Only occurrences of the new signature.
rg --type rust $'blocking_create_dir'

Length of output: 275


Script:

#!/bin/bash
# Description: Verify all function calls to `blocking_create_dir` across the entire codebase to ensure they match the new signature.

# Test: Search for the function usage. Expect: Only occurrences of the new signature.
rg 'blocking_create_dir'

Length of output: 263


234-240: LGTM! Verify the function usage in the codebase.

The method logic is correct and includes the new path_label parameter for Prometheus metrics.

However, ensure that the delete method is correctly used in the codebase.

Verification successful

Verification successful!

The delete function in src/object-store/src/layers/prometheus.rs has been correctly updated and all its usages match the new signature.

  • Lines: 234-240 in src/object-store/src/layers/prometheus.rs
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `delete` match the new signature.

# Test: Search for the function usage. Expect: Only occurrences of the new signature.
rg --type rust $'delete'

Length of output: 65202


Script:

#!/bin/bash
# Description: Verify the specific `delete` function usage in prometheus.rs matches the new signature.

# Search for the `delete` function definition in prometheus.rs to get its signature.
ast-grep --lang rust --pattern 'async fn delete(&self, path: &str, args: OpDelete) -> Result<RpDelete>' src/object-store/src/layers/prometheus.rs

# Search for calls to the `delete` function within prometheus.rs to ensure they match the new signature.
rg --type rust 'delete\(' src/object-store/src/layers/prometheus.rs

Length of output: 497


252-258: LGTM! Verify the function usage in the codebase.

The method logic is correct and includes the new path_label parameter for Prometheus metrics.

However, ensure that the list method is correctly used in the codebase.

Verification successful

The modification in the list method of prometheus.rs correctly uses the path_label parameter for Prometheus metrics. No further issues were found.

  • The list method in src/object-store/src/layers/prometheus.rs correctly integrates the path_label parameter.
  • Verified the invocation of the list method within prometheus.rs.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `list` match the new signature.

# Test: Search for the function usage. Expect: Only occurrences of the new signature.
rg --type rust $'list'

Length of output: 97347


Script:

#!/bin/bash
# Description: Verify all function calls to `list` in `src/object-store/src/layers/prometheus.rs` match the new signature.

# Test: Search for the specific function signature and its invocations.
rg --type rust 'list\(&self, path: &str, args: OpList\)' -A 5

Length of output: 1991


Script:

#!/bin/bash
# Description: Verify all invocations of the `list` method in the codebase.

# Test: Search for invocations of the `list` method.
rg --type rust '\.list\('

Length of output: 1364


Script:

#!/bin/bash
# Description: Verify invocations of the `list` method in `src/object-store/src/layers/prometheus.rs` to ensure correct usage of the `path_label` parameter.

# Test: Search for invocations of the `list` method in `prometheus.rs`.
rg --type rust '\.list\(' src/object-store/src/layers/prometheus.rs

Length of output: 127


Line range hint 157-180:
LGTM! Verify the function usage in the codebase.

The method logic is correct and includes the new path_label parameter for Prometheus metrics.

However, ensure that the read method is correctly used in the codebase.


Line range hint 187-210:
LGTM! Verify the function usage in the codebase.

The method logic is correct and includes the new path_label parameter for Prometheus metrics.

However, ensure that the write method is correctly used in the codebase.


217-223: LGTM! Verify the function usage in the codebase.

The method logic is correct and includes the new path_label parameter for Prometheus metrics.

However, ensure that the stat method is correctly used in the codebase.

src/object-store/src/layers/prometheus.rs Outdated Show resolved Hide resolved
src/object-store/src/layers/prometheus.rs Outdated Show resolved Hide resolved
@sunng87 sunng87 changed the title feat: add path prefix label to storage metrics feat: add path prefix label to obejct storage metrics Jul 4, 2024
Copy link

codecov bot commented Jul 4, 2024

Codecov Report

Attention: Patch coverage is 49.20635% with 64 lines in your changes missing coverage. Please review.

Project coverage is 84.67%. Comparing base (b5c6c72) to head (7e98924).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4277      +/-   ##
==========================================
- Coverage   84.94%   84.67%   -0.28%     
==========================================
  Files        1061     1061              
  Lines      188105   188201      +96     
==========================================
- Hits       159795   159352     -443     
- Misses      28310    28849     +539     

@evenyag
Copy link
Contributor

evenyag commented Jul 4, 2024

The official PrometheusLayer already supports this, I think we should switch to it
https://docs.rs/opendal/latest/opendal/layers/struct.PrometheusLayer.html#method.enable_path_label

@sunng87
Copy link
Member Author

sunng87 commented Jul 4, 2024

According to the patch comment, we forked it to avoid a panic with metrics registration. #2861

Checked upstream it doesn't seem to be addressed after our fork. Also our solution, using lazy_static, is not suitable to upstream because it's not suitable for a library.

@evenyag
Copy link
Contributor

evenyag commented Jul 4, 2024

According to the patch comment, we forked it to avoid a panic with metrics registration. #2861

Checked upstream it doesn't seem to be addressed after our fork. Also our solution, using lazy_static, is not suitable to upstream because it's not suitable for a library.

The layer itself could be cloned. So we can use lazy_static to init a global PrometheusLayer that uses the default registry. Then we can clone the global layer and reuse it.

Yes, I realized that the layer will create a PrometheusMetrics in each call to the Layer::layer() implementation. The PrometheusMetrics always registers metrics to the provided registry. However, the registry doesn't allow registering the same metric multiple times.

So we can't create multiple Operator with the same prometheus layer.
https://github.com/apache/opendal/blob/174bda53f79123cd114d2409189423a0a4cf6bf3/core/src/layers/prometheus.rs#L193-L210

@evenyag
Copy link
Contributor

evenyag commented Jul 4, 2024

According to the patch comment, we forked it to avoid a panic with metrics registration. #2861
Checked upstream it doesn't seem to be addressed after our fork. Also our solution, using lazy_static, is not suitable to upstream because it's not suitable for a library.

The layer itself could be cloned. So we can use lazy_static to init a global PrometheusLayer that uses the default registry. Then we can clone the global layer and reuse it.

Yes, I realized that the layer will create a PrometheusMetrics in each call to the Layer::layer() implementation. The PrometheusMetrics always registers metrics to the provided registry. However, the registry doesn't allow registering the same metric multiple times.

So we can't create multiple Operator with the same prometheus layer. https://github.com/apache/opendal/blob/174bda53f79123cd114d2409189423a0a4cf6bf3/core/src/layers/prometheus.rs#L193-L210

I created an issue for this. apache/opendal#4854

Maybe @Xuanwo can give us some suggestions.

@Xuanwo
Copy link
Contributor

Xuanwo commented Jul 4, 2024

I created an issue for this. apache/opendal#4854

Maybe @Xuanwo can give us some suggestions.

Thanks! I'm also thinking allow users to set metrics or reuse them in someway. I will give it look.

@sunng87
Copy link
Member Author

sunng87 commented Jul 4, 2024

Actually I found the Prometheus library has a few runtime panics which I think can be avoided by design. For example, if you provide labels doesn't match the declaration, it ends up with a runtime panics, which is very dangerous for some corner cases.

Copy link
Contributor

@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 (1)
src/object-store/src/util.rs (1)

126-141: Document function assumptions clearly.

Document the assumptions about the path pattern more clearly. This will help future developers understand the function's behavior and limitations.

-// this implementation tries to extract at most 3 levels of parent path
+// This implementation tries to extract at most 3 levels of parent path based on the assumption that the path follows the pattern `<data|index>/catalog/schema/table_id/...`.
Tools
GitHub Check: Check typos and docs

[warning] 138-138:
"insuffient" should be "insufficient".

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 395d1f0 and 0e09055.

Files selected for processing (1)
  • src/object-store/src/util.rs (2 hunks)
Additional context used
GitHub Check: Check typos and docs
src/object-store/src/util.rs

[warning] 138-138:
"insuffient" should be "insufficient".

Additional comments not posted (1)
src/object-store/src/util.rs (1)

200-222: Test cases look good.

The test cases for extract_parent_path are comprehensive and cover various scenarios.

src/object-store/src/util.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@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: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 0e09055 and 7daefb6.

Files selected for processing (1)
  • src/object-store/src/util.rs (2 hunks)
Files skipped from review as they are similar to previous changes (1)
  • src/object-store/src/util.rs

@Xuanwo
Copy link
Contributor

Xuanwo commented Jul 4, 2024

Actually I found the Prometheus library has a few runtime panics which I think can be avoided by design. For example, if you provide labels doesn't match the declaration, it ends up with a runtime panics, which is very dangerous for some corner cases.

Would you like to submit an issue to upstream and link back here?

@evenyag
Copy link
Contributor

evenyag commented Jul 4, 2024

Actually I found the Prometheus library has a few runtime panics which I think can be avoided by design. For example, if you provide labels doesn't match the declaration, it ends up with a runtime panics, which is very dangerous for some corner cases.

It provides a method get_metric_with_label_values() that returns an error instead.
https://docs.rs/prometheus/latest/prometheus/core/struct.MetricVec.html#method.get_metric_with_label_values

@evenyag
Copy link
Contributor

evenyag commented Jul 4, 2024

Thanks! I'm also thinking allow users to set metrics or reuse them in someway. I will give it look.

@Xuanwo I can submit a patch for a workaround by adding a method to set the metrics.

impl PrometheusLayer {
    fn metrics(mut self, metrics: Arc<PrometheusMetrics>) -> Self {
        self.metrics = Some(metrics);
        self
    }
}

But this may not be elegant enough.

@WenyXu
Copy link
Member

WenyXu commented Jul 4, 2024

The CI should be fixed in main branch🥲

Copy link
Contributor

@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: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7daefb6 and 4430263.

Files selected for processing (1)
  • src/object-store/src/layers/prometheus.rs (19 hunks)
Additional comments not posted (10)
src/object-store/src/layers/prometheus.rs (10)

131-145: LGTM!

The create_dir function correctly includes the path_label parameter for Prometheus metrics.


Line range hint 157-180:
LGTM!

The read function correctly includes the path_label parameter for Prometheus metrics.


Line range hint 187-210:
LGTM!

The write function correctly includes the path_label parameter for Prometheus metrics.


217-222: LGTM!

The stat function correctly includes the path_label parameter for Prometheus metrics.


234-240: LGTM!

The delete function correctly includes the path_label parameter for Prometheus metrics.


252-258: LGTM!

The list function correctly includes the path_label parameter for Prometheus metrics.


288-294: LGTM!

The presign function correctly includes the path_label parameter for Prometheus metrics.


306-320: LGTM!

The blocking_create_dir function correctly includes the path_label parameter for Prometheus metrics.


333-347: LGTM!

The blocking_read function correctly includes the path_label parameter for Prometheus metrics.


374-388: LGTM!

The blocking_write function correctly includes the path_label parameter for Prometheus metrics.

Copy link
Contributor

@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: 0

Outside diff range and nitpick comments (1)
src/object-store/src/util.rs (1)

126-138: Enhance documentation and handle edge cases.

The function extract_parent_path works as intended, but consider adding more context about its assumptions and limitations. Additionally, handle edge cases explicitly, such as paths with fewer than three levels.

// This logic tries to extract the parent path from the object storage operation.
// The function assumes that the region path is built from the pattern `<data|index>/catalog/schema/table_id/...`.
// This implementation extracts at most 3 levels of the parent path. For paths with fewer levels, it returns the full path.

pub(crate) fn extract_parent_path(path: &str) -> &str {
    let parts: Vec<&str> = path.split('/').collect();
    if parts.len() <= 3 {
        return path; // Return the full path if there are fewer than 3 levels.
    }
    let third_slash_index = parts.iter().take(3).map(|s| s.len() + 1).sum::<usize>() - 1;
    &path[..third_slash_index]
}
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 4430263 and 7e98924.

Files selected for processing (2)
  • src/object-store/src/layers/prometheus.rs (19 hunks)
  • src/object-store/src/util.rs (2 hunks)
Additional comments not posted (14)
src/object-store/src/layers/prometheus.rs (14)

131-137: LGTM!

The method correctly includes the path_label parameter for Prometheus metrics.


Line range hint 149-172:
LGTM!

The method correctly includes the path_label parameter for Prometheus metrics.


Line range hint 179-202:
LGTM!

The method correctly includes the path_label parameter for Prometheus metrics.


209-214: LGTM!

The method correctly includes the path_label parameter for Prometheus metrics.


226-232: LGTM!

The method correctly includes the path_label parameter for Prometheus metrics.


244-250: LGTM!

The method correctly includes the path_label parameter for Prometheus metrics.


264-268: LGTM!

The method does not require the path_label parameter as it operates on multiple paths.


280-286: LGTM!

The method correctly includes the path_label parameter for Prometheus metrics.


298-312: LGTM!

The method correctly includes the path_label parameter for Prometheus metrics.


Line range hint 325-353:
LGTM!

The method correctly includes the path_label parameter for Prometheus metrics.


Line range hint 366-394:
LGTM!

The method correctly includes the path_label parameter for Prometheus metrics.


407-421: LGTM!

The method correctly includes the path_label parameter for Prometheus metrics.


432-446: LGTM!

The method correctly includes the path_label parameter for Prometheus metrics.


458-472: LGTM!

The method correctly includes the path_label parameter for Prometheus metrics.

@zyy17 zyy17 added this pull request to the merge queue Jul 5, 2024
Merged via the queue into GreptimeTeam:main with commit d9efa56 Jul 5, 2024
53 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs-not-required This change does not impact docs.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants