-
Notifications
You must be signed in to change notification settings - Fork 96
feat: add telemetry as part of mount options for blobfuse mounts #2248
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
base: master
Are you sure you want to change the base?
Conversation
This commit adds telemetry=azpartner-aks/<blob-driver-version> as mount options for blobfuse mounts Signed-off-by: [email protected] <[email protected]>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: mittachaitu The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
Welcome @mittachaitu! |
|
Hi @mittachaitu. Thanks for your PR. I'm waiting for a github.com member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
andyzhangx
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/ok-to-test
pkg/blob/nodeserver.go
Outdated
| // Get mountOptions that the volume will be formatted and mounted with | ||
| if protocol == Fuse2 { | ||
| // Adding telemetry tag to know that blob is been mounted through AKS | ||
| mountFlags = util.JoinMountOptions(mountFlags, []string{fmt.Sprintf("--telemetry=azpartner-aks/%s", d.Version)}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
follow the PR example here: #2024 since protocol may be empty here, and also check whether this option is already specified
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, I think just use --telemetry=aks/%s is more straightfoward
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Andy, I have moved the code to under pkg/blobfuse-proxy/server.go and if user specifies the option through StorageClass then we are appending above to telemetry option
ex: In below example user has provided telemetry as part of mount option...
mountOptions:
- -o allow_other
- --file-cache-timeout-in-seconds=120
- --use-attr-cache=true
- --cancel-list-on-mount-seconds=10 # prevent billing charges on mounting
- -o attr_timeout=120
- -o entry_timeout=120
- -o negative_timeout=120
- --telemetry=tire1Then mount args to blobfuse2 will be (--telemetry=azpartner-aks/v1.28.0,normaltest)
server.go:99] updated --telemetry tag in mount args: mount /var/lib/kubelet/plugins/kubernetes.io/csi/blob.csi.azure.com/d6b00230de0d40736dda3f197b49a4919bfb9b7512f4466d881183c6a2baa974/globalmount -o allow_other --file-cache-timeout-in-seconds=120 --use-attr-cache=true --cancel-list-on-mount-seconds=10 -o attr_timeout=120 -o entry_timeout=120 -o negative_timeout=120 --log-level=LOG_DEBUG --cache-size-mb=1000 --telemetry=azpartner-aks/v1.28.0,normaltest --pre-mount-validate=true --use-https=true --empty-dir-check=false --tmp-path=/mnt/<RG>#<Storage Account>#<Contianer>#<Blob>#default# --container-name=traineddata --ignore-open-flags=true --disable-version-check=true
Note: If there is no --telemetry in mount option then --telemetry=azpartner-aks/v1.28.0.
btw, I think just use --telemetry=aks/%s is more straightfoward
The tag has been suggested by @vibhansa-msft, so not sure if there is any monitoring from blobfuse side
This commit moves the logic to add tag to blobfuse-proxy service. If user specifies --telemetry=tire1 as mount option then add azpartner-aks/v1.28.0 value as comma separated value to user provided version (--telemetry=azpartner-aks/v1.28.0,tire1) Signed-off-by: [email protected] <[email protected]>
| klog.V(2).Infof("append --telemetry=%s to mount args", telemetryTag) | ||
| args = args + " " + "--telemetry=" + telemetryTag | ||
| } else { | ||
| // If telemetry flag is already present, check for aks tag if not present |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If telemetry flag is already present, we just respect original setting, I don't think we need to change the original value by force
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If user has some custom tag, then we can't use that for tracking blob usage through AKS. If we just use the original setting then whole purpose to track usage will be lost, so I appended our tag with user specified value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but what if customer only wants to keep the original telemetry? this PR would change the telemetry even user does not want to.
and this adds the telemetry as azpartner-aks in open source driver, which means if it runs on AWS k8s node, it would still have this azpartner-aks telemetry, so maybe use default userAgent as fmt.Sprintf("%s/%s", driverName, driverVersion) is more reasonable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have updated tag to blobpartner-csi/<driver-version>, Concern from blobfuse team is if we go with driver specific tag then it will become costly operation for blobfuse analytics team to parse these tags (since they are expecting all partners should use similar tag instead of each partner goes with different tag).
Signed-off-by: mittachaitu <[email protected]>
|
/retest-required |
Signed-off-by: mittachaitu <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request adds telemetry tracking support for Azure Blob Storage usage through AKS by implementing a telemetry tag prefix in blobfuse mount operations. The implementation adds a version-aware telemetry tag (blobpartner-csi/<version>) to all blobfuse v2 mount operations to enable tracking and monitoring of blob storage access patterns.
Key changes:
- Telemetry tag infrastructure with version injection via build-time ldflags
- Logic to prepend AKS CSI driver telemetry tags to user-provided telemetry values
- Comprehensive test coverage for various telemetry scenarios including existing tags, missing tags, and different blobfuse versions
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| pkg/blobfuse-proxy/server/server.go | Implements telemetry tag injection logic for blobfuse v2 mounts with conditional handling for existing telemetry flags |
| pkg/blobfuse-proxy/server/server_test.go | Adds comprehensive test suite covering telemetry tag injection scenarios with mock command execution |
| Makefile | Updates build configuration to inject driver version into binary via ldflags for telemetry tagging |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ) | ||
|
|
||
| // telemetryTagPrefix is used to identify the mounts done via blobcsi driver | ||
| const telemetryTagPrefix = "blobpartner-csi/" |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The telemetry tag prefix is inconsistent with the PR description. The PR description states the telemetry tag should be "azpartner-aks/", but the implementation uses "blobpartner-csi/". This mismatch needs to be corrected to match the intended telemetry format.
| const telemetryTagPrefix = "blobpartner-csi/" | |
| const telemetryTagPrefix = "azpartner-aks/" |
| splitedArgs := strings.Split(args, "--telemetry=") | ||
| if len(splitedArgs) == 2 { | ||
| args = splitedArgs[0] + " --telemetry=" + telemetryTag + "," + splitedArgs[1] |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in variable name: 'splitedArgs' should be 'splitArgs' or 'splittedArgs'. 'Splited' is not a valid English word; the past tense of 'split' is 'split' or 'splitted' (though 'split' is more common).
| splitedArgs := strings.Split(args, "--telemetry=") | |
| if len(splitedArgs) == 2 { | |
| args = splitedArgs[0] + " --telemetry=" + telemetryTag + "," + splitedArgs[1] | |
| splitArgs := strings.Split(args, "--telemetry=") | |
| if len(splitArgs) == 2 { | |
| args = splitArgs[0] + " --telemetry=" + telemetryTag + "," + splitArgs[1] |
| splitedArgs := strings.Split(args, "--telemetry=") | ||
| if len(splitedArgs) == 2 { | ||
| args = splitedArgs[0] + " --telemetry=" + telemetryTag + "," + splitedArgs[1] | ||
| } | ||
| klog.V(2).Infof("updated --telemetry tag in mount args: %s", args) |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The telemetry string parsing logic has a critical flaw. When splitting by "--telemetry=", if there are multiple occurrences of this substring in args (e.g., in a container name or account name), len(splitedArgs) could be greater than 2, but only the first occurrence is handled. This could result in malformed arguments. Consider using a more robust parsing method such as regular expressions or proper argument parsing to specifically target the --telemetry flag.
| splitedArgs := strings.Split(args, "--telemetry=") | |
| if len(splitedArgs) == 2 { | |
| args = splitedArgs[0] + " --telemetry=" + telemetryTag + "," + splitedArgs[1] | |
| } | |
| klog.V(2).Infof("updated --telemetry tag in mount args: %s", args) | |
| // Split args into slice for robust parsing | |
| argSlice := strings.Fields(args) | |
| telemetryIdx := -1 | |
| for i, arg := range argSlice { | |
| if strings.HasPrefix(arg, "--telemetry=") { | |
| telemetryIdx = i | |
| break | |
| } | |
| } | |
| if telemetryIdx != -1 { | |
| // Update the telemetry tag, appending our tag if not present | |
| telemetryVal := strings.TrimPrefix(argSlice[telemetryIdx], "--telemetry=") | |
| // Avoid duplicate tags | |
| if !strings.Contains(telemetryVal, telemetryTagPrefix) { | |
| argSlice[telemetryIdx] = "--telemetry=" + telemetryTag + "," + telemetryVal | |
| args = strings.Join(argSlice, " ") | |
| klog.V(2).Infof("updated --telemetry tag in mount args: %s", args) | |
| } | |
| } |
| if !strings.Contains(args, telemetryTagPrefix) { | ||
| splitedArgs := strings.Split(args, "--telemetry=") | ||
| if len(splitedArgs) == 2 { | ||
| args = splitedArgs[0] + " --telemetry=" + telemetryTag + "," + splitedArgs[1] |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The string manipulation logic for inserting the telemetry tag creates a potential issue with spacing. The code constructs splitedArgs[0] + " --telemetry=" + telemetryTag + "," + splitedArgs[1], which adds a space before --telemetry= but doesn't trim it from splitedArgs[0]. This could result in double spaces if splitedArgs[0] already ends with a space. Consider using strings.TrimSpace() on splitedArgs[0] before concatenation.
| args = splitedArgs[0] + " --telemetry=" + telemetryTag + "," + splitedArgs[1] | |
| args = strings.TrimSpace(splitedArgs[0]) + " --telemetry=" + telemetryTag + "," + splitedArgs[1] |
| args: "--account-name=testaccount --container-name=testcontainer --tmp-path=/tmp/blobfuse-tmp", | ||
| mountServer: MountServer{ | ||
| blobfuseVersion: BlobfuseV2, | ||
| exec: fakeExecCommandEchoArgs, | ||
| }, | ||
| code: codes.OK, | ||
| areValidTelemetryArgs: func(cmdArgs string) bool { | ||
| expectedTelemetryArg := "--telemetry=" + telemetryTagPrefix + driverVersion | ||
| return strings.Contains(cmdArgs, expectedTelemetryArg) | ||
| }, | ||
| }, | ||
| { | ||
| name: "mount_with_same_telemetry_tag_blobfusev2", | ||
| args: "--account-name=testaccount --container-name=testcontainer --telemetry=" + telemetryTagPrefix + driverVersion, | ||
| mountServer: MountServer{ | ||
| blobfuseVersion: BlobfuseV2, | ||
| exec: fakeExecCommandEchoArgs, | ||
| }, | ||
| code: codes.OK, | ||
| areValidTelemetryArgs: func(cmdArgs string) bool { | ||
| // Argument order should remain unchanged | ||
| return strings.Contains(cmdArgs, "--account-name=testaccount --container-name=testcontainer --telemetry="+telemetryTagPrefix+driverVersion) | ||
| }, | ||
| }, | ||
| { | ||
| name: "mount_with_blobfusev1", | ||
| args: "--account-name=testaccount --container-name=testcontainer --tmp-path=/tmp/blobfuse-tmp", | ||
| mountServer: MountServer{ | ||
| blobfuseVersion: BlobfuseV1, | ||
| exec: fakeExecCommandEchoArgs, | ||
| }, | ||
| code: codes.OK, | ||
| areValidTelemetryArgs: func(cmdArgs string) bool { | ||
| // No telemetry arg should be added for blobfuse v1 | ||
| return !strings.Contains(cmdArgs, "--telemetry=") && cmdArgs == "--account-name=testaccount --container-name=testcontainer --tmp-path=/tmp/blobfuse-tmp" | ||
| }, | ||
| }, |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing test case: The telemetry string manipulation logic in server.go lines 100-103 doesn't have a test case for when len(splitedArgs) != 2 (e.g., when "--telemetry=" appears multiple times in args or not at all in the else branch). This edge case should be tested to ensure the code handles malformed input gracefully without modifying args or causing unexpected behavior.
| } | ||
| klog.V(2).Infof("updated --telemetry tag in mount args: %s", args) |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code silently does nothing when len(splitedArgs) != 2 (line 101 condition). This can occur if the string "--telemetry=" appears multiple times or is part of another parameter value. Consider adding logging (e.g., klog.Warningf) to indicate when the telemetry tag cannot be updated, so operators can identify potential issues with their mount arguments.
| } | |
| klog.V(2).Infof("updated --telemetry tag in mount args: %s", args) | |
| klog.V(2).Infof("updated --telemetry tag in mount args: %s", args) | |
| } else { | |
| klog.Warningf("could not update --telemetry tag in mount args: unexpected format or multiple --telemetry= flags found in args: %s", args) | |
| } |
| if !strings.Contains(args, telemetryTagPrefix) { | ||
| splitedArgs := strings.Split(args, "--telemetry=") | ||
| if len(splitedArgs) == 2 { | ||
| args = splitedArgs[0] + " --telemetry=" + telemetryTag + "," + splitedArgs[1] |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic doesn't handle the edge case where --telemetry= is provided with an empty value (e.g., --telemetry= --other-flag). In this case, splitedArgs[1] would start with a space and a different flag, resulting in malformed telemetry arguments like --telemetry=blobpartner-csi/version, --other-flag. Consider trimming whitespace from splitedArgs[1] and checking if it's empty before concatenating.
| args = splitedArgs[0] + " --telemetry=" + telemetryTag + "," + splitedArgs[1] | |
| telemetryValue := strings.TrimSpace(splitedArgs[1]) | |
| if telemetryValue == "" { | |
| args = splitedArgs[0] + " --telemetry=" + telemetryTag | |
| } else { | |
| args = splitedArgs[0] + " --telemetry=" + telemetryTag + "," + telemetryValue | |
| } |
What type of PR is this?
/ kind bug
What this PR does / why we need it:
This PR adds telemetry=azpartner-aks/ as mount options for blobfuse mounts.
This is required to track, usage of Azure Blob Storage through AKS.
Which issue(s) this PR fixes:
Fixes #
Requirements:
Special notes for your reviewer:
Release note: