appmap 0.88.0 → 0.89.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 22745bf509f674a271a3bc42eb870813cf22d6e0c399a87e99377311a0ddaf67
4
- data.tar.gz: 482036f94bc62a732263ac7318e6c942efd22282d9b2ace1ae1245bda28de591
3
+ metadata.gz: 9d046b1cedf455ae967a663b200c05751c4c0659defa5e7dce0a7f760ba865b6
4
+ data.tar.gz: 790f5a9705b0d32b60467ecb8e51dc75e8fdbb2ac3af2022ee1c8a1a7c8cc8ca
5
5
  SHA512:
6
- metadata.gz: dd9fe2dc676c639487b19c5ad4c10e52d8dd1ff95ef10f0829077fc6a4100613d220df7bb8aea5c425e65158617112148827136bc2151cfd8e0a13666e49c347
7
- data.tar.gz: 5913ce200514ce676f26a6bf20e348fe9481ecd929ac9b8a5874b9f2e2d20d3bdc82722a535afebe7a153c7a7290ccf8e8e510a336f0b5d7265b6b3665b18a69
6
+ metadata.gz: 7c999d39cb9385f3758746cf93d50f291a4a6f9ae1c8b33266897975bdd9aabf4c8a3f666a3b3650ee70a24978d574a5db0bfefe2539240b582f1a430eabe399
7
+ data.tar.gz: 731810f9c4afe0c0c9130ab81d71e0c20f85860bf57fef5d5736845aba4c4d240dff101bc5a46aef4c6ca9e08f5adfe90ac749bb059fc7ecacd08aec77926f4e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # [0.89.0](https://github.com/applandinc/appmap-ruby/compare/v0.88.0...v0.89.0) (2022-09-07)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Make Rack a runtime dependency ([3f2924d](https://github.com/applandinc/appmap-ruby/commit/3f2924d41af291bfe771829c2ea7978332ff1d44))
7
+
8
+
9
+ ### Features
10
+
11
+ * Add builtin labels for JWT ([3569333](https://github.com/applandinc/appmap-ruby/commit/3569333e99f82e03fff892001f2b65eb9e8aa52a))
12
+ * Write an AppMap for each observed HTTP request ([2e89eaf](https://github.com/applandinc/appmap-ruby/commit/2e89eaf1b1f327771d1f4f0642fa6c202e0f3afb))
13
+
1
14
  # [0.88.0](https://github.com/applandinc/appmap-ruby/compare/v0.87.0...v0.88.0) (2022-08-31)
2
15
 
3
16
 
data/Gemfile CHANGED
@@ -3,3 +3,5 @@ source "https://rubygems.org"
3
3
  git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  gemspec
6
+
7
+ gem 'rack', '~> 2'
data/README.md CHANGED
@@ -92,9 +92,7 @@ You can launch a database like this:
92
92
  ```
93
93
  ➜ docker-compose -p appmap-ruby up -d
94
94
  ... stuff
95
- ➜ docker-compose ps pg
96
- Name Command State Ports
97
- -----------------------------------------------------------------------------------------
98
- appmap-ruby_pg_1 docker-entrypoint.sh postgres Up (healthy) 0.0.0.0:59134->5432/tcp
99
- ➜ export DATABASE_URL=postgres://postgres@localhost:59134
95
+ ➜ docker-compose port pg 5432
96
+ 0.0.0.0:64479
97
+ ➜ export DATABASE_URL=postgres://postgres@localhost:64479
100
98
  ```
data/appmap.gemspec CHANGED
@@ -28,10 +28,10 @@ Gem::Specification.new do |spec|
28
28
  spec.require_paths = ['lib']
29
29
 
30
30
  spec.add_dependency 'method_source'
31
- spec.add_dependency 'rack'
32
31
  spec.add_dependency 'reverse_markdown'
33
32
 
34
33
  spec.add_runtime_dependency 'activesupport'
34
+ spec.add_runtime_dependency 'rack'
35
35
 
36
36
  spec.add_development_dependency 'bundler', '>= 1.16'
37
37
  spec.add_development_dependency 'minitest', '~> 5.15'
@@ -39,7 +39,7 @@ Gem::Specification.new do |spec|
39
39
  spec.add_development_dependency 'rake', '>= 12.3.3'
40
40
  spec.add_development_dependency 'rdoc'
41
41
  spec.add_development_dependency 'rubocop'
42
- spec.add_development_dependency "rake-compiler"
42
+ spec.add_development_dependency 'rake-compiler'
43
43
 
44
44
  # Testing
45
45
  spec.add_development_dependency 'climate_control'
@@ -0,0 +1,8 @@
1
+ - method: JWT#decode
2
+ label: jwt.decode
3
+
4
+ - method: JWT#encode
5
+ label: jwt.encode
6
+
7
+ - method: JWT::Signature#verify
8
+ label: jwt.signature.verify
@@ -2,7 +2,8 @@
2
2
 
3
3
  module AppMap
4
4
  module Middleware
5
- # RemoteRecording adds `/_appmap/record` routes to control recordings via HTTP requests
5
+ # RemoteRecording adds `/_appmap/record` routes to control recordings via HTTP requests.
6
+ # It can also be enabled to emit an AppMap for each request.
6
7
  class RemoteRecording
7
8
  def initialize(app)
8
9
  require 'json'
@@ -21,7 +22,7 @@ module AppMap
21
22
  end
22
23
  end
23
24
 
24
- def start_recording
25
+ def ws_start_recording
25
26
  return [ 409, 'Recording is already in progress' ] if @tracer
26
27
 
27
28
  @events = []
@@ -32,7 +33,7 @@ module AppMap
32
33
  [ 200 ]
33
34
  end
34
35
 
35
- def stop_recording(req)
36
+ def ws_stop_recording(req)
36
37
  return [ 404, 'No recording is in progress' ] unless @tracer
37
38
 
38
39
  tracer = @tracer
@@ -75,10 +76,50 @@ module AppMap
75
76
  end
76
77
 
77
78
  def call(env)
79
+ # Note: Puma config is avaliable here. For example:
80
+ # $ env['puma.config'].final_options[:workers]
81
+ # 0
82
+
78
83
  req = Rack::Request.new(env)
79
84
  return handle_record_request(req) if req.path == '/_appmap/record'
80
85
 
81
- @app.call(env)
86
+ start_time = Time.now
87
+ # Support multi-threaded web server such as Puma by recording each thread
88
+ # into a separate Tracer.
89
+ tracer = AppMap.tracing.trace(thread: Thread.current) if record_all_requests?
90
+
91
+ @app.call(env).tap do |status, headers|
92
+ if tracer
93
+ AppMap.tracing.delete(tracer)
94
+
95
+ events = tracer.events.map(&:to_h)
96
+
97
+ appmap_name = "#{req.request_method} #{req.path} (#{status}) - #{start_time.strftime('%T.%L')}"
98
+ appmap_file_name = AppMap::Util.scenario_filename([ start_time.to_f, req.url ].join('_'))
99
+ output_dir = File.join(AppMap::DEFAULT_APPMAP_DIR, 'requests')
100
+ appmap_file_path = File.join(output_dir, appmap_file_name)
101
+
102
+ metadata = AppMap.detect_metadata
103
+ metadata[:name] = appmap_name
104
+ metadata[:timestamp] = start_time.to_f
105
+ metadata[:recorder] = {
106
+ name: 'record_requests'
107
+ }
108
+
109
+ appmap = {
110
+ version: AppMap::APPMAP_FORMAT_VERSION,
111
+ classMap: AppMap.class_map(tracer.event_methods),
112
+ metadata: metadata,
113
+ events: events
114
+ }
115
+
116
+ FileUtils.mkdir_p(output_dir)
117
+ File.write(appmap_file_path, JSON.generate(appmap))
118
+
119
+ headers['AppMap-Name'] = File.expand_path(appmap_name)
120
+ headers['AppMap-File-Name'] = File.expand_path(appmap_file_path)
121
+ end
122
+ end
82
123
  end
83
124
 
84
125
  def recording_state
@@ -92,9 +133,9 @@ module AppMap
92
133
  if method.eql?('GET')
93
134
  recording_state
94
135
  elsif method.eql?('POST')
95
- start_recording
136
+ ws_start_recording
96
137
  elsif method.eql?('DELETE')
97
- stop_recording(req)
138
+ ws_stop_recording(req)
98
139
  else
99
140
  [ 404, '' ]
100
141
  end
@@ -106,6 +147,10 @@ module AppMap
106
147
  headers['Content-Type'] && headers['Content-Type'] =~ /html/
107
148
  end
108
149
 
150
+ def record_all_requests?
151
+ ENV['APPMAP_RECORD_REQUESTS'] == 'true'
152
+ end
153
+
109
154
  def recording?
110
155
  !@event_thread.nil?
111
156
  end
data/lib/appmap/trace.rb CHANGED
@@ -48,8 +48,8 @@ module AppMap
48
48
  @tracers.empty?
49
49
  end
50
50
 
51
- def trace(enable: true)
52
- Tracer.new.tap do |tracer|
51
+ def trace(enable: true, thread: nil)
52
+ Tracer.new(thread_id: thread&.object_id).tap do |tracer|
53
53
  @tracers << tracer
54
54
  tracer.enable if enable
55
55
  end
@@ -64,7 +64,7 @@ module AppMap
64
64
  end
65
65
 
66
66
  def record_event(event, package: nil, defined_class: nil, method: nil)
67
- @tracers.each do |tracer|
67
+ @tracers.select { |tracer| tracer.thread_id.nil? || tracer.thread_id === event.thread_id }.each do |tracer|
68
68
  tracer.record_event(event, package: package, defined_class: defined_class, method: method)
69
69
  end
70
70
  end
@@ -114,14 +114,16 @@ module AppMap
114
114
 
115
115
  class Tracer
116
116
  attr_accessor :stacks
117
+ attr_reader :thread_id, :events
117
118
 
118
119
  # Records the events which happen in a program.
119
- def initialize
120
+ def initialize(thread_id: nil)
120
121
  @events = []
121
122
  @last_package_for_thread = {}
122
123
  @methods = Set.new
123
124
  @stack_printer = StackPrinter.new if StackPrinter.enabled?
124
125
  @enabled = false
126
+ @thread_id = thread_id
125
127
  end
126
128
 
127
129
  def enable
@@ -143,6 +145,8 @@ module AppMap
143
145
  def record_event(event, package: nil, defined_class: nil, method: nil)
144
146
  return unless @enabled
145
147
 
148
+ raise "Expected event in thread #{@thread_id}, got #{event.thread_id}" if @thread_id && @thread_id != event.thread_id
149
+
146
150
  @stack_printer.record(event) if @stack_printer
147
151
  @last_package_for_thread[Thread.current.object_id] = package if package
148
152
  @events << event
@@ -3,7 +3,7 @@
3
3
  module AppMap
4
4
  URL = 'https://github.com/applandinc/appmap-ruby'
5
5
 
6
- VERSION = '0.88.0'
6
+ VERSION = '0.89.0'
7
7
 
8
8
  APPMAP_FORMAT_VERSION = '1.7.0'
9
9
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appmap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.88.0
4
+ version: 0.89.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Gilpin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-31 00:00:00.000000000 Z
11
+ date: 2022-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: method_source
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rack
28
+ name: reverse_markdown
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: reverse_markdown
42
+ name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: activesupport
56
+ name: rack
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -386,6 +386,7 @@ files:
386
386
  - lib/appmap/gem_hooks/activerecord.yml
387
387
  - lib/appmap/gem_hooks/cancancan.yml
388
388
  - lib/appmap/gem_hooks/devise.yml
389
+ - lib/appmap/gem_hooks/jwt.yml
389
390
  - lib/appmap/gem_hooks/pandoc-ruby.yml
390
391
  - lib/appmap/gem_hooks/rails.yml
391
392
  - lib/appmap/gem_hooks/railties.yml