stack-service-base 0.0.2 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d365e12102a76d0d4e8e1c453151361881db1d57f4864cba7e3ac0662027b00
4
- data.tar.gz: cae46609114c37ee39d63b9b7adb9cac3de539e17263da3e0290798d56da05fe
3
+ metadata.gz: 340d3036dfae55df21ac629aea2f177b890257e29e8d51d7c7ec975bff57ee0b
4
+ data.tar.gz: 76ab84fb603376f3a8f29901c5987cd4bf664625dd6a9bd533f20e928716a775
5
5
  SHA512:
6
- metadata.gz: 2b632ef3a662cfa1105fa3c06b9f14744314f2d1edec155031f4f63c6c52a175682e9f98d5cc5a69958255c27b1c748da4f56e6c8b312036f76b51fe5c9c2f7e
7
- data.tar.gz: e5c025affc7e0109e403c7a3e3f31f55b139dd7323b3250ec84dec1fabcec17b7f474a4856a054b34746474f3b825a9a7cefcefac745f4e203ce420d483031b4
6
+ metadata.gz: d99472369e7dae16f8cfd8526e785a6dee35727e4f7e7b48e81a3509a295c9712883c8060d177f76cb56022d42055868f1ce3ee7cabd27163635a66bb9154bb9
7
+ data.tar.gz: 3d86d30f6fbcbcb06339d2cdfe03afbf51a58696177d88c4d7fc81e404454093ba0c4e00ef80ac228ebc41140dbf6569f6c405577df0c1ca126ea00cc24360d3
@@ -0,0 +1,181 @@
1
+ ENV['OTEL_LOG_LEVEL'] ||= 'debug'
2
+ ENV['OTEL_TRACES_EXPORTER'] ||= 'console,otlp'
3
+
4
+ unless defined? OTEL_ENABLED
5
+ OTEL_ENABLED = !ENV['OTEL_EXPORTER_OTLP_ENDPOINT'].to_s.empty?
6
+ end
7
+ $stdout.puts "OTEL_ENABLED: #{OTEL_ENABLED}"
8
+
9
+ # require 'async'
10
+ # require 'grape'
11
+
12
+ if OTEL_ENABLED
13
+ STACK_NAME = ENV['STACK_NAME'] || 'undefined_stack'
14
+ SERVICE_NAME = ENV['STACK_SERVICE_NAME'] || 'undefined_service'
15
+ ENV['OTEL_RESOURCE_ATTRIBUTES'] ||= "deployment.environment=#{STACK_NAME},service.name=#{SERVICE_NAME}"
16
+ ENV.select{ |k,v| k =~ /OTEL/}.each { |k,v| $stdout.puts "#{k}: #{v}"}
17
+
18
+ require 'opentelemetry/sdk'
19
+ require 'opentelemetry/exporter/otlp'
20
+ require 'opentelemetry/instrumentation/all'
21
+ require 'opentelemetry-api'
22
+ end
23
+
24
+ if defined? Async::Task and OTEL_ENABLED
25
+ module AsyncTaskOTELPatch
26
+ def initialize(parent = Task.current?, finished: nil, **options, &block)
27
+ ctx_ = OpenTelemetry::Context.current
28
+
29
+ block_otl = ->(t, *arguments){
30
+ OpenTelemetry::Context.with_current(ctx_) do
31
+ block.call t, *arguments
32
+ end
33
+ }
34
+ super parent, finished: , **options, &block_otl
35
+ end
36
+ end
37
+
38
+ Async::Task.prepend AsyncTaskOTELPatch
39
+ end
40
+
41
+ def flatten_hash(hash, path = [], result = {})
42
+ hash.each do |k, v|
43
+ path += [k]
44
+ result[path.join('.')] = v.to_s if v.is_a?(String) || v.is_a?(Numeric)
45
+ flatten_hash(v, path, result) if v.is_a?(Hash) || v.is_a?(Array)
46
+ path.pop
47
+ end
48
+ result
49
+ end
50
+
51
+ if defined? LOGGER and OTEL_ENABLED
52
+ OpenTelemetry.logger = LOGGER
53
+ end
54
+
55
+ def otel_initialize
56
+ $stderr.puts "otl_configure: OTEL_ENABLED: #{OTEL_ENABLED}"
57
+ return unless OTEL_ENABLED
58
+
59
+ OpenTelemetry::SDK.configure do |c|
60
+ # c.service_name = SERVICE_NAME
61
+ c.use_all # enables all instrumentation!
62
+ end
63
+
64
+ at_exit do
65
+ OpenTelemetry.tracer_provider.force_flush
66
+ OpenTelemetry.tracer_provider.shutdown
67
+ end
68
+
69
+ $tracer_ = OpenTelemetry.tracer_provider.tracer(SERVICE_NAME)
70
+
71
+ otl_span "#{SERVICE_NAME} start", {
72
+ 'stack.name': ENV['STACK_NAME'],
73
+ 'stack.service.name': ENV['STACK_SERVICE_NAME'],
74
+ 'org.opencontainers.image.title': ENV['ORG_OPENCONTAINERS_IMAGE_TITLE'],
75
+ 'org.opencontainers.image.url': ENV['ORG_OPENCONTAINERS_IMAGE_URL'],
76
+ 'org.opencontainers.image.source': ENV['ORG_OPENCONTAINERS_IMAGE_SOURCE'],
77
+ 'org.opencontainers.image.created': ENV['ORG_OPENCONTAINERS_IMAGE_CREATED'],
78
+ 'com.gitlab.ci.commt.timestamp': ENV['COM_GITLAB_CI_COMMIT_TIMESTAMP'],
79
+ 'com.gitlab.ci.tag': ENV['COM_GITLAB_CI_TAG'],
80
+ RACK_ENV: ENV['RACK_ENV'],
81
+ NODE_ENV: ENV['NODE_ENV'],
82
+ SERVER_ENV: ENV['SERVER_ENV'],
83
+ } do |span|
84
+
85
+ span.add_event("not-working in kibana APM", attributes:{
86
+ event: 'Success',
87
+ message: 'Get data from elastic Success'
88
+ }.transform_keys(&:to_s) )
89
+ # span.status = OpenTelemetry::Trace::Status.error("error message here!")
90
+ end
91
+
92
+ end
93
+
94
+ if defined? Sequel and OTEL_ENABLED
95
+ class Sequel::Database
96
+ alias old_test_connection test_connection
97
+
98
+ def test_connection(...)
99
+ OpenTelemetry::Common::Utilities.untraced do
100
+ old_test_connection(...)
101
+ end
102
+ end
103
+
104
+ alias old_valid_connection? valid_connection?
105
+ def valid_connection?(...)
106
+ OpenTelemetry::Common::Utilities.untraced do
107
+ old_valid_connection?(...)
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ def otl_span(name, attributes = {})
114
+ # span_ = OpenTelemetry::Trace.current_span
115
+ return yield(nil) unless OTEL_ENABLED
116
+
117
+ return yield(nil) unless $tracer_
118
+ $tracer_&.in_span(name, attributes: flatten_hash(attributes.transform_keys(&:to_s).transform_values{_1 || 'n/a'}) ) do |span|
119
+ yield span
120
+ end
121
+ end
122
+
123
+ def otl_current_span
124
+ return unless OTEL_ENABLED
125
+ yield OpenTelemetry::Trace.current_span
126
+ end
127
+
128
+ def otl_def(name)
129
+ original_method = self.respond_to?(:instance_method) ? instance_method(name) : method(name)
130
+ self.respond_to?(:remove_method) ? remove_method(name) : Object.send(:remove_method, name)
131
+ original_method = original_method.respond_to?(:unbind) ? original_method.unbind : original_method
132
+
133
+ define_method(name) do |*args, **kwargs, &block|
134
+ klass = self.respond_to?(:class_name) ? self.class_name : (self.respond_to?(:name) ? self.name : 'main')
135
+ otl_span("method: #{klass}.#{name}", {args: args.to_s, kwargs: kwargs.to_s}) do |span|
136
+ original_method.bind(self).call(*args, **kwargs, &block)
137
+ end
138
+ end
139
+ end
140
+
141
+ if defined? OpenTelemetry::Instrumentation::Rack::Middlewares
142
+ OpenTelemetry::Instrumentation::Rack::Middlewares::TracerMiddleware.config[:url_quantization] = ->(path, env) {
143
+ "HTTP #{env['REQUEST_METHOD']} #{path}"
144
+ }
145
+ end
146
+
147
+ if OTEL_ENABLED
148
+ class OpenTelemetry::SDK::Trace::Span
149
+ alias add_attributes_old add_attributes
150
+
151
+ def add_attributes(attributes)
152
+ add_attributes_old flatten_hash attributes
153
+ .transform_keys(&:to_s)
154
+ .transform_values{ _1 || 'n/a' }
155
+ end
156
+ end
157
+ end
158
+
159
+ if defined? Safrano::Request and OTEL_ENABLED
160
+ require 'odata/error'
161
+
162
+ class Safrano::Request
163
+ def process
164
+ begin
165
+ @response = Safrano::Response.new
166
+ before.tap_error { |err| dispatch_error(err) }
167
+ .tap_valid { |_res| dispatch }
168
+
169
+ rescue Sequel::Error => e
170
+ OpenTelemetry::Trace.current_span.tap do |span|
171
+ span.record_exception(e)
172
+ span.status = OpenTelemetry::Trace::Status.error("Unhandled exception of type: #{e.class}")
173
+ end
174
+ dispatch_error(Safrano::SequelExceptionError.new(e))
175
+ end
176
+ @response.finish
177
+ end
178
+ end
179
+ end
180
+
181
+
@@ -1,6 +1,12 @@
1
+ require 'stack-service-base/open_telemetry'
2
+
1
3
  module StackServiceBase
