Class: Tasker::Telemetry::Plugins::BaseExporter

Inherits:
Object
  • Object
show all
Includes:
Concerns::StructuredLogging
Defined in:
lib/tasker/telemetry/plugins/base_exporter.rb

Overview

Base class for telemetry export plugins

Provides a standard interface and common functionality for all export plugins. Plugins should inherit from this class and implement the required methods.

Examples:

Creating a custom exporter

class MyCustomExporter < Tasker::Telemetry::Plugins::BaseExporter
  def export(metrics_data, options = {})
    # Implementation here
    log_plugin_event(:info, "Custom export completed", metrics_count: metrics_data.size)
  end

  def supports_format?(format)
    format.to_s == 'custom'
  end

  def supported_formats
    ['custom']
  end
end

Direct Known Subclasses

CsvExporter, JsonExporter

Constant Summary

Constants included from Concerns::StructuredLogging

Concerns::StructuredLogging::CORRELATION_ID_KEY

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Concerns::StructuredLogging

#correlation_id, #correlation_id=, #log_exception, #log_orchestration_event, #log_performance_event, #log_step_event, #log_structured, #log_task_event, #with_correlation_id

Constructor Details

#initialize(name: nil, version: '1.0.0', description: nil) ⇒ BaseExporter

Returns a new instance of BaseExporter.



32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/tasker/telemetry/plugins/base_exporter.rb', line 32

def initialize(name: nil, version: '1.0.0', description: nil)
  # Safe class name extraction for test environments where class.name might be nil
  default_name = if self.class.name
                   self.class.name.demodulize.underscore
                 else
                   'anonymous_exporter'
                 end

  @name = name || default_name
  @version = version
  @description = description || "#{@name} telemetry exporter"
end

Instance Attribute Details

#descriptionObject (readonly)

Plugin metadata



30
31
32
# File 'lib/tasker/telemetry/plugins/base_exporter.rb', line 30

def description
  @description
end

#nameObject (readonly)

Plugin metadata



30
31
32
# File 'lib/tasker/telemetry/plugins/base_exporter.rb', line 30

def name
  @name
end

#versionObject (readonly)

Plugin metadata



30
31
32
# File 'lib/tasker/telemetry/plugins/base_exporter.rb', line 30

def version
  @version
end

Instance Method Details

#export(metrics_data, options = {}) ⇒ Hash

Export metrics data (must be implemented by subclasses)

Parameters:

  • metrics_data (Hash)

    Metrics data to export

  • options (Hash) (defaults to: {})

    Export options

Returns:

  • (Hash)

    Export result with :success, :format, :data keys

Raises:

  • (NotImplementedError)

    If not implemented by subclass



51
52
53
# File 'lib/tasker/telemetry/plugins/base_exporter.rb', line 51

def export(metrics_data, options = {})
  raise NotImplementedError, "#{self.class.name} must implement #export method"
end

#metadataHash Also known as: plugin_info

Get plugin metadata

Returns:

  • (Hash)

    Plugin metadata



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/tasker/telemetry/plugins/base_exporter.rb', line 149

def 
  # Use class constants when available, otherwise use instance variables
  version = if self.class.const_defined?(:VERSION)
              self.class.const_get(:VERSION)
            else
              @version == '1.0.0' ? 'unknown' : @version
            end

  description = if self.class.const_defined?(:DESCRIPTION)
                  self.class.const_get(:DESCRIPTION)
                else
                  nil # Return nil when no DESCRIPTION constant is defined
                end

  {
    name: @name,
    version: version,
    description: description,
    supported_formats: supported_formats,
    class_name: self.class.name
  }
end

#on_cache_sync(sync_data) ⇒ Object

Called when cache sync occurs

Parameters:

  • sync_data (Hash)

    Cache sync information



76
77
78
# File 'lib/tasker/telemetry/plugins/base_exporter.rb', line 76

def on_cache_sync(sync_data)
  # Default: no action
end

#on_export_complete(completion_data) ⇒ Object

Called when export completes

Parameters:

  • completion_data (Hash)

    Export completion information



90
91
92
# File 'lib/tasker/telemetry/plugins/base_exporter.rb', line 90

def on_export_complete(completion_data)
  # Default: no action
end

#on_export_request(request_data) ⇒ Object

Called when export is requested

Parameters:

  • request_data (Hash)

    Export request information



83
84
85
# File 'lib/tasker/telemetry/plugins/base_exporter.rb', line 83

def on_export_request(request_data)
  # Default: no action
end

#safe_export(metrics_data, options = {}) ⇒ Hash

Safe export wrapper with error handling and timing

Parameters:

  • metrics_data (Hash)

    Metrics data to export

  • options (Hash) (defaults to: {})

    Export options

Returns:

  • (Hash)

    Export result with success/error information



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/tasker/telemetry/plugins/base_exporter.rb', line 99

def safe_export(metrics_data, options = {})
  start_time = Time.current

  begin
    # Validate metrics data structure
    validate_metrics_data!(metrics_data) if respond_to?(:validate_metrics_data!, true)

    result = export(metrics_data, options)

    duration = ((Time.current - start_time) * 1000).round(2)

    log_plugin_event(:info, 'Plugin export completed',
                     metrics_count: metrics_data.size,
                     duration_ms: duration,
                     success: true)

    {
      success: true,
      format: result[:format] || 'unknown',
      data: result[:data],
      result: result, # Include the full result for test compatibility
      plugin: { name: @name, version: @version }, # Add plugin field for test compatibility
      metrics_count: metrics_data.size,
      duration_ms: duration,
      plugin_name: @name,
      plugin_version: @version
    }
  rescue StandardError => e
    duration = ((Time.current - start_time) * 1000).round(2)

    log_plugin_event(:error, 'Plugin export failed',
                     metrics_count: metrics_data.size,
                     duration_ms: duration,
                     error: e.message,
                     success: false)

    {
      success: false,
      error: e.message,
      metrics_count: metrics_data.size,
      duration_ms: duration,
      plugin_name: @name,
      plugin_version: @version
    }
  end
end

#supported_formatsArray<String>

Get supported formats (should be implemented by subclasses)

Returns:

  • (Array<String>)

    Supported export formats



67
68
69
# File 'lib/tasker/telemetry/plugins/base_exporter.rb', line 67

def supported_formats
  []
end

#supports_format?(format) ⇒ Boolean

Check if plugin supports a specific format (must be implemented by subclasses)

Parameters:

  • format (String, Symbol)

    Format to check

Returns:

  • (Boolean)

    Whether format is supported

Raises:

  • (NotImplementedError)

    If not implemented by subclass



60
61
62
# File 'lib/tasker/telemetry/plugins/base_exporter.rb', line 60

def supports_format?(format)
  raise NotImplementedError, "#{self.class.name} must implement #supports_format? method"
end