Module: Jekyll::Minify::Instrumentation
- Defined in:
- lib/jekyll-minify/instrumentation.rb
Overview
OpenTelemetry instrumentation facade for jekyll-minify.
All tracing is configured centrally in TRACED_METHODS — no span code lives in business logic classes. To add a span: append one entry. To rename a method: update the one entry. When a method is removed from its class the stale entry raises NoMethodError in tests, signalling the entry to delete.
Requires opentelemetry-api at runtime; falls back to a no-op if absent. Users opt in to real tracing by adding opentelemetry-sdk and opentelemetry-exporter-otlp to their site Gemfile and exporting:
OTEL_SERVICE_NAME=jekyll-minify
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
Defined Under Namespace
Classes: NoopSpan, NoopTracer
Constant Summary collapse
- TRACER_NAME =
Name reported to the OTel tracer provider for spans created by this gem.
'jekyll-minify'- TRACED_METHODS =
Central instrumentation registry.
Each row: [class_name, method_type, method_name, span_name, attribute_proc]
method_type:
:instance — public instance method :private — private instance method (visibility is preserved on the wrapper) :class — class / module method (prepended on the singleton class)attribute_proc: ->(span, this, args, result) or nil span — OTel span (or NoopSpan); call span.set_attribute after super returns this — receiver object (instance or nil for class methods) args — positional args array as passed to the method result — return value of the original method
:nocov: — attribute procs are configuration data; coverage comes from integration tests
[ ['Jekyll::Minify::Minifier', :class, :minify_site, 'minify.site_minify', lambda { |span, _this, args, result| span.set_attribute('minify.dest_path', args[0].dest.to_s) next unless result types = result.values_at(:html, :css, :js) span.set_attribute('minify.total_file_count', types.sum { |t| t[:count] }) span.set_attribute('minify.total_original_size_bytes', types.sum { |t| t[:original_bytes] }) span.set_attribute('minify.total_minified_size_bytes', types.sum { |t| t[:minified_bytes] }) span.set_attribute('minify.error_count', result[:errors].length) }], ['Jekyll::Minify::Minifier', :private, :minify_each_file, 'minify.file_discovery', lambda { |span, _this, args, _result| span.set_attribute('minify.dest_path', args[0].to_s) }], ['Jekyll::Minify::Minifier', :private, :minify_with_fallback, 'minify.file_process', lambda { |span, _this, args, _result| span.set_attribute('minify.file_path', args[0].to_s) span.set_attribute('minify.asset_type', args[1].to_s) }], ['Jekyll::Minify::Minifier', :private, :minify_html, 'minify.html_minify', lambda { |span, _this, args, result| span.set_attribute('minify.input_size_bytes', args[0].bytesize) span.set_attribute('minify.output_size_bytes', result.to_s.bytesize) }], ['Jekyll::Minify::Minifier', :private, :minify_css, 'minify.css_minify', lambda { |span, _this, args, result| span.set_attribute('minify.input_size_bytes', args[0].bytesize) span.set_attribute('minify.output_size_bytes', result.to_s.bytesize) }], ['Jekyll::Minify::Minifier', :private, :minify_js, 'minify.js_minify', lambda { |span, _this, args, result| span.set_attribute('minify.input_size_bytes', args[0].bytesize) span.set_attribute('minify.output_size_bytes', result.to_s.bytesize) }] ].freeze
Class Method Summary collapse
-
.enabled? ⇒ Boolean
Returns true when OTel is requested via standard environment variables.
-
.install! ⇒ void
Installs wrappers on all classes listed in TRACED_METHODS using Module#prepend.
-
.instrument(span_name, attributes: {}) {|span| ... } ⇒ Object
Wraps a block in an OTel span.
-
.reset! ⇒ void
Resets the cached tracer and installation flag.
-
.resolve_class(name) ⇒ Class?
Resolves a dot-separated class name to a constant; returns nil on NameError.
-
.tracer ⇒ OpenTelemetry::Trace::Tracer, NoopTracer
Returns the active OTel tracer, or a no-op tracer if opentelemetry-api is absent.
Class Method Details
.enabled? ⇒ Boolean
Returns true when OTel is requested via standard environment variables.
install! guards on this so the prepend wrappers are only applied when a real exporter is configured. In CI and local tests (no OTel env vars) business logic classes are untouched, keeping allow_any_instance_of stubs and other RSpec mechanics fully functional.
125 126 127 |
# File 'lib/jekyll-minify/instrumentation.rb', line 125 def self.enabled? ENV.key?('OTEL_EXPORTER_OTLP_ENDPOINT') || ENV.key?('OTEL_SERVICE_NAME') end |
.install! ⇒ void
This method returns an undefined value.
Installs wrappers on all classes listed in TRACED_METHODS using Module#prepend.
Called once at plugin load time (end of jekyll-minify.rb, after all requires), but only when enabled? returns true. Use OTEL_EXPORTER_OTLP_ENDPOINT or OTEL_SERVICE_NAME to activate tracing.
136 137 138 139 140 141 142 143 144 |
# File 'lib/jekyll-minify/instrumentation.rb', line 136 def self.install! return if @installed @installed = true setup_sdk! TRACED_METHODS.group_by { |e| e[0] }.each do |class_name, entries| prepend_wrappers(resolve_class(class_name), entries) end end |
.instrument(span_name, attributes: {}) {|span| ... } ⇒ Object
Wraps a block in an OTel span.
105 106 107 |
# File 'lib/jekyll-minify/instrumentation.rb', line 105 def self.instrument(span_name, attributes: {}, &block) tracer.in_span(span_name, attributes: attributes, &block) end |
.reset! ⇒ void
This method returns an undefined value.
Resets the cached tracer and installation flag. Call in tests after changing OTel configuration.
112 113 114 115 |
# File 'lib/jekyll-minify/instrumentation.rb', line 112 def self.reset! @tracer = nil @installed = false end |
.resolve_class(name) ⇒ Class?
Resolves a dot-separated class name to a constant; returns nil on NameError.
190 191 192 193 194 |
# File 'lib/jekyll-minify/instrumentation.rb', line 190 def self.resolve_class(name) name.split('::').reduce(Object) { |m, c| m.const_get(c) } rescue NameError nil end |
.tracer ⇒ OpenTelemetry::Trace::Tracer, NoopTracer
Returns the active OTel tracer, or a no-op tracer if opentelemetry-api is absent.
88 89 90 91 92 93 94 95 96 97 |
# File 'lib/jekyll-minify/instrumentation.rb', line 88 def self.tracer @tracer ||= if defined?(OpenTelemetry) # :nocov: OpenTelemetry.tracer_provider.tracer(TRACER_NAME, Jekyll::Minify::VERSION) # :nocov: else NoopTracer.new end end |