miniapm 1.0.0
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/CHANGELOG.md +43 -0
- data/LICENSE +21 -0
- data/README.md +174 -0
- data/lib/generators/miniapm/install_generator.rb +27 -0
- data/lib/generators/miniapm/templates/README +19 -0
- data/lib/generators/miniapm/templates/initializer.rb +60 -0
- data/lib/miniapm/configuration.rb +176 -0
- data/lib/miniapm/context.rb +138 -0
- data/lib/miniapm/error_event.rb +130 -0
- data/lib/miniapm/exporters/errors.rb +67 -0
- data/lib/miniapm/exporters/otlp.rb +90 -0
- data/lib/miniapm/instrumentations/activejob.rb +271 -0
- data/lib/miniapm/instrumentations/activerecord.rb +123 -0
- data/lib/miniapm/instrumentations/base.rb +61 -0
- data/lib/miniapm/instrumentations/cache.rb +85 -0
- data/lib/miniapm/instrumentations/http/faraday.rb +112 -0
- data/lib/miniapm/instrumentations/http/httparty.rb +84 -0
- data/lib/miniapm/instrumentations/http/net_http.rb +99 -0
- data/lib/miniapm/instrumentations/rails/controller.rb +129 -0
- data/lib/miniapm/instrumentations/rails/railtie.rb +42 -0
- data/lib/miniapm/instrumentations/redis/redis.rb +135 -0
- data/lib/miniapm/instrumentations/redis/redis_client.rb +116 -0
- data/lib/miniapm/instrumentations/registry.rb +90 -0
- data/lib/miniapm/instrumentations/search/elasticsearch.rb +121 -0
- data/lib/miniapm/instrumentations/search/opensearch.rb +120 -0
- data/lib/miniapm/instrumentations/search/searchkick.rb +119 -0
- data/lib/miniapm/instrumentations/sidekiq.rb +185 -0
- data/lib/miniapm/middleware/error_handler.rb +120 -0
- data/lib/miniapm/middleware/rack.rb +103 -0
- data/lib/miniapm/span.rb +289 -0
- data/lib/miniapm/testing.rb +209 -0
- data/lib/miniapm/trace.rb +26 -0
- data/lib/miniapm/transport/batch_sender.rb +345 -0
- data/lib/miniapm/transport/http.rb +45 -0
- data/lib/miniapm/version.rb +5 -0
- data/lib/miniapm.rb +184 -0
- metadata +183 -0
data/lib/miniapm.rb
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "logger"
|
|
4
|
+
|
|
5
|
+
require_relative "miniapm/version"
|
|
6
|
+
require_relative "miniapm/configuration"
|
|
7
|
+
require_relative "miniapm/context"
|
|
8
|
+
require_relative "miniapm/span"
|
|
9
|
+
require_relative "miniapm/trace"
|
|
10
|
+
require_relative "miniapm/error_event"
|
|
11
|
+
require_relative "miniapm/transport/http"
|
|
12
|
+
require_relative "miniapm/transport/batch_sender"
|
|
13
|
+
require_relative "miniapm/exporters/otlp"
|
|
14
|
+
require_relative "miniapm/exporters/errors"
|
|
15
|
+
require_relative "miniapm/middleware/rack"
|
|
16
|
+
require_relative "miniapm/middleware/error_handler"
|
|
17
|
+
require_relative "miniapm/instrumentations/base"
|
|
18
|
+
require_relative "miniapm/instrumentations/registry"
|
|
19
|
+
|
|
20
|
+
module MiniAPM
|
|
21
|
+
class Error < StandardError; end
|
|
22
|
+
class ConfigurationError < Error; end
|
|
23
|
+
|
|
24
|
+
class << self
|
|
25
|
+
attr_writer :configuration
|
|
26
|
+
|
|
27
|
+
def configuration
|
|
28
|
+
@configuration ||= Configuration.new
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def configure
|
|
32
|
+
yield(configuration)
|
|
33
|
+
start! if configuration.auto_start
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def start!
|
|
37
|
+
return if @started
|
|
38
|
+
|
|
39
|
+
configuration.validate!
|
|
40
|
+
|
|
41
|
+
@started = true
|
|
42
|
+
Instrumentations::Registry.install_all!
|
|
43
|
+
Transport::BatchSender.start!
|
|
44
|
+
logger.info { "MiniAPM started (service: #{configuration.service_name})" }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def stop!
|
|
48
|
+
return unless @started
|
|
49
|
+
|
|
50
|
+
Transport::BatchSender.stop!
|
|
51
|
+
@started = false
|
|
52
|
+
logger.info { "MiniAPM stopped" }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def started?
|
|
56
|
+
@started || false
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def enabled?
|
|
60
|
+
configuration.enabled && started?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def logger
|
|
64
|
+
@logger ||= begin
|
|
65
|
+
log = Logger.new($stdout)
|
|
66
|
+
log.level = Logger::INFO
|
|
67
|
+
log.progname = "MiniAPM"
|
|
68
|
+
log
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
attr_writer :logger
|
|
73
|
+
|
|
74
|
+
# Create a span with automatic context management
|
|
75
|
+
# Sampling is decided once per trace and inherited by all child spans
|
|
76
|
+
def span(name, category: :internal, attributes: {})
|
|
77
|
+
return yield(nil) unless enabled?
|
|
78
|
+
|
|
79
|
+
# Check if we're in an existing trace
|
|
80
|
+
current_trace = Context.current_trace
|
|
81
|
+
parent_span = Context.current_span
|
|
82
|
+
|
|
83
|
+
if current_trace
|
|
84
|
+
# We're already in a trace - use its sampled state
|
|
85
|
+
return yield(nil) unless current_trace.sampled?
|
|
86
|
+
|
|
87
|
+
span = if parent_span
|
|
88
|
+
parent_span.create_child(name, category: category, attributes: attributes)
|
|
89
|
+
else
|
|
90
|
+
Span.new(
|
|
91
|
+
name: name,
|
|
92
|
+
category: category,
|
|
93
|
+
trace_id: current_trace.trace_id,
|
|
94
|
+
attributes: attributes
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
else
|
|
98
|
+
# Create new trace with sampling decision
|
|
99
|
+
span = Span.new_root(name, category: category, attributes: attributes)
|
|
100
|
+
|
|
101
|
+
# new_root creates a trace - check if it's sampled
|
|
102
|
+
return yield(nil) unless Context.current_trace&.sampled?
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
Context.with_span(span) do
|
|
106
|
+
yield span
|
|
107
|
+
rescue StandardError => e
|
|
108
|
+
span.record_exception(e)
|
|
109
|
+
raise
|
|
110
|
+
ensure
|
|
111
|
+
span.finish
|
|
112
|
+
record_span(span)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def record_span(span)
|
|
117
|
+
return unless enabled?
|
|
118
|
+
return unless Context.current_trace&.sampled?
|
|
119
|
+
|
|
120
|
+
span = begin
|
|
121
|
+
configuration.before_send&.call(span) || span
|
|
122
|
+
rescue StandardError => e
|
|
123
|
+
logger.error { "MiniAPM before_send callback error: #{e.class}: #{e.message}" }
|
|
124
|
+
span # Return original span if callback fails
|
|
125
|
+
end
|
|
126
|
+
return unless span
|
|
127
|
+
|
|
128
|
+
Transport::BatchSender.enqueue(:span, span)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def record_error(exception, context: {})
|
|
132
|
+
return unless enabled?
|
|
133
|
+
return if ignored_exception?(exception)
|
|
134
|
+
|
|
135
|
+
error_event = ErrorEvent.from_exception(exception, context)
|
|
136
|
+
Transport::BatchSender.enqueue(:error, error_event)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def current_trace_id
|
|
140
|
+
Context.current_trace_id
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def current_span_id
|
|
144
|
+
Context.current_span&.span_id
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def current_span
|
|
148
|
+
Context.current_span
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Force flush all pending data (useful for testing and graceful shutdown)
|
|
152
|
+
def flush!
|
|
153
|
+
Transport::BatchSender.flush!
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Get stats about enqueued/sent/dropped data
|
|
157
|
+
def stats
|
|
158
|
+
Transport::BatchSender.stats
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Check if MiniAPM can connect to the server
|
|
162
|
+
def healthy?
|
|
163
|
+
return false unless enabled?
|
|
164
|
+
|
|
165
|
+
result = Transport::HTTP.post(
|
|
166
|
+
"#{configuration.endpoint}/health",
|
|
167
|
+
{},
|
|
168
|
+
headers: { "Authorization" => "Bearer #{configuration.api_key}" }
|
|
169
|
+
)
|
|
170
|
+
result[:success]
|
|
171
|
+
rescue StandardError
|
|
172
|
+
false
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
private
|
|
176
|
+
|
|
177
|
+
def ignored_exception?(exception)
|
|
178
|
+
configuration.ignored_exceptions.include?(exception.class.name)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Load Rails integration if Rails is present
|
|
184
|
+
require_relative "miniapm/instrumentations/rails/railtie" if defined?(Rails::Railtie)
|
metadata
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: miniapm
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Chris Hasinski
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-01-03 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rake
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '13.0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '13.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rspec
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '3.12'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '3.12'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: webmock
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '3.19'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '3.19'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: vcr
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '6.2'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '6.2'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: timecop
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0.9'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0.9'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rack
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '3.0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '3.0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: rack-test
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '2.1'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '2.1'
|
|
111
|
+
description: Ruby gem for Rails APM integration with MiniAPM. Exports traces in OTLP
|
|
112
|
+
format, captures errors, and provides comprehensive instrumentation for Rails, ActiveRecord,
|
|
113
|
+
Sidekiq, HTTP clients, Redis, and search engines.
|
|
114
|
+
email:
|
|
115
|
+
- krzysztof.hasinski@gmail.com
|
|
116
|
+
executables: []
|
|
117
|
+
extensions: []
|
|
118
|
+
extra_rdoc_files: []
|
|
119
|
+
files:
|
|
120
|
+
- CHANGELOG.md
|
|
121
|
+
- LICENSE
|
|
122
|
+
- README.md
|
|
123
|
+
- lib/generators/miniapm/install_generator.rb
|
|
124
|
+
- lib/generators/miniapm/templates/README
|
|
125
|
+
- lib/generators/miniapm/templates/initializer.rb
|
|
126
|
+
- lib/miniapm.rb
|
|
127
|
+
- lib/miniapm/configuration.rb
|
|
128
|
+
- lib/miniapm/context.rb
|
|
129
|
+
- lib/miniapm/error_event.rb
|
|
130
|
+
- lib/miniapm/exporters/errors.rb
|
|
131
|
+
- lib/miniapm/exporters/otlp.rb
|
|
132
|
+
- lib/miniapm/instrumentations/activejob.rb
|
|
133
|
+
- lib/miniapm/instrumentations/activerecord.rb
|
|
134
|
+
- lib/miniapm/instrumentations/base.rb
|
|
135
|
+
- lib/miniapm/instrumentations/cache.rb
|
|
136
|
+
- lib/miniapm/instrumentations/http/faraday.rb
|
|
137
|
+
- lib/miniapm/instrumentations/http/httparty.rb
|
|
138
|
+
- lib/miniapm/instrumentations/http/net_http.rb
|
|
139
|
+
- lib/miniapm/instrumentations/rails/controller.rb
|
|
140
|
+
- lib/miniapm/instrumentations/rails/railtie.rb
|
|
141
|
+
- lib/miniapm/instrumentations/redis/redis.rb
|
|
142
|
+
- lib/miniapm/instrumentations/redis/redis_client.rb
|
|
143
|
+
- lib/miniapm/instrumentations/registry.rb
|
|
144
|
+
- lib/miniapm/instrumentations/search/elasticsearch.rb
|
|
145
|
+
- lib/miniapm/instrumentations/search/opensearch.rb
|
|
146
|
+
- lib/miniapm/instrumentations/search/searchkick.rb
|
|
147
|
+
- lib/miniapm/instrumentations/sidekiq.rb
|
|
148
|
+
- lib/miniapm/middleware/error_handler.rb
|
|
149
|
+
- lib/miniapm/middleware/rack.rb
|
|
150
|
+
- lib/miniapm/span.rb
|
|
151
|
+
- lib/miniapm/testing.rb
|
|
152
|
+
- lib/miniapm/trace.rb
|
|
153
|
+
- lib/miniapm/transport/batch_sender.rb
|
|
154
|
+
- lib/miniapm/transport/http.rb
|
|
155
|
+
- lib/miniapm/version.rb
|
|
156
|
+
homepage: https://miniapm.com
|
|
157
|
+
licenses:
|
|
158
|
+
- MIT
|
|
159
|
+
metadata:
|
|
160
|
+
homepage_uri: https://miniapm.com
|
|
161
|
+
source_code_uri: https://github.com/miniapm/miniapm-ruby
|
|
162
|
+
changelog_uri: https://github.com/miniapm/miniapm-ruby/blob/main/CHANGELOG.md
|
|
163
|
+
documentation_uri: https://miniapm.com/docs
|
|
164
|
+
post_install_message:
|
|
165
|
+
rdoc_options: []
|
|
166
|
+
require_paths:
|
|
167
|
+
- lib
|
|
168
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
169
|
+
requirements:
|
|
170
|
+
- - ">="
|
|
171
|
+
- !ruby/object:Gem::Version
|
|
172
|
+
version: 3.0.0
|
|
173
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
|
+
requirements:
|
|
175
|
+
- - ">="
|
|
176
|
+
- !ruby/object:Gem::Version
|
|
177
|
+
version: '0'
|
|
178
|
+
requirements: []
|
|
179
|
+
rubygems_version: 3.5.22
|
|
180
|
+
signing_key:
|
|
181
|
+
specification_version: 4
|
|
182
|
+
summary: Lightweight APM client for MiniAPM server
|
|
183
|
+
test_files: []
|