Module: StyleCapsule::Instrumentation
- Defined in:
- lib/style_capsule/instrumentation.rb
Overview
Centralized instrumentation module for StyleCapsule
Provides efficient, non-blocking instrumentation using ActiveSupport::Notifications. Metrics (time, size) are only calculated when subscribers are present, ensuring zero performance impact when instrumentation is not being used.
All events follow Rails naming convention: style_capsule.module.event
Class Method Summary collapse
-
.available? ⇒ Boolean
Check if ActiveSupport::Notifications is available.
-
.instrument(event_name, payload = {}) { ... } ⇒ Object
Instrument an operation with automatic timing and size metrics.
-
.instrument_css_processing(strategy:, component_class:, capsule_id:, css_content:) { ... } ⇒ String
Instrument CSS processing operations.
-
.instrument_fallback(component_class:, capsule_id:, original_path:, fallback_path:, exception:, exception_object:) ⇒ void
Instrument fallback to temporary directory.
-
.instrument_fallback_failure(component_class:, capsule_id:, original_path:, fallback_path:, original_exception:, original_exception_object:, fallback_exception:, fallback_exception_object:) ⇒ void
Instrument fallback failure (both original and fallback failed).
-
.instrument_file_write(component_class:, capsule_id:, file_path:, size:) { ... } ⇒ Object
Instrument CSS file write operations.
-
.instrument_registration(namespace:, file_path: nil, inline_size: nil, cache_strategy: :none) { ... } ⇒ Object
Instrument stylesheet registration.
-
.instrument_write_failure(component_class:, capsule_id:, file_path:, exception:, exception_object:) ⇒ void
Instrument write failure (non-permission errors).
-
.notify(event_name, payload = {}) ⇒ void
Instrument an event without a block (for events that don't have duration).
Class Method Details
.available? ⇒ Boolean
Check if ActiveSupport::Notifications is available
34 35 36 |
# File 'lib/style_capsule/instrumentation.rb', line 34 def self.available? !!defined?(ActiveSupport::Notifications) end |
.instrument(event_name, payload = {}) { ... } ⇒ Object
Instrument an operation with automatic timing and size metrics
This method is highly efficient:
- Only measures time if subscribers exist (ActiveSupport::Notifications is optimized for this)
- Only calculates sizes if subscribers exist (lazy evaluation)
- Uses monotonic time for accurate measurements
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/style_capsule/instrumentation.rb', line 61 def self.instrument(event_name, payload = {}, &block) return yield unless available? # Check if there are any subscribers (ActiveSupport optimizes this check) # If no subscribers, just execute the block without any overhead unless ActiveSupport::Notifications.notifier.listening?(event_name) return yield end apply_input_size!(payload) # Use ActiveSupport::Notifications.instrument which automatically: # - Measures duration using monotonic time (available in event.duration) # - Only does work if subscribers exist (zero overhead if no subscribers) # Note: output_size is not included in payload (subscribers can calculate from result if needed) result = nil ActiveSupport::Notifications.instrument(event_name, payload) do result = yield result end result end |
.instrument_css_processing(strategy:, component_class:, capsule_id:, css_content:) { ... } ⇒ String
Instrument CSS processing operations
124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/style_capsule/instrumentation.rb', line 124 def self.instrument_css_processing(strategy:, component_class:, capsule_id:, css_content:, &block) component_name = component_class.is_a?(Class) ? component_class.name : component_class.to_s instrument( "style_capsule.css_processor.scope", strategy: strategy, component_class: component_name, capsule_id: capsule_id, css_content: css_content ) do result = yield result end end |
.instrument_fallback(component_class:, capsule_id:, original_path:, fallback_path:, exception:, exception_object:) ⇒ void
This method returns an undefined value.
Instrument fallback to temporary directory
168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/style_capsule/instrumentation.rb', line 168 def self.instrument_fallback(component_class:, capsule_id:, original_path:, fallback_path:, exception:, exception_object:) notify( "style_capsule.css_file_writer.fallback", component_class: component_class.name, capsule_id: capsule_id, original_path: original_path, fallback_path: fallback_path, exception: exception, exception_object: exception_object ) end |
.instrument_fallback_failure(component_class:, capsule_id:, original_path:, fallback_path:, original_exception:, original_exception_object:, fallback_exception:, fallback_exception_object:) ⇒ void
This method returns an undefined value.
Instrument fallback failure (both original and fallback failed)
191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/style_capsule/instrumentation.rb', line 191 def self.instrument_fallback_failure(component_class:, capsule_id:, original_path:, fallback_path:, original_exception:, original_exception_object:, fallback_exception:, fallback_exception_object:) notify( "style_capsule.css_file_writer.fallback_failure", component_class: component_class.name, capsule_id: capsule_id, original_path: original_path, fallback_path: fallback_path, original_exception: original_exception, original_exception_object: original_exception_object, fallback_exception: fallback_exception, fallback_exception_object: fallback_exception_object ) end |
.instrument_file_write(component_class:, capsule_id:, file_path:, size:) { ... } ⇒ Object
Instrument CSS file write operations
147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/style_capsule/instrumentation.rb', line 147 def self.instrument_file_write(component_class:, capsule_id:, file_path:, size:, &block) instrument( "style_capsule.css_file_writer.write", component_class: component_class.name, capsule_id: capsule_id, file_path: file_path, size: size ) do yield end end |
.instrument_registration(namespace:, file_path: nil, inline_size: nil, cache_strategy: :none) { ... } ⇒ Object
Instrument stylesheet registration
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/style_capsule/instrumentation.rb', line 232 def self.instrument_registration(namespace:, file_path: nil, inline_size: nil, cache_strategy: :none, &block) payload = { namespace: namespace.to_s, cache_strategy: cache_strategy } payload[:file_path] = file_path if file_path payload[:inline_size] = inline_size if inline_size instrument( "style_capsule.stylesheet_registry.register", payload ) do yield end end |
.instrument_write_failure(component_class:, capsule_id:, file_path:, exception:, exception_object:) ⇒ void
This method returns an undefined value.
Instrument write failure (non-permission errors)
213 214 215 216 217 218 219 220 221 222 |
# File 'lib/style_capsule/instrumentation.rb', line 213 def self.instrument_write_failure(component_class:, capsule_id:, file_path:, exception:, exception_object:) notify( "style_capsule.css_file_writer.write_failure", component_class: component_class.name, capsule_id: capsule_id, file_path: file_path, exception: exception, exception_object: exception_object ) end |
.notify(event_name, payload = {}) ⇒ void
This method returns an undefined value.
Instrument an event without a block (for events that don't have duration)
107 108 109 110 111 112 113 114 |
# File 'lib/style_capsule/instrumentation.rb', line 107 def self.notify(event_name, payload = {}) return unless available? # Only notify if subscribers exist return unless ActiveSupport::Notifications.notifier.listening?(event_name) ActiveSupport::Notifications.instrument(event_name, payload) end |