tasker-rb 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/DEVELOPMENT.md +548 -0
- data/README.md +87 -0
- data/ext/tasker_core/Cargo.lock +4720 -0
- data/ext/tasker_core/Cargo.toml +76 -0
- data/ext/tasker_core/extconf.rb +38 -0
- data/ext/tasker_core/src/CLAUDE.md +7 -0
- data/ext/tasker_core/src/bootstrap.rs +320 -0
- data/ext/tasker_core/src/bridge.rs +400 -0
- data/ext/tasker_core/src/client_ffi.rs +173 -0
- data/ext/tasker_core/src/conversions.rs +131 -0
- data/ext/tasker_core/src/diagnostics.rs +57 -0
- data/ext/tasker_core/src/event_handler.rs +179 -0
- data/ext/tasker_core/src/event_publisher_ffi.rs +239 -0
- data/ext/tasker_core/src/ffi_logging.rs +245 -0
- data/ext/tasker_core/src/global_event_system.rs +16 -0
- data/ext/tasker_core/src/in_process_event_ffi.rs +319 -0
- data/ext/tasker_core/src/lib.rs +41 -0
- data/ext/tasker_core/src/observability_ffi.rs +339 -0
- data/lib/tasker_core/batch_processing/batch_aggregation_scenario.rb +85 -0
- data/lib/tasker_core/batch_processing/batch_worker_context.rb +238 -0
- data/lib/tasker_core/bootstrap.rb +394 -0
- data/lib/tasker_core/domain_events/base_publisher.rb +220 -0
- data/lib/tasker_core/domain_events/base_subscriber.rb +178 -0
- data/lib/tasker_core/domain_events/publisher_registry.rb +253 -0
- data/lib/tasker_core/domain_events/subscriber_registry.rb +152 -0
- data/lib/tasker_core/domain_events.rb +43 -0
- data/lib/tasker_core/errors/CLAUDE.md +7 -0
- data/lib/tasker_core/errors/common.rb +305 -0
- data/lib/tasker_core/errors/error_classifier.rb +61 -0
- data/lib/tasker_core/errors.rb +4 -0
- data/lib/tasker_core/event_bridge.rb +330 -0
- data/lib/tasker_core/handlers.rb +159 -0
- data/lib/tasker_core/internal.rb +31 -0
- data/lib/tasker_core/logger.rb +234 -0
- data/lib/tasker_core/models.rb +337 -0
- data/lib/tasker_core/observability/types.rb +158 -0
- data/lib/tasker_core/observability.rb +292 -0
- data/lib/tasker_core/registry/handler_registry.rb +453 -0
- data/lib/tasker_core/registry/resolver_chain.rb +258 -0
- data/lib/tasker_core/registry/resolvers/base_resolver.rb +90 -0
- data/lib/tasker_core/registry/resolvers/class_constant_resolver.rb +156 -0
- data/lib/tasker_core/registry/resolvers/explicit_mapping_resolver.rb +146 -0
- data/lib/tasker_core/registry/resolvers/method_dispatch_wrapper.rb +144 -0
- data/lib/tasker_core/registry/resolvers/registry_resolver.rb +229 -0
- data/lib/tasker_core/registry/resolvers.rb +42 -0
- data/lib/tasker_core/registry.rb +12 -0
- data/lib/tasker_core/step_handler/api.rb +48 -0
- data/lib/tasker_core/step_handler/base.rb +354 -0
- data/lib/tasker_core/step_handler/batchable.rb +50 -0
- data/lib/tasker_core/step_handler/decision.rb +53 -0
- data/lib/tasker_core/step_handler/mixins/api.rb +452 -0
- data/lib/tasker_core/step_handler/mixins/batchable.rb +465 -0
- data/lib/tasker_core/step_handler/mixins/decision.rb +252 -0
- data/lib/tasker_core/step_handler/mixins.rb +66 -0
- data/lib/tasker_core/subscriber.rb +212 -0
- data/lib/tasker_core/task_handler/base.rb +254 -0
- data/lib/tasker_core/tasker_rb.so +0 -0
- data/lib/tasker_core/template_discovery.rb +181 -0
- data/lib/tasker_core/tracing.rb +166 -0
- data/lib/tasker_core/types/batch_processing_outcome.rb +301 -0
- data/lib/tasker_core/types/client_types.rb +145 -0
- data/lib/tasker_core/types/decision_point_outcome.rb +177 -0
- data/lib/tasker_core/types/error_types.rb +72 -0
- data/lib/tasker_core/types/simple_message.rb +151 -0
- data/lib/tasker_core/types/step_context.rb +328 -0
- data/lib/tasker_core/types/step_handler_call_result.rb +307 -0
- data/lib/tasker_core/types/step_message.rb +112 -0
- data/lib/tasker_core/types/step_types.rb +207 -0
- data/lib/tasker_core/types/task_template.rb +240 -0
- data/lib/tasker_core/types/task_types.rb +148 -0
- data/lib/tasker_core/types.rb +132 -0
- data/lib/tasker_core/version.rb +13 -0
- data/lib/tasker_core/worker/CLAUDE.md +7 -0
- data/lib/tasker_core/worker/event_poller.rb +224 -0
- data/lib/tasker_core/worker/in_process_domain_event_poller.rb +271 -0
- data/lib/tasker_core.rb +160 -0
- metadata +322 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TaskerCore
|
|
4
|
+
# Clean Handlers Domain API
|
|
5
|
+
#
|
|
6
|
+
# This module provides the primary public interface for working with TaskerCore handlers.
|
|
7
|
+
# It's organized into two main namespaces: Steps and Tasks, mirroring the Rails engine
|
|
8
|
+
# architecture while providing a clean Ruby interface with enhanced type safety.
|
|
9
|
+
#
|
|
10
|
+
# The Handlers namespace serves as the recommended entry point for handler operations,
|
|
11
|
+
# abstracting the underlying implementation details while preserving method signatures
|
|
12
|
+
# that developers familiar with the Rails engine will recognize.
|
|
13
|
+
#
|
|
14
|
+
# @example Creating and using a step handler
|
|
15
|
+
# # Define a handler class
|
|
16
|
+
# class ProcessPaymentHandler < TaskerCore::Handlers::Steps::Base
|
|
17
|
+
# def call(context)
|
|
18
|
+
# # Access task context
|
|
19
|
+
# amount = context.get_task_field('amount')
|
|
20
|
+
# currency = context.get_task_field('currency')
|
|
21
|
+
#
|
|
22
|
+
# # Process payment logic
|
|
23
|
+
# result = charge_payment(amount, currency)
|
|
24
|
+
#
|
|
25
|
+
# # Return results
|
|
26
|
+
# success(result: { payment_id: result.id, status: "succeeded" })
|
|
27
|
+
# end
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
# # Create instance with configuration
|
|
31
|
+
# handler = TaskerCore::Handlers::Steps.create(
|
|
32
|
+
# ProcessPaymentHandler,
|
|
33
|
+
# config: { timeout: 30, max_attempts: 3 }
|
|
34
|
+
# )
|
|
35
|
+
#
|
|
36
|
+
# @example Validating handler implementation
|
|
37
|
+
# validation = TaskerCore::Handlers::Steps.validate(ProcessPaymentHandler)
|
|
38
|
+
# # => {
|
|
39
|
+
# # valid: true,
|
|
40
|
+
# # missing_required: [],
|
|
41
|
+
# # optional_implemented: [:process_results],
|
|
42
|
+
# # handler_class: "ProcessPaymentHandler"
|
|
43
|
+
# # }
|
|
44
|
+
#
|
|
45
|
+
# if validation[:valid]
|
|
46
|
+
# puts "Handler implements all required methods"
|
|
47
|
+
# else
|
|
48
|
+
# puts "Missing: #{validation[:missing_required].join(', ')}"
|
|
49
|
+
# end
|
|
50
|
+
#
|
|
51
|
+
# @example Using API handlers for HTTP operations
|
|
52
|
+
# class FetchUserHandler < TaskerCore::Handlers::Steps::API
|
|
53
|
+
# def call(context)
|
|
54
|
+
# user_id = context.get_task_field('user_id')
|
|
55
|
+
#
|
|
56
|
+
# # Automatic error classification and retry logic
|
|
57
|
+
# response = get("/users/#{user_id}")
|
|
58
|
+
#
|
|
59
|
+
# success(result: response.body)
|
|
60
|
+
# end
|
|
61
|
+
# end
|
|
62
|
+
#
|
|
63
|
+
# @example Task-level handler for workflow coordination
|
|
64
|
+
# # Task handlers coordinate multiple steps
|
|
65
|
+
# result = TaskerCore::Handlers::Tasks.handle(task_uuid: "123-456")
|
|
66
|
+
# # => Orchestrates all steps for the task
|
|
67
|
+
#
|
|
68
|
+
# Architecture:
|
|
69
|
+
# - **Steps**: Individual business logic units (payment processing, API calls, etc.)
|
|
70
|
+
# - **Tasks**: Workflow orchestration and step coordination
|
|
71
|
+
# - **API**: Specialized step handlers for HTTP operations with automatic retry
|
|
72
|
+
#
|
|
73
|
+
# Method Signature:
|
|
74
|
+
# Cross-language standard handler signature (TAS-96):
|
|
75
|
+
# - `call(context)` - Primary handler execution with unified StepContext
|
|
76
|
+
# - `context.task` - Task wrapper with context data
|
|
77
|
+
# - `context.workflow_step` - Workflow step wrapper with execution state
|
|
78
|
+
# - `context.dependency_results` - Results from parent steps
|
|
79
|
+
#
|
|
80
|
+
# @see TaskerCore::Handlers::Steps For step-level business logic
|
|
81
|
+
# @see TaskerCore::Handlers::Tasks For task-level orchestration
|
|
82
|
+
# @see TaskerCore::StepHandler::Base For low-level step handler implementation
|
|
83
|
+
# @see TaskerCore::StepHandler::Api For HTTP-based handlers
|
|
84
|
+
module Handlers
|
|
85
|
+
# Step Handler API with preserved method signatures
|
|
86
|
+
module Steps
|
|
87
|
+
# Import the existing base step handler with preserved signatures
|
|
88
|
+
require_relative 'step_handler/base'
|
|
89
|
+
require_relative 'step_handler/mixins' # TAS-112: Composition pattern mixins
|
|
90
|
+
require_relative 'step_handler/api'
|
|
91
|
+
require_relative 'step_handler/decision' # TAS-53: Decision point handlers
|
|
92
|
+
require_relative 'step_handler/batchable' # TAS-59: Batch processing handlers
|
|
93
|
+
|
|
94
|
+
# Re-export with clean namespace
|
|
95
|
+
Base = TaskerCore::StepHandler::Base
|
|
96
|
+
|
|
97
|
+
# TAS-112: Composition Pattern - Mixin modules (preferred)
|
|
98
|
+
# Use these with `include` in handlers that inherit from Base
|
|
99
|
+
Mixins = TaskerCore::StepHandler::Mixins
|
|
100
|
+
|
|
101
|
+
# Legacy class aliases (deprecated - use Mixins instead)
|
|
102
|
+
API = TaskerCore::StepHandler::Api
|
|
103
|
+
Decision = TaskerCore::StepHandler::Decision
|
|
104
|
+
Batchable = TaskerCore::StepHandler::Batchable
|
|
105
|
+
|
|
106
|
+
class << self
|
|
107
|
+
# Create a new step handler instance
|
|
108
|
+
# @param handler_class [Class] Handler class to instantiate
|
|
109
|
+
# @param config [Hash] Handler configuration
|
|
110
|
+
# @return [Object] Handler instance
|
|
111
|
+
def create(handler_class, config: {})
|
|
112
|
+
handler_class.new(config: config)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Validate step handler implementation
|
|
116
|
+
# @param handler_class [Class] Handler class to validate
|
|
117
|
+
# @return [Hash] Validation result
|
|
118
|
+
def validate(handler_class)
|
|
119
|
+
required_methods = %i[process]
|
|
120
|
+
optional_methods = %i[process_results handle]
|
|
121
|
+
|
|
122
|
+
missing = required_methods.reject { |method| handler_class.method_defined?(method) }
|
|
123
|
+
present_optional = optional_methods.select { |method| handler_class.method_defined?(method) }
|
|
124
|
+
|
|
125
|
+
{
|
|
126
|
+
valid: missing.empty?,
|
|
127
|
+
missing_required: missing,
|
|
128
|
+
optional_implemented: present_optional,
|
|
129
|
+
handler_class: handler_class.name
|
|
130
|
+
}
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Task Handler API
|
|
136
|
+
module Tasks
|
|
137
|
+
require_relative 'task_handler/base'
|
|
138
|
+
|
|
139
|
+
# Re-export with clean namespace
|
|
140
|
+
Base = TaskHandler
|
|
141
|
+
|
|
142
|
+
class << self
|
|
143
|
+
# Handle task with preserved signature
|
|
144
|
+
# @param task_uuid [Integer] Task ID to handle
|
|
145
|
+
# @return [Object] Task handle result
|
|
146
|
+
def handle(task_uuid)
|
|
147
|
+
Base.new.handle(task_uuid)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Create task handler instance
|
|
151
|
+
# @param config [Hash] Handler configuration
|
|
152
|
+
# @return [TaskHandler] Handler instance
|
|
153
|
+
def create(config: {})
|
|
154
|
+
Base.new(config: config)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'singleton'
|
|
4
|
+
|
|
5
|
+
module TaskerCore
|
|
6
|
+
module Internal
|
|
7
|
+
# Simple stub for OrchestrationManager to satisfy StepHandler::Base dependencies
|
|
8
|
+
# In the FFI worker context, we don't need the full Rails engine infrastructure
|
|
9
|
+
class OrchestrationManager
|
|
10
|
+
include Singleton
|
|
11
|
+
|
|
12
|
+
def orchestration_system
|
|
13
|
+
# Return a simple stub that satisfies the interface expected by handlers
|
|
14
|
+
NullOrchestrationSystem.new
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Minimal orchestration system stub for FFI worker context
|
|
19
|
+
class NullOrchestrationSystem
|
|
20
|
+
def method_missing(_method_name, *_args, **_kwargs)
|
|
21
|
+
# Log that the method was called but return nil
|
|
22
|
+
# This allows handlers to work without crashing
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def respond_to_missing?(_method_name, _include_private = false)
|
|
27
|
+
true
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'singleton'
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
module TaskerCore
|
|
7
|
+
# DEPRECATED: Legacy logger wrapper that delegates to TaskerCore::Tracing
|
|
8
|
+
#
|
|
9
|
+
# This class is maintained for backward compatibility but all new code should
|
|
10
|
+
# use TaskerCore::Tracing directly for unified structured logging via FFI.
|
|
11
|
+
#
|
|
12
|
+
# TAS-29 Phase 6: This logger now delegates to the Rust tracing infrastructure
|
|
13
|
+
# through the FFI bridge, providing unified structured logging across Ruby and Rust.
|
|
14
|
+
#
|
|
15
|
+
# Migration Guide:
|
|
16
|
+
# # Old:
|
|
17
|
+
# logger = TaskerCore::Logger.instance
|
|
18
|
+
# logger.info("Message")
|
|
19
|
+
#
|
|
20
|
+
# # New:
|
|
21
|
+
# TaskerCore::Tracing.info("Message", { operation: "example" })
|
|
22
|
+
#
|
|
23
|
+
# The logger supports two logging approaches:
|
|
24
|
+
# 1. **Traditional Logging**: Simple string messages (delegates to Tracing)
|
|
25
|
+
# 2. **Structured Logging**: Component-based logging (converts to Tracing fields)
|
|
26
|
+
#
|
|
27
|
+
# Structured logs include:
|
|
28
|
+
# - Emoji prefix for visual identification
|
|
29
|
+
# - Component label for categorization
|
|
30
|
+
# - Operation description
|
|
31
|
+
# - Structured metadata as JSON
|
|
32
|
+
# - ISO 8601 timestamps
|
|
33
|
+
#
|
|
34
|
+
# @example Traditional logging (backward compatibility)
|
|
35
|
+
# logger = TaskerCore::Logger.instance
|
|
36
|
+
# logger.info "Worker started successfully"
|
|
37
|
+
# logger.error "Failed to process step: #{error.message}"
|
|
38
|
+
# logger.debug "Processing step #{step_uuid}"
|
|
39
|
+
#
|
|
40
|
+
# @example Structured logging with component context
|
|
41
|
+
# logger.log_task(:info, "initialization",
|
|
42
|
+
# task_uuid: "550e8400-e29b-41d4-a716-446655440000",
|
|
43
|
+
# namespace: "payments",
|
|
44
|
+
# step_count: 4,
|
|
45
|
+
# priority: "high"
|
|
46
|
+
# )
|
|
47
|
+
# # Output: [2025-10-02 12:00:00] INFO TaskerCore: 📋 TASK_OPERATION: initialization | {"task_uuid":"...","namespace":"payments",...}
|
|
48
|
+
#
|
|
49
|
+
# @example Queue worker logging
|
|
50
|
+
# logger.log_queue_worker(:debug, "claiming_step",
|
|
51
|
+
# namespace: "payments",
|
|
52
|
+
# step_uuid: "7c9e6679-7425-40de-944b-e07fc1f90ae7",
|
|
53
|
+
# retry_count: 2,
|
|
54
|
+
# queue_depth: 15
|
|
55
|
+
# )
|
|
56
|
+
# # Output: [2025-10-02 12:00:01] DEBUG TaskerCore: 🔄 QUEUE_WORKER: claiming_step (namespace: payments) | {...}
|
|
57
|
+
#
|
|
58
|
+
# @example Step execution logging
|
|
59
|
+
# logger.log_step(:info, "handler_execution",
|
|
60
|
+
# step_uuid: "7c9e6679-7425-40de-944b-e07fc1f90ae7",
|
|
61
|
+
# handler_class: "ProcessPaymentHandler",
|
|
62
|
+
# execution_time_ms: 125,
|
|
63
|
+
# result_size_bytes: 1024
|
|
64
|
+
# )
|
|
65
|
+
#
|
|
66
|
+
# @example FFI operation logging
|
|
67
|
+
# logger.log_ffi(:info, "bootstrap_worker",
|
|
68
|
+
# component: "RubyWorker",
|
|
69
|
+
# worker_id: "ruby-worker-123",
|
|
70
|
+
# deployment_mode: "Hybrid"
|
|
71
|
+
# )
|
|
72
|
+
#
|
|
73
|
+
# @example Database operation logging
|
|
74
|
+
# logger.log_database(:debug, "step_transition",
|
|
75
|
+
# step_uuid: "7c9e6679-7425-40de-944b-e07fc1f90ae7",
|
|
76
|
+
# from_state: "in_progress",
|
|
77
|
+
# to_state: "complete",
|
|
78
|
+
# duration_ms: 15
|
|
79
|
+
# )
|
|
80
|
+
#
|
|
81
|
+
# @example Configuration logging
|
|
82
|
+
# logger.log_config(:info, "environment_loaded",
|
|
83
|
+
# environment: "production",
|
|
84
|
+
# config_file: "/etc/tasker/config.yml",
|
|
85
|
+
# overrides_applied: 3
|
|
86
|
+
# )
|
|
87
|
+
#
|
|
88
|
+
# @example Handler registry logging
|
|
89
|
+
# logger.log_registry(:debug, "handler_registered",
|
|
90
|
+
# namespace: "payments",
|
|
91
|
+
# name: "ProcessPaymentHandler",
|
|
92
|
+
# handler_count: 12
|
|
93
|
+
# )
|
|
94
|
+
#
|
|
95
|
+
# Component Types and Their Emojis:
|
|
96
|
+
# - **📋 TASK_OPERATION**: Task-level operations (creation, completion, state changes)
|
|
97
|
+
# - **🔄 QUEUE_WORKER**: Queue processing and step claiming
|
|
98
|
+
# - **🚀 ORCHESTRATOR**: Orchestration coordination and workflow management
|
|
99
|
+
# - **🔧 STEP_OPERATION**: Step execution and handler invocation
|
|
100
|
+
# - **💾 DATABASE**: Database operations and state persistence
|
|
101
|
+
# - **🌉 FFI**: Rust FFI bridge operations and cross-language communication
|
|
102
|
+
# - **⚙️ CONFIG**: Configuration loading and validation
|
|
103
|
+
# - **📚 REGISTRY**: Handler registry operations and discovery
|
|
104
|
+
#
|
|
105
|
+
# Log Levels:
|
|
106
|
+
# - **:debug**: Detailed diagnostic information
|
|
107
|
+
# - **:info**: General informational messages
|
|
108
|
+
# - **:warn**: Warning messages for potential issues
|
|
109
|
+
# - **:error**: Error messages for failures
|
|
110
|
+
# - **:fatal**: Critical failures requiring immediate attention
|
|
111
|
+
#
|
|
112
|
+
# @see #log_task For task-level operations
|
|
113
|
+
# @see #log_queue_worker For queue processing
|
|
114
|
+
# @see #log_orchestrator For orchestration operations
|
|
115
|
+
# @see #log_step For step execution
|
|
116
|
+
# @see #log_database For database operations
|
|
117
|
+
# @see #log_ffi For FFI bridge operations
|
|
118
|
+
# @see #log_config For configuration operations
|
|
119
|
+
# @see #log_registry For handler registry operations
|
|
120
|
+
class Logger
|
|
121
|
+
include Singleton
|
|
122
|
+
|
|
123
|
+
# Traditional string-based logging methods (delegates to Tracing)
|
|
124
|
+
def info(message, &)
|
|
125
|
+
Tracing.info(message.to_s, extract_context_fields)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def warn(message, &)
|
|
129
|
+
Tracing.warn(message.to_s, extract_context_fields)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def error(message, &)
|
|
133
|
+
Tracing.error(message.to_s, extract_context_fields)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def fatal(message, &)
|
|
137
|
+
Tracing.error(message.to_s, extract_context_fields.merge(severity: 'fatal'))
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def debug(message, &)
|
|
141
|
+
Tracing.debug(message.to_s, extract_context_fields)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Enhanced structured logging methods (delegates to Tracing with appropriate fields)
|
|
145
|
+
|
|
146
|
+
def log_task(level, operation, **data)
|
|
147
|
+
fields = extract_context_fields.merge(
|
|
148
|
+
operation: operation,
|
|
149
|
+
component: 'task_operation'
|
|
150
|
+
).merge(data)
|
|
151
|
+
Tracing.send(level, operation, fields)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def log_queue_worker(level, operation, namespace: nil, **data)
|
|
155
|
+
fields = extract_context_fields.merge(
|
|
156
|
+
operation: operation,
|
|
157
|
+
component: 'queue_worker'
|
|
158
|
+
).merge(data)
|
|
159
|
+
fields[:namespace] = namespace if namespace
|
|
160
|
+
Tracing.send(level, operation, fields)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def log_orchestrator(level, operation, **data)
|
|
164
|
+
fields = extract_context_fields.merge(
|
|
165
|
+
operation: operation,
|
|
166
|
+
component: 'orchestrator'
|
|
167
|
+
).merge(data)
|
|
168
|
+
Tracing.send(level, operation, fields)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def log_step(level, operation, **data)
|
|
172
|
+
fields = extract_context_fields.merge(
|
|
173
|
+
operation: operation,
|
|
174
|
+
component: 'step_operation'
|
|
175
|
+
).merge(data)
|
|
176
|
+
Tracing.send(level, operation, fields)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def log_database(level, operation, **data)
|
|
180
|
+
fields = extract_context_fields.merge(
|
|
181
|
+
operation: operation,
|
|
182
|
+
component: 'database'
|
|
183
|
+
).merge(data)
|
|
184
|
+
Tracing.send(level, operation, fields)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def log_ffi(level, operation, component: nil, **data)
|
|
188
|
+
fields = extract_context_fields.merge(
|
|
189
|
+
operation: operation,
|
|
190
|
+
component: component || 'ffi'
|
|
191
|
+
).merge(data)
|
|
192
|
+
Tracing.send(level, operation, fields)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def log_config(level, operation, **data)
|
|
196
|
+
fields = extract_context_fields.merge(
|
|
197
|
+
operation: operation,
|
|
198
|
+
component: 'config'
|
|
199
|
+
).merge(data)
|
|
200
|
+
Tracing.send(level, operation, fields)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def log_registry(level, operation, namespace: nil, name: nil, **data)
|
|
204
|
+
fields = extract_context_fields.merge(
|
|
205
|
+
operation: operation,
|
|
206
|
+
component: 'registry'
|
|
207
|
+
).merge(data)
|
|
208
|
+
fields[:namespace] = namespace if namespace
|
|
209
|
+
fields[:handler_name] = name if name
|
|
210
|
+
Tracing.send(level, operation, fields)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def initialize
|
|
214
|
+
# No-op - everything delegates to Tracing now
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
private
|
|
218
|
+
|
|
219
|
+
# Extract context fields from thread-local or instance variables if available
|
|
220
|
+
def extract_context_fields
|
|
221
|
+
fields = {}
|
|
222
|
+
|
|
223
|
+
# Try to extract correlation_id from thread-local storage if available
|
|
224
|
+
fields[:correlation_id] = Thread.current[:correlation_id] if Thread.current[:correlation_id]
|
|
225
|
+
|
|
226
|
+
# Try to extract task/step UUIDs if available
|
|
227
|
+
fields[:task_uuid] = Thread.current[:task_uuid] if Thread.current[:task_uuid]
|
|
228
|
+
|
|
229
|
+
fields[:step_uuid] = Thread.current[:step_uuid] if Thread.current[:step_uuid]
|
|
230
|
+
|
|
231
|
+
fields
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|