Skip to content

Conversation

@gargnitingoogle
Copy link
Collaborator

@gargnitingoogle gargnitingoogle commented Nov 4, 2025

Description

Log flag optimizations (profile/machine-type) in mount logs

This pull request introduces a significant improvement to GCSFuse's logging by capturing and reporting details about configuration flags that are automatically optimized based on factors like machine type or predefined profiles. This change moves from simply listing optimized flags to providing a structured map that includes the final value, the reason for optimization, and whether it was optimized. This enhanced logging will greatly assist in debugging, understanding, and verifying the configuration applied during GCSFuse mounts.

Highlights

  • Enhanced Optimization Logging: The system now logs detailed information about configuration flags that have been optimized based on machine type or profile settings, providing greater transparency into GCSFuse's dynamic configuration adjustments.
  • ApplyOptimizations Signature Change: The ApplyOptimizations function in cfg/config.go and its template now returns a map[string]OptimizationResult instead of a []string, allowing for richer data about each optimized flag.
  • mountInfo Struct Update: A new field, optimizedFlags (type map[string]cfg.OptimizationResult), has been added to the mountInfo struct in cmd/root.go to store the detailed results of flag optimizations.
  • Improved Test Utility: A new helper function, isFlagPresentInOptimizationResults, was introduced in cfg/optimize_test.go to facilitate testing the presence of specific flags within the new optimizedFlags map.
  • Mount Log Integration: The cmd/legacy_main.go file has been updated to include the optimizedFlags in the GCSFuse mount logs, making this information readily available during operation.

Link to the issue in case of a bug fix.

b/456466737

Testing details

  1. Manual - Tested locally. Sample gcsfuse log:
    {"timestamp":{"seconds":1762415296,"nanos":154084615},"severity":"INFO","message":"GCSFuse Config","mount-id":"gargnitin-test-hns-asiase1-9fcf07c7","Optimized Flags":{"file-system":{"rename-dir-limit":{"final_value":200000,"optimization_reason":"machine-type group \"high-performance\""}},"implicit-dirs":{"final_value":true,"optimization_reason":"profile \"aiml-training\""},"metadata-cache":{"negative-ttl-secs":{"final_value":0,"optimization_reason":"profile \"aiml-training\""},"stat-cache-max-size-mb":{"final_value":-1,"optimization_reason":"profile \"aiml-training\""},"ttl-secs":{"final_value":-1,"optimization_reason":"profile \"aiml-training\""},"type-cache-max-size-mb":{"final_value":-1,"optimization_reason":"profile \"aiml-training\""}},"write":{"global-max-blocks":{"final_value":1600,"optimization_reason":"machine-type group \"high-performance\""}}}}
    Sample gke log in cloud console:
5F45cQVTRvE9ij5
  1. Unit tests - NA
  2. Integration tests - Ran as part of presubmit

Any backward incompatible change? If so, please explain.

@gargnitingoogle gargnitingoogle added the execute-integration-tests Run only integration tests label Nov 4, 2025
@gargnitingoogle gargnitingoogle marked this pull request as ready for review November 4, 2025 03:53
@gargnitingoogle gargnitingoogle requested review from a team and Tulsishah as code owners November 4, 2025 03:53
@gargnitingoogle
Copy link
Collaborator Author

/gemini summary

@github-actions
Copy link

github-actions bot commented Nov 4, 2025

/gemini review

@github-actions
Copy link

github-actions bot commented Nov 4, 2025

/gemini summary

@github-actions github-actions bot added the remind-reviewers Auto remind reviewers in attention set for review post 24hrs of inactivity on PR. label Nov 4, 2025
@gargnitingoogle
Copy link
Collaborator Author

/gemini review

@gargnitingoogle gargnitingoogle enabled auto-merge (squash) November 4, 2025 03:54
@gemini-code-assist
Copy link
Contributor

Summary of Changes

This pull request introduces a significant improvement to GCSFuse's logging by capturing and reporting details about configuration flags that are automatically optimized based on factors like machine type or predefined profiles. This change moves from simply listing optimized flags to providing a structured map that includes the final value, the reason for optimization, and whether it was optimized. This enhanced logging will greatly assist in debugging, understanding, and verifying the configuration applied during GCSFuse mounts.

Highlights

  • Enhanced Optimization Logging: The system now logs detailed information about configuration flags that have been optimized based on machine type or profile settings, providing greater transparency into GCSFuse's dynamic configuration adjustments.
  • ApplyOptimizations Signature Change: The ApplyOptimizations function in cfg/config.go and its template now returns a map[string]OptimizationResult instead of a []string, allowing for richer data about each optimized flag.
  • mountInfo Struct Update: A new field, optimizedFlags (type map[string]cfg.OptimizationResult), has been added to the mountInfo struct in cmd/root.go to store the detailed results of flag optimizations.
  • Improved Test Utility: A new helper function, isFlagPresentInOptimizationResults, was introduced in cfg/optimize_test.go to facilitate testing the presence of specific flags within the new optimizedFlags map.
  • Mount Log Integration: The cmd/legacy_main.go file has been updated to include the optimizedFlags in the GCSFuse mount logs, making this information readily available during operation.
