cogbox 0.190.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/.rspec +3 -0
- data/.rubocop.yml +22 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE +190 -0
- data/README.md +184 -0
- data/Rakefile +12 -0
- data/lib/cogbox/code_interpreter.rb +360 -0
- data/lib/cogbox/cogbox.rb +337 -0
- data/lib/cogbox/common/charts.rb +125 -0
- data/lib/cogbox/common/code_interpreter.rb +57 -0
- data/lib/cogbox/common/code_language.rb +15 -0
- data/lib/cogbox/common/cogbox.rb +231 -0
- data/lib/cogbox/common/file_system.rb +27 -0
- data/lib/cogbox/common/git.rb +20 -0
- data/lib/cogbox/common/image.rb +501 -0
- data/lib/cogbox/common/process.rb +150 -0
- data/lib/cogbox/common/pty.rb +310 -0
- data/lib/cogbox/common/resources.rb +40 -0
- data/lib/cogbox/common/response.rb +84 -0
- data/lib/cogbox/common/snapshot.rb +125 -0
- data/lib/cogbox/computer_use.rb +920 -0
- data/lib/cogbox/config.rb +110 -0
- data/lib/cogbox/file_system.rb +452 -0
- data/lib/cogbox/file_transfer.rb +384 -0
- data/lib/cogbox/git.rb +335 -0
- data/lib/cogbox/lsp_server.rb +140 -0
- data/lib/cogbox/object_storage.rb +173 -0
- data/lib/cogbox/otel.rb +184 -0
- data/lib/cogbox/process.rb +551 -0
- data/lib/cogbox/sandbox.rb +752 -0
- data/lib/cogbox/sdk/version.rb +11 -0
- data/lib/cogbox/sdk.rb +57 -0
- data/lib/cogbox/snapshot_service.rb +239 -0
- data/lib/cogbox/util.rb +81 -0
- data/lib/cogbox/volume.rb +47 -0
- data/lib/cogbox/volume_service.rb +62 -0
- data/lib/cogbox.rb +11 -0
- data/project.json +100 -0
- data/scripts/generate-docs.rb +403 -0
- data/sig/cogbox/sdk.rbs +6 -0
- metadata +240 -0
data/lib/cogbox/otel.rb
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Copyright Daytona Platforms Inc.
|
|
2
|
+
# Copyright Cognifyi
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# frozen_string_literal: true
|
|
6
|
+
|
|
7
|
+
module Cogbox
|
|
8
|
+
# Holds OTel provider state for the SDK.
|
|
9
|
+
class OtelState
|
|
10
|
+
attr_reader :tracer_provider
|
|
11
|
+
attr_reader :meter_provider
|
|
12
|
+
attr_reader :tracer
|
|
13
|
+
attr_reader :meter
|
|
14
|
+
|
|
15
|
+
def initialize(tracer_provider:, meter_provider:, tracer:, meter:)
|
|
16
|
+
@tracer_provider = tracer_provider
|
|
17
|
+
@meter_provider = meter_provider
|
|
18
|
+
@tracer = tracer
|
|
19
|
+
@meter = meter
|
|
20
|
+
@histograms = {}
|
|
21
|
+
@histograms_mutex = Mutex.new
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Returns a cached histogram for the given metric name.
|
|
25
|
+
def histogram(name)
|
|
26
|
+
@histograms_mutex.synchronize do
|
|
27
|
+
@histograms[name] ||= meter.create_histogram(name, unit: 'ms')
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def shutdown
|
|
32
|
+
tracer_provider.shutdown
|
|
33
|
+
meter_provider.shutdown
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Initializes OTel providers, sets globals, installs Typhoeus propagation.
|
|
38
|
+
# OTel gems are required lazily so they are never loaded when disabled.
|
|
39
|
+
#
|
|
40
|
+
# @param sdk_version [String]
|
|
41
|
+
# @return [OtelState]
|
|
42
|
+
def self.init_otel(sdk_version) # rubocop:disable Metrics/MethodLength
|
|
43
|
+
require 'opentelemetry-sdk'
|
|
44
|
+
require 'opentelemetry-metrics-sdk'
|
|
45
|
+
require 'opentelemetry-exporter-otlp'
|
|
46
|
+
require 'opentelemetry-exporter-otlp-metrics'
|
|
47
|
+
|
|
48
|
+
resource = OpenTelemetry::SDK::Resources::Resource.create(
|
|
49
|
+
'service.name' => 'cogbox-ruby-sdk',
|
|
50
|
+
'service.version' => sdk_version
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
tracer_provider = OpenTelemetry::SDK::Trace::TracerProvider.new(resource:)
|
|
54
|
+
tracer_provider.add_span_processor(
|
|
55
|
+
OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
|
|
56
|
+
OpenTelemetry::Exporter::OTLP::Exporter.new
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
OpenTelemetry.tracer_provider = tracer_provider
|
|
60
|
+
|
|
61
|
+
meter_provider = OpenTelemetry::SDK::Metrics::MeterProvider.new(resource:)
|
|
62
|
+
meter_provider.add_metric_reader(
|
|
63
|
+
OpenTelemetry::SDK::Metrics::Export::PeriodicMetricReader.new(
|
|
64
|
+
exporter: OpenTelemetry::Exporter::OTLP::Metrics::MetricsExporter.new
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
OpenTelemetry.meter_provider = meter_provider
|
|
68
|
+
|
|
69
|
+
tracer = tracer_provider.tracer('cogbox-ruby-sdk', sdk_version)
|
|
70
|
+
meter = meter_provider.meter('cogbox-ruby-sdk')
|
|
71
|
+
|
|
72
|
+
# Install Typhoeus trace-context propagation
|
|
73
|
+
install_typhoeus_propagation
|
|
74
|
+
|
|
75
|
+
OtelState.new(tracer_provider:, meter_provider:, tracer:, meter:)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Flushes and shuts down OTel providers.
|
|
79
|
+
def self.shutdown_otel(state)
|
|
80
|
+
state&.shutdown
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Wraps a block with OTel span creation and duration histogram recording.
|
|
84
|
+
# When otel_state is nil (OTel disabled), calls the block directly.
|
|
85
|
+
#
|
|
86
|
+
# @param otel_state [OtelState, nil]
|
|
87
|
+
# @param component [String]
|
|
88
|
+
# @param method_name [String]
|
|
89
|
+
# @return [Object] The block's return value
|
|
90
|
+
def self.with_instrumentation(otel_state, component, method_name, &block) # rubocop:disable Metrics/MethodLength
|
|
91
|
+
return block.call unless otel_state
|
|
92
|
+
|
|
93
|
+
span_name = "#{component}.#{method_name}"
|
|
94
|
+
metric_name = "#{to_snake_case(span_name)}_duration"
|
|
95
|
+
status = 'success'
|
|
96
|
+
|
|
97
|
+
otel_state.tracer.in_span(
|
|
98
|
+
span_name,
|
|
99
|
+
attributes: { 'component' => component, 'method' => method_name }
|
|
100
|
+
) do |_span|
|
|
101
|
+
start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
|
102
|
+
begin
|
|
103
|
+
block.call
|
|
104
|
+
rescue StandardError => e
|
|
105
|
+
status = 'error'
|
|
106
|
+
raise e
|
|
107
|
+
ensure
|
|
108
|
+
duration_ms = (::Process.clock_gettime(::Process::CLOCK_MONOTONIC) - start_time) * 1000.0
|
|
109
|
+
otel_state.histogram(metric_name).record(
|
|
110
|
+
duration_ms,
|
|
111
|
+
attributes: { 'component' => component, 'method' => method_name, 'status' => status }
|
|
112
|
+
)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Converts "ClassName.method_name" to "class_name_method_name".
|
|
118
|
+
def self.to_snake_case(str)
|
|
119
|
+
result = +''
|
|
120
|
+
str.each_char.with_index do |char, i|
|
|
121
|
+
if char == '.'
|
|
122
|
+
result << '_'
|
|
123
|
+
elsif char =~ /[A-Z]/ && i > 0 && str[i - 1] != '.'
|
|
124
|
+
result << '_' << char.downcase
|
|
125
|
+
else
|
|
126
|
+
result << char.downcase
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
result
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Installs Typhoeus.before callback for W3C trace-context propagation.
|
|
133
|
+
def self.install_typhoeus_propagation
|
|
134
|
+
return unless defined?(Typhoeus)
|
|
135
|
+
|
|
136
|
+
Typhoeus.before do |request|
|
|
137
|
+
headers = request.options[:headers] ||= {}
|
|
138
|
+
OpenTelemetry.propagation.inject(headers)
|
|
139
|
+
true
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Mixin that provides the `instrument` class macro for wrapping methods
|
|
144
|
+
# with OTel spans and metrics.
|
|
145
|
+
module Instrumentation
|
|
146
|
+
def self.included(base)
|
|
147
|
+
base.extend(ClassMethods)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
module ClassMethods
|
|
151
|
+
# Instruments the listed methods with OTel tracing/metrics.
|
|
152
|
+
# Must be called after all target methods are defined.
|
|
153
|
+
#
|
|
154
|
+
# @param method_names [Array<Symbol>] methods to instrument
|
|
155
|
+
# @param component [String] component name for span/metric attributes
|
|
156
|
+
def instrument(*method_names, component:) # rubocop:disable Metrics/MethodLength
|
|
157
|
+
method_names.each do |method_name|
|
|
158
|
+
original = instance_method(method_name)
|
|
159
|
+
|
|
160
|
+
# Detect original visibility
|
|
161
|
+
visibility = if private_method_defined?(method_name, false)
|
|
162
|
+
:private
|
|
163
|
+
elsif protected_method_defined?(method_name, false)
|
|
164
|
+
:protected
|
|
165
|
+
else
|
|
166
|
+
:public
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
define_method(method_name) do |*args, **kwargs, &blk|
|
|
170
|
+
::Cogbox.with_instrumentation(otel_state, component, method_name.to_s) do
|
|
171
|
+
original.bind_call(self, *args, **kwargs, &blk)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Restore visibility
|
|
176
|
+
case visibility
|
|
177
|
+
when :private then private method_name
|
|
178
|
+
when :protected then protected method_name
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|