2
4
  class << self
3
5
  def rack_setup app
6
+ # skip if called within Rspec task
7
+ # TODO: warn if called not within Rspec task but with a wrong app class
8
+ return unless app.respond_to? :use
9
+
4
10
  app.instance_eval do
5
11
  if ENV.fetch('PROMETHEUS_METRICS_EXPORT', 'true') == 'true'
6
12
  require 'stack-service-base/prometheus'
@@ -9,6 +15,12 @@ module StackServiceBase
9
15
  use Prometheus::Middleware::Collector
10
16
  use Prometheus::Middleware::Exporter
11
17
  end
18
+
19
+ if OTEL_ENABLED
20
+ otel_initialize
21
+
22
+ end
23
+
12
24
  end
13
25
  end
14
26
  end
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module StackServiceBase
2
2
  class Base
3
- VERSION = '0.0.2'
3
+ VERSION = '0.0.4'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stack-service-base
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-05-01 00:00:00.000000000 Z
11
+ date: 2025-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: prometheus-client
@@ -24,6 +24,48 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: opentelemetry-sdk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: opentelemetry-exporter-otlp
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: opentelemetry-instrumentation-all
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: rake
29
71
  requirement: !ruby/object:Gem::Requirement
@@ -115,6 +157,7 @@ extensions: []
115
157
  extra_rdoc_files: []
116
158
  files:
117
159
  - lib/stack-service-base.rb
160
+ - lib/stack-service-base/open_telemetry.rb
118
161
  - lib/stack-service-base/prometheus.rb
119
162
  - lib/stack-service-base/prometheus_parser.rb
120
163
  - lib/version.rb
OSZAR »