Changelog
  • cfg/config.go
    • Changed the return type of ApplyOptimizations from []string to map[string]OptimizationResult.
    • Updated how optimized flags are stored, now mapping flag names to their OptimizationResult objects.
  • cfg/optimize.go
    • Modified the OptimizationReason string format for profile-based optimizations, removing "setting" for conciseness.
  • cfg/optimize_test.go
    • Added isFlagPresentInOptimizationResults helper function to check for flags in the new map structure.
    • Updated test assertions in TestApplyOptimizations_Success to use the new helper function.
  • cmd/legacy_main.go
    • Added a new logger.Info call to log the optimizedFlags map if it contains entries.
  • cmd/root.go
    • Added optimizedFlags map[string]cfg.OptimizationResult field to the mountInfo struct.
    • Updated the call to cfg.Rationalize to pass only the flag names (keys from the optimizedFlags map) instead of the full map.
    • Stored the optimizedFlags map in the mountInfo struct.
  • tools/config-gen/templates/config.tpl
    • Synchronized with cfg/config.go changes, updating the ApplyOptimizations function signature and the method of recording optimized flags within the template.
Activity
  • The author, gargnitingoogle, initiated the PR by requesting a summary.
  • The github-actions[bot] requested a review.
  • The github-actions[bot] requested a summary.
  • The author, gargnitingoogle, requested a review.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request enhances the logging of flag optimizations by changing the ApplyOptimizations function to return a map with detailed optimization results. This provides better insight into why a flag's value was changed. The implementation is sound and correctly propagated through the configuration generation, application logic, and tests. I have a couple of minor suggestions to improve code style and performance.

@meet2mky
Copy link
Collaborator

meet2mky commented Nov 4, 2025

Can you test it once how does these optimisation flags look in the GKE Log Explorer?

@gargnitingoogle
Copy link
Collaborator Author

gargnitingoogle commented Nov 4, 2025

Can you test it once how does these optimisation flags look in the GKE Log Explorer?

Yes, I shared a sample generated log in the PR description in manual testing section. Copying here...

