-
Notifications
You must be signed in to change notification settings - Fork 13
Support vernier metadata #165
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: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,10 @@ class VernierBackend < BaseBackend | |
| :retained, | ||
| ].freeze | ||
|
|
||
| PRIVATE_METADATA = [ | ||
| :started_at, # started_at uses a monotonic source, not realtime | ||
| ].freeze | ||
|
|
||
| class << self | ||
| def name | ||
| :vernier | ||
|
|
@@ -43,7 +47,9 @@ def start(params = {}) | |
| @mode = params.delete(:mode) || DEFAULTS[:mode] | ||
| raise ArgumentError unless AVAILABLE_MODES.include?(@mode) | ||
|
|
||
| @metadata = params.delete(:metadata) | ||
| if Gem.loaded_specs["vernier"].version < Gem::Version.new("1.7.0") | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In 1.7.0 or greater, we can just pass it directly as as it was added in https://github.com/jhawthorn/vernier/pull/145/files |
||
| @metadata = params.delete(:metadata) | ||
| end | ||
| clear | ||
|
|
||
| @collector ||= ::Vernier::Collector.new(@mode, **params) | ||
|
|
@@ -74,11 +80,19 @@ def results | |
|
|
||
| return unless vernier_profile | ||
|
|
||
| # Store all vernier metadata | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Vernier stores some "internal" metadata that is actually interesting to us and we want to have in the output. We'll copy these to "user metadata" |
||
| meta = vernier_profile.meta.reject { |k, v| k == :user_metadata || v.nil? || PRIVATE_METADATA.include?(k) } | ||
| meta.merge!(@metadata) if @metadata | ||
|
|
||
| # Internal metadata takes precedence over user metadata, but store | ||
| # everything in user metadata | ||
| vernier_profile.meta[:user_metadata]&.merge!(meta) | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The merge order here matters, so if a user supplied a key that is otherwise internal, the internal one takes precedence since we are jamming both into the same "namespace". |
||
|
|
||
| # HACK: - "data" is private, but we want to avoid serializing to JSON then | ||
| # parsing back from JSON by just directly getting the hash | ||
| data = ::Vernier::Output::Firefox.new(vernier_profile).send(:data) | ||
| data[:meta][:mode] = @mode # TODO: https://github.com/jhawthorn/vernier/issues/30 | ||
| data[:meta].merge!(@metadata) if @metadata | ||
| data[:meta][:mode] = @mode | ||
| data[:meta][:vernierUserMetadata] ||= meta # for compatibility with < 1.7.0 | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for metadata, we now read directly from this output key. To be compatible with older versions of vernier, we'll store the metadata that was added by the user here if it doesn't exist. |
||
| @mode = nil | ||
| @metadata = nil | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -77,7 +77,7 @@ def teardown | |
| assert_instance_of(AppProfiler::VernierProfile, profile) | ||
| assert_equal("wowza", profile.id) | ||
| assert_equal("bar", profile.context) | ||
| assert_equal("spam", profile[:meta][:extrameta]) | ||
| assert_equal("spam", profile.metadata[:extrameta]) | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was already a bit leaky, we should have been accessing it through the metadata helper method. |
||
| end | ||
|
|
||
| test ".run wall profile" do | ||
|
|
@@ -200,6 +200,50 @@ def teardown | |
|
|
||
| assert_nil(AppProfiler.profiler.results) | ||
| end | ||
|
|
||
| test ".results contain vernierUserMetadata, and extra meta" do | ||
| skip "metadata output added in >=1.7.0" if Gem.loaded_specs["vernier"].version < Gem::Version.new("1.7.0") | ||
|
|
||
| profile = AppProfiler.profiler.run( | ||
| vernier_params( | ||
| interval: 2000, | ||
| metadata: { | ||
| user_data_1: "foo", | ||
| user_data_2: "bar", | ||
| interval: 1000, | ||
| }, | ||
| ), | ||
| ) do | ||
| sleep(0.1) | ||
| end | ||
|
|
||
| assert_instance_of(AppProfiler::VernierProfile, profile) | ||
|
|
||
| # Stores "internal" vernier metadata | ||
| assert_equal(:wall, profile.metadata[:mode]) | ||
| assert_equal(2000, profile.metadata[:interval]) # The internal value takes precedence over the user value | ||
| assert_equal(0, profile.metadata[:allocation_interval]) | ||
| assert_equal(false, profile.metadata[:gc]) | ||
|
|
||
| # Don't include ignored/private metadata | ||
| AppProfiler::Backend::VernierBackend::PRIVATE_METADATA.each do |excluded| | ||
| refute_includes(profile.metadata, excluded) | ||
| end | ||
|
|
||
| # Stores the user supplied data | ||
| assert_equal("foo", profile.metadata[:user_data_1]) | ||
| assert_equal("foo", profile.metadata[:user_data_1]) | ||
|
|
||
| # Check that "extra" meta (for UI display) is also present | ||
| { | ||
| user_data_1: "foo", | ||
| user_data_2: "bar", | ||
| interval: 2000, | ||
| mode: :wall, | ||
| }.each do |k, v| | ||
| assert(profile[:meta][:extra].first[:entries].find { |e| e[:label] == k && e[:value] == v }) | ||
| end | ||
| end | ||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,7 @@ | |
| module AppProfiler | ||
| class VernierProfileTest < TestCase | ||
| test ".from_vernier assigns id and context metadata" do | ||
| profile = BaseProfile.from_vernier(vernier_profile(meta: { id: "foo", context: "bar" })) | ||
| profile = BaseProfile.from_vernier(vernier_profile(meta: { vernierUserMetadata: { id: "foo", context: "bar" } })) | ||
|
|
||
| assert_equal("foo", profile.id) | ||
| assert_equal("foo", ProfileId.current) | ||
|
|
@@ -97,14 +97,19 @@ class VernierProfileTest < TestCase | |
| end | ||
|
|
||
| test "#[] forwards to profile metadata" do | ||
| profile = VernierProfile.new(vernier_profile(meta: { interval: 10_000 })) | ||
| profile = VernierProfile.new(vernier_profile(meta: { vernierUserMetadata: { interval: 10_000 } })) | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we are creating a "Mock" profile, these calls to |
||
|
|
||
| assert_equal(10_000, profile.metadata[:interval]) | ||
| end | ||
|
|
||
| test "#path raises an UnsafeFilename exception given chars not in allow list" do | ||
| assert_raises(AppProfiler::BaseProfile::UnsafeFilename) do | ||
| profile = BaseProfile.from_vernier(vernier_profile(meta: { id: "|`@${}", context: "bar" })) | ||
| profile = BaseProfile.from_vernier(vernier_profile(meta: { | ||
| vernierUserMetadata: { | ||
| id: "|`@${}", | ||
| context: "bar", | ||
| }, | ||
| })) | ||
| profile.file | ||
| end | ||
| end | ||
|
|
@@ -126,7 +131,7 @@ class VernierProfileTest < TestCase | |
| test "#file uses custom profile_file_name block when provided" do | ||
| old_profile_file_name = AppProfiler.profile_file_name | ||
| AppProfiler.profile_file_name = ->(metadata) { "file-name-#{metadata[:id]}" } | ||
| profile = VernierProfile.new(vernier_profile(meta: { id: "foo", context: "bar" })) | ||
| profile = VernierProfile.new(vernier_profile(meta: { vernierUserMetadata: { id: "foo", context: "bar" } })) | ||
| assert_match("file-name-foo.vernier.json", File.basename(profile.file.to_s)) | ||
| ensure | ||
| AppProfiler.profile_file_name = old_profile_file_name | ||
|
|
||
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.
Bump this for local development of vernier, so that all tests will run.