# preexisting log line(s)
{"timestamp":{"seconds":1762273085,"nanos":636732946},"severity":"INFO","message":"Start gcsfuse/unknown (Go version go1.24.8) for app \"\" using mount point: gargnitin-test-hns-asiase1-mount\n","mount-id":"gargnitin-test-hns-asiase1-e7164ab0"}
{"timestamp":{"seconds":1762273085,"nanos":636767706},"severity":"INFO","message":"GCSFuse Config","mount-id":"gargnitin-test-hns-asiase1-e7164ab0","CLI Flags":{"log-format":"json","machine-type":"a2-megagpu-16g","profile":"aiml-training"}}
# New log line(s)
{"timestamp":{"seconds":1762273085,"nanos":636786216},"severity":"INFO","message":"GCSFuse Config","mount-id":"gargnitin-test-hns-asiase1-e7164ab0","Flags optimized":{"file-system.rename-dir-limit":{"FinalValue":200000,"OptimizationReason":"machine-type group \"high-performance\"","Optimized":true},"implicit-dirs":{"FinalValue":true,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.negative-ttl-secs":{"FinalValue":0,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.stat-cache-max-size-mb":{"FinalValue":-1,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.ttl-secs":{"FinalValue":-1,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.type-cache-max-size-mb":{"FinalValue":-1,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"write.global-max-blocks":{"FinalValue":1600,"OptimizationReason":"machine-type group \"high-performance\"","Optimized":true}}}
# preexisting log line(s)
{"timestamp":{"seconds":1762273085,"nanos":636827356},"severity":"INFO","message":"GCSFuse Config","mount-id":"gargnitin-test-hns-asiase1-e7164ab0","Full Config":{"AppName":"","CacheDir":"","CloudProfiler":{"AllocatedHeap":true,"Cpu":true,"Enabled":false,"Goroutines":false,"Heap":true,"Label":"gcsfuse-0.0.0","Mutex":false},"Debug":{"ExitOnInvariantViolation":false,"Fuse":false,"Gcs":false,"LogMutex":false},"DisableAutoconfig":false,"EnableAtomicRenameObject":true,"EnableGoogleLibAuth":true,"EnableHns":true,"EnableNewReader":true,"EnableUnsupportedDirSupport":false,"FileCache":{"CacheFileForRangeRead":false,"DownloadChunkSizeMb":200,"EnableCrc":false,"EnableODirect":false,"EnableParallelDownloads":false,"ExcludeRegex":"","ExperimentalParallelDownloadsDefaultOn":true,"IncludeRegex":"","MaxParallelDownloads":128,"MaxSizeMb":-1,"ParallelDownloadsPerFile":16,"WriteBufferSize":4194304},"FileSystem":{"DirMode":"755","DisableParallelDirops":false,"ExperimentalEnableDentryCache":false,"ExperimentalEnableReaddirplus":false,"FileMode":"644","FuseOptions":[],"Gid":-1,"IgnoreInterrupts":true,"KernelListCacheTtlSecs":0,"ODirect":false,"PreconditionErrors":true,"RenameDirLimit":200000,"TempDir":"","Uid":-1},"Foreground":false,"GcsAuth":{"AnonymousAccess":false,"KeyFile":"","ReuseTokenFromUrl":true,"TokenUrl":""},"GcsConnection":{"BillingProject":"","ClientProtocol":"http1","CustomEndpoint":"","EnableHttpDnsCache":true,"ExperimentalEnableJsonRead":false,"GrpcConnPoolSize":1,"HttpClientTimeout":0,"LimitBytesPerSec":-1,"LimitOpsPerSec":-1,"MaxConnsPerHost":0,"MaxIdleConnsPerHost":100,"SequentialReadSizeMb":200},"GcsRetries":{"ChunkTransferTimeoutSecs":10,"MaxRetryAttempts":0,"MaxRetrySleep":30000000000,"Multiplier":2,"ReadStall":{"Enable":true,"InitialReqTimeout":20000000000,"MaxReqTimeout":1200000000000,"MinReqTimeout":1500000000,"ReqIncreaseRate":15,"ReqTargetPercentile":0.99}},"ImplicitDirs":true,"List":{"EnableEmptyManagedFolders":false},"Logging":{"FilePath":"","Format":"json","LogRotate":{"BackupFileCount":10,"Compress":true,"MaxFileSizeMb":512},"Severity":"INFO"},"MachineType":"a2-megagpu-16g","MetadataCache":{"DeprecatedStatCacheCapacity":20460,"DeprecatedStatCacheTtl":60000000000,"DeprecatedTypeCacheTtl":60000000000,"EnableNonexistentTypeCache":false,"ExperimentalMetadataPrefetchOnMount":"disabled","NegativeTtlSecs":0,"StatCacheMaxSizeMb":17592186044415,"TtlSecs":9223372036,"TypeCacheMaxSizeMb":-1},"Metrics":{"BufferSize":256,"CloudMetricsExportIntervalSecs":0,"PrometheusPort":0,"StackdriverExportInterval":0,"UseNewNames":false,"Workers":3},"Monitoring":{"ExperimentalTracingMode":"","ExperimentalTracingProjectId":"","ExperimentalTracingSamplingRatio":0},"OnlyDir":"","Profile":"aiml-training","Read":{"BlockSizeMb":16,"EnableBufferedRead":false,"GlobalMaxBlocks":40,"InactiveStreamTimeout":10000000000,"MaxBlocksPerHandle":20,"MinBlocksPerHandle":4,"RandomSeekThreshold":3,"StartBlocksPerHandle":1},"WorkloadInsight":{"OutputFile":"","Visualize":false},"Write":{"BlockSizeMb":32,"CreateEmptyFile":false,"EnableRapidAppends":true,"EnableStreamingWrites":true,"FinalizeFileForRapid":false,"GlobalMaxBlocks":1600,"MaxBlocksPerFile":1}}}
{"timestamp":{"seconds":1762273085,"nanos":931233199},"severity":"INFO","message":"File system has been successfully mounted.","mount-id":"gargnitin-test-hns-asiase1-e7164ab0"}

@gargnitingoogle gargnitingoogle force-pushed the gargnitin/log-optimizations-on-startup/v1 branch from 3364d8a to e2230d6 Compare November 4, 2025 16:22
@meet2mky
Copy link
Collaborator

meet2mky commented Nov 4, 2025

Can you test it once how does these optimisation flags look in the GKE Log Explorer?

Yes, I shared a sample generated log in the PR description in manual testing section. Copying here...

# preexisting log line(s)
{"timestamp":{"seconds":1762273085,"nanos":636732946},"severity":"INFO","message":"Start gcsfuse/unknown (Go version go1.24.8) for app \"\" using mount point: gargnitin-test-hns-asiase1-mount\n","mount-id":"gargnitin-test-hns-asiase1-e7164ab0"}
{"timestamp":{"seconds":1762273085,"nanos":636767706},"severity":"INFO","message":"GCSFuse Config","mount-id":"gargnitin-test-hns-asiase1-e7164ab0","CLI Flags":{"log-format":"json","machine-type":"a2-megagpu-16g","profile":"aiml-training"}}
# New log line(s)
{"timestamp":{"seconds":1762273085,"nanos":636786216},"severity":"INFO","message":"GCSFuse Config","mount-id":"gargnitin-test-hns-asiase1-e7164ab0","Flags optimized":{"file-system.rename-dir-limit":{"FinalValue":200000,"OptimizationReason":"machine-type group \"high-performance\"","Optimized":true},"implicit-dirs":{"FinalValue":true,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.negative-ttl-secs":{"FinalValue":0,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.stat-cache-max-size-mb":{"FinalValue":-1,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.ttl-secs":{"FinalValue":-1,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.type-cache-max-size-mb":{"FinalValue":-1,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"write.global-max-blocks":{"FinalValue":1600,"OptimizationReason":"machine-type group \"high-performance\"","Optimized":true}}}
# preexisting log line(s)
{"timestamp":{"seconds":1762273085,"nanos":636827356},"severity":"INFO","message":"GCSFuse Config","mount-id":"gargnitin-test-hns-asiase1-e7164ab0","Full Config":{"AppName":"","CacheDir":"","CloudProfiler":{"AllocatedHeap":true,"Cpu":true,"Enabled":false,"Goroutines":false,"Heap":true,"Label":"gcsfuse-0.0.0","Mutex":false},"Debug":{"ExitOnInvariantViolation":false,"Fuse":false,"Gcs":false,"LogMutex":false},"DisableAutoconfig":false,"EnableAtomicRenameObject":true,"EnableGoogleLibAuth":true,"EnableHns":true,"EnableNewReader":true,"EnableUnsupportedDirSupport":false,"FileCache":{"CacheFileForRangeRead":false,"DownloadChunkSizeMb":200,"EnableCrc":false,"EnableODirect":false,"EnableParallelDownloads":false,"ExcludeRegex":"","ExperimentalParallelDownloadsDefaultOn":true,"IncludeRegex":"","MaxParallelDownloads":128,"MaxSizeMb":-1,"ParallelDownloadsPerFile":16,"WriteBufferSize":4194304},"FileSystem":{"DirMode":"755","DisableParallelDirops":false,"ExperimentalEnableDentryCache":false,"ExperimentalEnableReaddirplus":false,"FileMode":"644","FuseOptions":[],"Gid":-1,"IgnoreInterrupts":true,"KernelListCacheTtlSecs":0,"ODirect":false,"PreconditionErrors":true,"RenameDirLimit":200000,"TempDir":"","Uid":-1},"Foreground":false,"GcsAuth":{"AnonymousAccess":false,"KeyFile":"","ReuseTokenFromUrl":true,"TokenUrl":""},"GcsConnection":{"BillingProject":"","ClientProtocol":"http1","CustomEndpoint":"","EnableHttpDnsCache":true,"ExperimentalEnableJsonRead":false,"GrpcConnPoolSize":1,"HttpClientTimeout":0,"LimitBytesPerSec":-1,"LimitOpsPerSec":-1,"MaxConnsPerHost":0,"MaxIdleConnsPerHost":100,"SequentialReadSizeMb":200},"GcsRetries":{"ChunkTransferTimeoutSecs":10,"MaxRetryAttempts":0,"MaxRetrySleep":30000000000,"Multiplier":2,"ReadStall":{"Enable":true,"InitialReqTimeout":20000000000,"MaxReqTimeout":1200000000000,"MinReqTimeout":1500000000,"ReqIncreaseRate":15,"ReqTargetPercentile":0.99}},"ImplicitDirs":true,"List":{"EnableEmptyManagedFolders":false},"Logging":{"FilePath":"","Format":"json","LogRotate":{"BackupFileCount":10,"Compress":true,"MaxFileSizeMb":512},"Severity":"INFO"},"MachineType":"a2-megagpu-16g","MetadataCache":{"DeprecatedStatCacheCapacity":20460,"DeprecatedStatCacheTtl":60000000000,"DeprecatedTypeCacheTtl":60000000000,"EnableNonexistentTypeCache":false,"ExperimentalMetadataPrefetchOnMount":"disabled","NegativeTtlSecs":0,"StatCacheMaxSizeMb":17592186044415,"TtlSecs":9223372036,"TypeCacheMaxSizeMb":-1},"Metrics":{"BufferSize":256,"CloudMetricsExportIntervalSecs":0,"PrometheusPort":0,"StackdriverExportInterval":0,"UseNewNames":false,"Workers":3},"Monitoring":{"ExperimentalTracingMode":"","ExperimentalTracingProjectId":"","ExperimentalTracingSamplingRatio":0},"OnlyDir":"","Profile":"aiml-training","Read":{"BlockSizeMb":16,"EnableBufferedRead":false,"GlobalMaxBlocks":40,"InactiveStreamTimeout":10000000000,"MaxBlocksPerHandle":20,"MinBlocksPerHandle":4,"RandomSeekThreshold":3,"StartBlocksPerHandle":1},"WorkloadInsight":{"OutputFile":"","Visualize":false},"Write":{"BlockSizeMb":32,"CreateEmptyFile":false,"EnableRapidAppends":true,"EnableStreamingWrites":true,"FinalizeFileForRapid":false,"GlobalMaxBlocks":1600,"MaxBlocksPerFile":1}}}
{"timestamp":{"seconds":1762273085,"nanos":931233199},"severity":"INFO","message":"File system has been successfully mounted.","mount-id":"gargnitin-test-hns-asiase1-e7164ab0"}

I was asking about how it gets parsed in the LogExplorer so that we can be sure all of the fields are correctly displaying in the json format in the LogExplorer.

@gargnitingoogle
Copy link
Collaborator Author

Can you test it once how does these optimisation flags look in the GKE Log Explorer?

Yes, I shared a sample generated log in the PR description in manual testing section. Copying here...

# preexisting log line(s)
{"timestamp":{"seconds":1762273085,"nanos":636732946},"severity":"INFO","message":"Start gcsfuse/unknown (Go version go1.24.8) for app \"\" using mount point: gargnitin-test-hns-asiase1-mount\n","mount-id":"gargnitin-test-hns-asiase1-e7164ab0"}
{"timestamp":{"seconds":1762273085,"nanos":636767706},"severity":"INFO","message":"GCSFuse Config","mount-id":"gargnitin-test-hns-asiase1-e7164ab0","CLI Flags":{"log-format":"json","machine-type":"a2-megagpu-16g","profile":"aiml-training"}}
# New log line(s)
{"timestamp":{"seconds":1762273085,"nanos":636786216},"severity":"INFO","message":"GCSFuse Config","mount-id":"gargnitin-test-hns-asiase1-e7164ab0","Flags optimized":{"file-system.rename-dir-limit":{"FinalValue":200000,"OptimizationReason":"machine-type group \"high-performance\"","Optimized":true},"implicit-dirs":{"FinalValue":true,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.negative-ttl-secs":{"FinalValue":0,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.stat-cache-max-size-mb":{"FinalValue":-1,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.ttl-secs":{"FinalValue":-1,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.type-cache-max-size-mb":{"FinalValue":-1,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"write.global-max-blocks":{"FinalValue":1600,"OptimizationReason":"machine-type group \"high-performance\"","Optimized":true}}}
# preexisting log line(s)
{"timestamp":{"seconds":1762273085,"nanos":636827356},"severity":"INFO","message":"GCSFuse Config","mount-id":"gargnitin-test-hns-asiase1-e7164ab0","Full Config":{"AppName":"","CacheDir":"","CloudProfiler":{"AllocatedHeap":true,"Cpu":true,"Enabled":false,"Goroutines":false,"Heap":true,"Label":"gcsfuse-0.0.0","Mutex":false},"Debug":{"ExitOnInvariantViolation":false,"Fuse":false,"Gcs":false,"LogMutex":false},"DisableAutoconfig":false,"EnableAtomicRenameObject":true,"EnableGoogleLibAuth":true,"EnableHns":true,"EnableNewReader":true,"EnableUnsupportedDirSupport":false,"FileCache":{"CacheFileForRangeRead":false,"DownloadChunkSizeMb":200,"EnableCrc":false,"EnableODirect":false,"EnableParallelDownloads":false,"ExcludeRegex":"","ExperimentalParallelDownloadsDefaultOn":true,"IncludeRegex":"","MaxParallelDownloads":128,"MaxSizeMb":-1,"ParallelDownloadsPerFile":16,"WriteBufferSize":4194304},"FileSystem":{"DirMode":"755","DisableParallelDirops":false,"ExperimentalEnableDentryCache":false,"ExperimentalEnableReaddirplus":false,"FileMode":"644","FuseOptions":[],"Gid":-1,"IgnoreInterrupts":true,"KernelListCacheTtlSecs":0,"ODirect":false,"PreconditionErrors":true,"RenameDirLimit":200000,"TempDir":"","Uid":-1},"Foreground":false,"GcsAuth":{"AnonymousAccess":false,"KeyFile":"","ReuseTokenFromUrl":true,"TokenUrl":""},"GcsConnection":{"BillingProject":"","ClientProtocol":"http1","CustomEndpoint":"","EnableHttpDnsCache":true,"ExperimentalEnableJsonRead":false,"GrpcConnPoolSize":1,"HttpClientTimeout":0,"LimitBytesPerSec":-1,"LimitOpsPerSec":-1,"MaxConnsPerHost":0,"MaxIdleConnsPerHost":100,"SequentialReadSizeMb":200},"GcsRetries":{"ChunkTransferTimeoutSecs":10,"MaxRetryAttempts":0,"MaxRetrySleep":30000000000,"Multiplier":2,"ReadStall":{"Enable":true,"InitialReqTimeout":20000000000,"MaxReqTimeout":1200000000000,"MinReqTimeout":1500000000,"ReqIncreaseRate":15,"ReqTargetPercentile":0.99}},"ImplicitDirs":true,"List":{"EnableEmptyManagedFolders":false},"Logging":{"FilePath":"","Format":"json","LogRotate":{"BackupFileCount":10,"Compress":true,"MaxFileSizeMb":512},"Severity":"INFO"},"MachineType":"a2-megagpu-16g","MetadataCache":{"DeprecatedStatCacheCapacity":20460,"DeprecatedStatCacheTtl":60000000000,"DeprecatedTypeCacheTtl":60000000000,"EnableNonexistentTypeCache":false,"ExperimentalMetadataPrefetchOnMount":"disabled","NegativeTtlSecs":0,"StatCacheMaxSizeMb":17592186044415,"TtlSecs":9223372036,"TypeCacheMaxSizeMb":-1},"Metrics":{"BufferSize":256,"CloudMetricsExportIntervalSecs":0,"PrometheusPort":0,"StackdriverExportInterval":0,"UseNewNames":false,"Workers":3},"Monitoring":{"ExperimentalTracingMode":"","ExperimentalTracingProjectId":"","ExperimentalTracingSamplingRatio":0},"OnlyDir":"","Profile":"aiml-training","Read":{"BlockSizeMb":16,"EnableBufferedRead":false,"GlobalMaxBlocks":40,"InactiveStreamTimeout":10000000000,"MaxBlocksPerHandle":20,"MinBlocksPerHandle":4,"RandomSeekThreshold":3,"StartBlocksPerHandle":1},"WorkloadInsight":{"OutputFile":"","Visualize":false},"Write":{"BlockSizeMb":32,"CreateEmptyFile":false,"EnableRapidAppends":true,"EnableStreamingWrites":true,"FinalizeFileForRapid":false,"GlobalMaxBlocks":1600,"MaxBlocksPerFile":1}}}
{"timestamp":{"seconds":1762273085,"nanos":931233199},"severity":"INFO","message":"File system has been successfully mounted.","mount-id":"gargnitin-test-hns-asiase1-e7164ab0"}

I was asking about how it gets parsed in the LogExplorer so that we can be sure all of the fields are correctly displaying in the json format in the LogExplorer.

ok, I'll test it in gke and share.

@codecov
Copy link

codecov bot commented Nov 4, 2025

Codecov Report

❌ Patch coverage is 75.00000% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.06%. Comparing base (1c5f551) to head (43963b2).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
cmd/root.go 33.33% 4 Missing and 2 partials ⚠️
cmd/legacy_main.go 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3965      +/-   ##
==========================================
+ Coverage   83.05%   83.06%   +0.01%     
==========================================
  Files         148      148              
  Lines       18149    18185      +36     
==========================================
+ Hits        15074    15106      +32     
- Misses       2523     2527       +4     
  Partials      552      552              
Flag Coverage Δ
unittests 83.06% <75.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@gargnitingoogle
Copy link
Collaborator Author

Can you test it once how does these optimisation flags look in the GKE Log Explorer?

Yes, I shared a sample generated log in the PR description in manual testing section. Copying here...

# preexisting log line(s)
{"timestamp":{"seconds":1762273085,"nanos":636732946},"severity":"INFO","message":"Start gcsfuse/unknown (Go version go1.24.8) for app \"\" using mount point: gargnitin-test-hns-asiase1-mount\n","mount-id":"gargnitin-test-hns-asiase1-e7164ab0"}
{"timestamp":{"seconds":1762273085,"nanos":636767706},"severity":"INFO","message":"GCSFuse Config","mount-id":"gargnitin-test-hns-asiase1-e7164ab0","CLI Flags":{"log-format":"json","machine-type":"a2-megagpu-16g","profile":"aiml-training"}}
# New log line(s)
{"timestamp":{"seconds":1762273085,"nanos":636786216},"severity":"INFO","message":"GCSFuse Config","mount-id":"gargnitin-test-hns-asiase1-e7164ab0","Flags optimized":{"file-system.rename-dir-limit":{"FinalValue":200000,"OptimizationReason":"machine-type group \"high-performance\"","Optimized":true},"implicit-dirs":{"FinalValue":true,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.negative-ttl-secs":{"FinalValue":0,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.stat-cache-max-size-mb":{"FinalValue":-1,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.ttl-secs":{"FinalValue":-1,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"metadata-cache.type-cache-max-size-mb":{"FinalValue":-1,"OptimizationReason":"profile \"aiml-training\"","Optimized":true},"write.global-max-blocks":{"FinalValue":1600,"OptimizationReason":"machine-type group \"high-performance\"","Optimized":true}}}
# preexisting log line(s)
{"timestamp":{"seconds":1762273085,"nanos":636827356},"severity":"INFO","message":"GCSFuse Config","mount-id":"gargnitin-test-hns-asiase1-e7164ab0","Full Config":{"AppName":"","CacheDir":"","CloudProfiler":{"AllocatedHeap":true,"Cpu":true,"Enabled":false,"Goroutines":false,"Heap":true,"Label":"gcsfuse-0.0.0","Mutex":false},"Debug":{"ExitOnInvariantViolation":false,"Fuse":false,"Gcs":false,"LogMutex":false},"DisableAutoconfig":false,"EnableAtomicRenameObject":true,"EnableGoogleLibAuth":true,"EnableHns":true,"EnableNewReader":true,"EnableUnsupportedDirSupport":false,"FileCache":{"CacheFileForRangeRead":false,"DownloadChunkSizeMb":200,"EnableCrc":false,"EnableODirect":false,"EnableParallelDownloads":false,"ExcludeRegex":"","ExperimentalParallelDownloadsDefaultOn":true,"IncludeRegex":"","MaxParallelDownloads":128,"MaxSizeMb":-1,"ParallelDownloadsPerFile":16,"WriteBufferSize":4194304},"FileSystem":{"DirMode":"755","DisableParallelDirops":false,"ExperimentalEnableDentryCache":false,"ExperimentalEnableReaddirplus":false,"FileMode":"644","FuseOptions":[],"Gid":-1,"IgnoreInterrupts":true,"KernelListCacheTtlSecs":0,"ODirect":false,"PreconditionErrors":true,"RenameDirLimit":200000,"TempDir":"","Uid":-1},"Foreground":false,"GcsAuth":{"AnonymousAccess":false,"KeyFile":"","ReuseTokenFromUrl":true,"TokenUrl":""},"GcsConnection":{"BillingProject":"","ClientProtocol":"http1","CustomEndpoint":"","EnableHttpDnsCache":true,"ExperimentalEnableJsonRead":false,"GrpcConnPoolSize":1,"HttpClientTimeout":0,"LimitBytesPerSec":-1,"LimitOpsPerSec":-1,"MaxConnsPerHost":0,"MaxIdleConnsPerHost":100,"SequentialReadSizeMb":200},"GcsRetries":{"ChunkTransferTimeoutSecs":10,"MaxRetryAttempts":0,"MaxRetrySleep":30000000000,"Multiplier":2,"ReadStall":{"Enable":true,"InitialReqTimeout":20000000000,"MaxReqTimeout":1200000000000,"MinReqTimeout":1500000000,"ReqIncreaseRate":15,"ReqTargetPercentile":0.99}},"ImplicitDirs":true,"List":{"EnableEmptyManagedFolders":false},"Logging":{"FilePath":"","Format":"json","LogRotate":{"BackupFileCount":10,"Compress":true,"MaxFileSizeMb":512},"Severity":"INFO"},"MachineType":"a2-megagpu-16g","MetadataCache":{"DeprecatedStatCacheCapacity":20460,"DeprecatedStatCacheTtl":60000000000,"DeprecatedTypeCacheTtl":60000000000,"EnableNonexistentTypeCache":false,"ExperimentalMetadataPrefetchOnMount":"disabled","NegativeTtlSecs":0,"StatCacheMaxSizeMb":17592186044415,"TtlSecs":9223372036,"TypeCacheMaxSizeMb":-1},"Metrics":{"BufferSize":256,"CloudMetricsExportIntervalSecs":0,"PrometheusPort":0,"StackdriverExportInterval":0,"UseNewNames":false,"Workers":3},"Monitoring":{"ExperimentalTracingMode":"","ExperimentalTracingProjectId":"","ExperimentalTracingSamplingRatio":0},"OnlyDir":"","Profile":"aiml-training","Read":{"BlockSizeMb":16,"EnableBufferedRead":false,"GlobalMaxBlocks":40,"InactiveStreamTimeout":10000000000,"MaxBlocksPerHandle":20,"MinBlocksPerHandle":4,"RandomSeekThreshold":3,"StartBlocksPerHandle":1},"WorkloadInsight":{"OutputFile":"","Visualize":false},"Write":{"BlockSizeMb":32,"CreateEmptyFile":false,"EnableRapidAppends":true,"EnableStreamingWrites":true,"FinalizeFileForRapid":false,"GlobalMaxBlocks":1600,"MaxBlocksPerFile":1}}}
{"timestamp":{"seconds":1762273085,"nanos":931233199},"severity":"INFO","message":"File system has been successfully mounted.","mount-id":"gargnitin-test-hns-asiase1-e7164ab0"}

I was asking about how it gets parsed in the LogExplorer so that we can be sure all of the fields are correctly displaying in the json format in the LogExplorer.

ok, I'll test it in gke and share.

Sample log: https://cloudlogging.app.goo.gl/Rj5AY9UM7ANfAn8FA

6eEzKYHJTsFPpe6

@meet2mky
Copy link
Collaborator

meet2mky commented Nov 4, 2025

Is the Optimized: true would ever be false in the Flags Optimized?

@meet2mky
Copy link
Collaborator

meet2mky commented Nov 4, 2025

Also why do we need . dot within the flag names in the logs?

@gargnitingoogle
Copy link
Collaborator Author

@meet2mky I've updated the logs to both hide the Optimized: True value as well has have made the flag name hierarchical to be consistent with the rest of flag logs .

Latest log: https://cloudlogging.app.goo.gl/AapxGw2qMHL7uzZ99

@gargnitingoogle
Copy link
Collaborator Author

/gemini review

@gargnitingoogle
Copy link
Collaborator Author

/gemini summary

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request significantly improves the logging of optimized configuration flags by providing a structured map with detailed information. The changes are well-implemented, and the addition of tests for the new hierarchical map creation logic is appreciated. My main feedback is to address code duplication by centralizing the createHierarchicalOptimizedFlags function.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

This pull request significantly enhances GCSFuse's logging capabilities by providing detailed, structured information about configuration flags that are automatically optimized based on machine type or predefined profiles. Instead of a simple list, the logs now include the final value, the reason for optimization, and whether a flag was optimized, greatly aiding in debugging and verifying GCSFuse configurations.

Highlights

  • Enhanced Optimization Logging: The system now logs detailed information about configuration flags that have been optimized based on machine type or profile settings, providing greater transparency into GCSFuse's dynamic configuration adjustments.
  • ApplyOptimizations Signature Change: The ApplyOptimizations function in cfg/config.go and its template now returns a map[string]OptimizationResult instead of a []string, allowing for richer data about each optimized flag.
  • mountInfo Struct Update: A new field, optimizedFlags (type map[string]cfg.OptimizationResult), has been added to the mountInfo struct in cmd/root.go to store the detailed results of flag optimizations.
  • Improved Test Utility: A new helper function, isFlagPresentInOptimizationResults, was introduced in cfg/optimize_test.go to facilitate testing the presence of specific flags within the new optimizedFlags map.
  • Mount Log Integration: The cmd/legacy_main.go file has been updated to include the optimizedFlags in the GCSFuse mount logs, making this information readily available during operation.
Changelog
  • cfg/config.go
    • Changed the return type of ApplyOptimizations from []string to map[string]OptimizationResult to store richer details about optimized flags.
    • Updated how optimized flags are stored, now mapping flag names to their OptimizationResult objects.
  • cfg/optimize.go
    • Updated the OptimizationResult struct with yaml and json tags, hiding the Optimized field from serialization.
    • Removed unused struct definitions: flagOverrideSet, machineType, and optimizationConfig.
    • Modified the OptimizationReason string format for profile-based optimizations for conciseness.
    • Added a new helper function createHierarchicalOptimizedFlags to convert flat optimization results into a nested map structure.
  • cfg/optimize_test.go
    • Introduced a new helper function isFlagPresentInOptimizationResults to simplify testing for specific flags within the optimizedFlags map.
    • Updated existing test assertions in TestApplyOptimizations_Success to utilize the new helper function.
    • Added comprehensive test cases for createHierarchicalOptimizedFlags, covering various nesting scenarios and key conflict detection.
  • cmd/legacy_main.go
    • Added a duplicate createHierarchicalOptimizedFlags function (note: this is a known code duplication issue).
    • Updated logGCSFuseMountInformation to include a new log entry for Optimized Flags when the map is not empty.
  • cmd/root.go
    • Added optimizedFlags map[string]any field to the mountInfo struct to store hierarchical optimization results.
    • Imported maps and slices packages.
    • Modified the call to cfg.Rationalize to pass only the names (keys) of the optimized flags.
    • Integrated createHierarchicalOptimizedFlags to transform the flat optimizedFlags map into a hierarchical structure for logging, with a fallback to a flat map in case of errors.
  • tools/config-gen/templates/config.tpl
    • Synchronized with cfg/config.go changes, updating the ApplyOptimizations function signature.
    • Adjusted the method of recording optimized flags within the template to store OptimizationResult objects in a map.
Activity
  • The author, gargnitingoogle, initiated the PR by requesting summary and review from the bot.
  • A bot review suggested simplifying the isFlagPresentInOptimizationResults helper function and pre-allocating slices for better performance, which the author subsequently addressed.
  • Reviewer meet2mky inquired about the appearance of optimized flags in GKE Log Explorer.
  • The author provided a sample log and later a screenshot from GKE Log Explorer to demonstrate the logging format.
  • meet2mky followed up with questions regarding the Optimized: true field and the use of dot notation in flag names within the logs.
  • The author updated the logging mechanism to hide the Optimized field and present flag names hierarchically, providing a new sample log and screenshot.
  • Codecov reported 50% patch coverage with 3 lines missing coverage, specifically in cmd/legacy_main.go and cmd/root.go.
  • A recent bot review highlighted a duplicate createHierarchicalOptimizedFlags function in cmd/legacy_main.go and cfg/optimize.go, recommending its centralization.

@meet2mky
Copy link
Collaborator

meet2mky commented Nov 5, 2025

Output is looking great 💯 , do we already have this method in cfg package? please review the gemini comment.

@gargnitingoogle
Copy link
Collaborator Author

gargnitingoogle commented Nov 5, 2025

do we already have this method in cfg package? please review the gemini comment.

No, it was a unintentional dup because of a miss in refactor. Fixed it now.

Copy link
Collaborator

@meet2mky meet2mky left a comment

Choose a reason for hiding this comment

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

Few minor comments.

@gargnitingoogle gargnitingoogle force-pushed the gargnitin/log-optimizations-on-startup/v1 branch from ae035c0 to 4703c81 Compare November 6, 2025 06:43
meet2mky
meet2mky previously approved these changes Nov 6, 2025
Copy link
Collaborator

@meet2mky meet2mky left a comment

Choose a reason for hiding this comment

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

Looks good to me.

@gargnitingoogle gargnitingoogle force-pushed the gargnitin/log-optimizations-on-startup/v1 branch from 3baad76 to c404b90 Compare November 7, 2025 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

execute-integration-tests Run only integration tests remind-reviewers Auto remind reviewers in attention set for review post 24hrs of inactivity on PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants