instana 1.10.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +23 -0
  3. data/.gitignore +16 -0
  4. data/.rubocop.yml +1156 -0
  5. data/.travis.yml +43 -0
  6. data/Configuration.md +149 -0
  7. data/Dockerfile +13 -0
  8. data/Gemfile +41 -0
  9. data/LICENSE +21 -0
  10. data/README.md +102 -0
  11. data/Rakefile +56 -0
  12. data/Tracing.md +145 -0
  13. data/Troubleshooting.md +32 -0
  14. data/benchmarks/Gemfile +7 -0
  15. data/benchmarks/id_generation.rb +12 -0
  16. data/benchmarks/opentracing.rb +26 -0
  17. data/benchmarks/rack_vanilla_vs_traced.rb +80 -0
  18. data/benchmarks/stackprof_rack_tracing.rb +77 -0
  19. data/benchmarks/time_processing.rb +12 -0
  20. data/bin/console +7 -0
  21. data/bin/setup +8 -0
  22. data/examples/opentracing.rb +31 -0
  23. data/examples/tracing.rb +80 -0
  24. data/gemfiles/libraries.gemfile +71 -0
  25. data/gemfiles/rails32.gemfile +51 -0
  26. data/gemfiles/rails42.gemfile +50 -0
  27. data/gemfiles/rails50.gemfile +52 -0
  28. data/instana.gemspec +46 -0
  29. data/lib/instana.rb +12 -0
  30. data/lib/instana/agent.rb +441 -0
  31. data/lib/instana/agent/helpers.rb +61 -0
  32. data/lib/instana/agent/hooks.rb +37 -0
  33. data/lib/instana/agent/tasks.rb +48 -0
  34. data/lib/instana/base.rb +54 -0
  35. data/lib/instana/collector.rb +116 -0
  36. data/lib/instana/collectors/gc.rb +57 -0
  37. data/lib/instana/collectors/memory.rb +34 -0
  38. data/lib/instana/collectors/thread.rb +30 -0
  39. data/lib/instana/config.rb +79 -0
  40. data/lib/instana/eum/eum-test.js.erb +16 -0
  41. data/lib/instana/eum/eum.js.erb +14 -0
  42. data/lib/instana/frameworks/cuba.rb +6 -0
  43. data/lib/instana/frameworks/instrumentation/abstract_mysql_adapter.rb +58 -0
  44. data/lib/instana/frameworks/instrumentation/action_controller.rb +183 -0
  45. data/lib/instana/frameworks/instrumentation/action_view.rb +43 -0
  46. data/lib/instana/frameworks/instrumentation/active_record.rb +27 -0
  47. data/lib/instana/frameworks/instrumentation/mysql2_adapter.rb +81 -0
  48. data/lib/instana/frameworks/instrumentation/mysql_adapter.rb +56 -0
  49. data/lib/instana/frameworks/instrumentation/postgresql_adapter.rb +71 -0
  50. data/lib/instana/frameworks/rails.rb +42 -0
  51. data/lib/instana/frameworks/roda.rb +6 -0
  52. data/lib/instana/frameworks/sinatra.rb +9 -0
  53. data/lib/instana/helpers.rb +40 -0
  54. data/lib/instana/instrumentation.rb +21 -0
  55. data/lib/instana/instrumentation/dalli.rb +78 -0
  56. data/lib/instana/instrumentation/excon.rb +74 -0
  57. data/lib/instana/instrumentation/grpc.rb +84 -0
  58. data/lib/instana/instrumentation/net-http.rb +66 -0
  59. data/lib/instana/instrumentation/rack.rb +77 -0
  60. data/lib/instana/instrumentation/redis.rb +82 -0
  61. data/lib/instana/instrumentation/resque.rb +131 -0
  62. data/lib/instana/instrumentation/rest-client.rb +34 -0
  63. data/lib/instana/instrumentation/sidekiq-client.rb +45 -0
  64. data/lib/instana/instrumentation/sidekiq-worker.rb +54 -0
  65. data/lib/instana/opentracing/carrier.rb +4 -0
  66. data/lib/instana/opentracing/tracer.rb +18 -0
  67. data/lib/instana/rack.rb +10 -0
  68. data/lib/instana/setup.rb +36 -0
  69. data/lib/instana/test.rb +40 -0
  70. data/lib/instana/thread_local.rb +15 -0
  71. data/lib/instana/tracer.rb +392 -0
  72. data/lib/instana/tracing/processor.rb +92 -0
  73. data/lib/instana/tracing/span.rb +401 -0
  74. data/lib/instana/tracing/span_context.rb +33 -0
  75. data/lib/instana/util.rb +261 -0
  76. data/lib/instana/version.rb +4 -0
  77. data/lib/oj_check.rb +16 -0
  78. data/lib/opentracing.rb +6 -0
  79. data/test/agent/agent_test.rb +143 -0
  80. data/test/apps/cuba.rb +15 -0
  81. data/test/apps/grpc_server.rb +81 -0
  82. data/test/apps/roda.rb +10 -0
  83. data/test/apps/sinatra.rb +5 -0
  84. data/test/benchmarks/bench_id_generation.rb +12 -0
  85. data/test/benchmarks/bench_opentracing.rb +13 -0
  86. data/test/config_test.rb +37 -0
  87. data/test/frameworks/cuba_test.rb +44 -0
  88. data/test/frameworks/rack_test.rb +167 -0
  89. data/test/frameworks/rails/actioncontroller_test.rb +93 -0
  90. data/test/frameworks/rails/actionview3_test.rb +255 -0
  91. data/test/frameworks/rails/actionview4_test.rb +254 -0
  92. data/test/frameworks/rails/actionview5_test.rb +221 -0
  93. data/test/frameworks/rails/activerecord3_test.rb +134 -0
  94. data/test/frameworks/rails/activerecord4_test.rb +134 -0
  95. data/test/frameworks/rails/activerecord5_test.rb +87 -0
  96. data/test/frameworks/roda_test.rb +44 -0
  97. data/test/frameworks/sinatra_test.rb +44 -0
  98. data/test/instana_test.rb +27 -0
  99. data/test/instrumentation/dalli_test.rb +253 -0
  100. data/test/instrumentation/excon_test.rb +147 -0
  101. data/test/instrumentation/grpc_test.rb +377 -0
  102. data/test/instrumentation/net-http_test.rb +160 -0
  103. data/test/instrumentation/redis_test.rb +119 -0
  104. data/test/instrumentation/resque_test.rb +128 -0
  105. data/test/instrumentation/rest-client_test.rb +55 -0
  106. data/test/instrumentation/sidekiq-client_test.rb +125 -0
  107. data/test/instrumentation/sidekiq-worker_test.rb +173 -0
  108. data/test/jobs/resque_error_job.rb +22 -0
  109. data/test/jobs/resque_fast_job.rb +20 -0
  110. data/test/jobs/sidekiq_job_1.rb +6 -0
  111. data/test/jobs/sidekiq_job_2.rb +7 -0
  112. data/test/models/block.rb +18 -0
  113. data/test/servers/grpc_50051.rb +20 -0
  114. data/test/servers/helpers/sidekiq_worker_initializer.rb +27 -0
  115. data/test/servers/rackapp_6511.rb +25 -0
  116. data/test/servers/rails_3205.rb +167 -0
  117. data/test/servers/sidekiq/worker.rb +27 -0
  118. data/test/test_helper.rb +145 -0
  119. data/test/tracing/custom_test.rb +158 -0
  120. data/test/tracing/id_management_test.rb +130 -0
  121. data/test/tracing/opentracing_test.rb +335 -0
  122. data/test/tracing/trace_test.rb +67 -0
  123. data/test/tracing/tracer_async_test.rb +198 -0
  124. data/test/tracing/tracer_test.rb +223 -0
  125. metadata +327 -0
@@ -0,0 +1,125 @@
1
+ require 'test_helper'
2
+
3
+ class SidekiqClientTest < Minitest::Test
4
+ def test_config_defaults
5
+ assert ::Instana.config[:'sidekiq-client'].is_a?(Hash)
6
+ assert ::Instana.config[:'sidekiq-client'].key?(:enabled)
7
+ assert_equal true, ::Instana.config[:'sidekiq-client'][:enabled]
8
+ end
9
+
10
+ def test_enqueue
11
+ clear_all!
12
+ Instana.tracer.start_or_continue_trace(:sidekiqtests) do
13
+ disable_redis_instrumentation
14
+ ::Sidekiq::Client.push(
15
+ 'queue' => 'some_random_queue',
16
+ 'class' => ::SidekiqJobOne,
17
+ 'args' => [1, 2, 3],
18
+ 'retry' => false
19
+ )
20
+ enable_redis_instrumentation
21
+ end
22
+
23
+ queue = ::Sidekiq::Queue.new('some_random_queue')
24
+ job = queue.first
25
+
26
+ assert_job_enqueued(job)
27
+ assert_normal_trace_recorded(job)
28
+ end
29
+
30
+ def test_enqueue_failure
31
+ clear_all!
32
+
33
+ Instana.tracer.start_or_continue_trace(:sidekiqtests) do
34
+ disable_redis_instrumentation
35
+ add_sidekiq_exception_middleware
36
+ begin
37
+ ::Sidekiq::Client.push(
38
+ 'queue' => 'some_random_queue',
39
+ 'class' => ::SidekiqJobTwo,
40
+ 'args' => [1, 2, 3],
41
+ 'retry' => false
42
+ )
43
+ rescue; end
44
+ enable_redis_instrumentation
45
+ remove_sidekiq_exception_middleware
46
+ end
47
+
48
+ queue = ::Sidekiq::Queue.new('some_random_queue')
49
+ assert_equal 0, queue.size
50
+
51
+ assert_failure_trace_recorded
52
+ end
53
+
54
+ private
55
+
56
+ def assert_job_enqueued(job)
57
+ job_message = JSON.parse(job.value)
58
+
59
+ assert_equal 'some_random_queue', job_message['queue']
60
+ assert_equal 'SidekiqJobOne', job_message['class']
61
+ assert_equal [1, 2, 3], job_message['args']
62
+ assert_equal false, job_message['retry']
63
+ assert_equal false, job_message['X-Instana-T'].nil?
64
+ assert_equal false, job_message['X-Instana-S'].nil?
65
+ end
66
+
67
+ def assert_normal_trace_recorded(job)
68
+ spans = ::Instana.processor.queued_spans
69
+ assert_equal 2, spans.length
70
+
71
+ first_span = spans[1]
72
+ second_span = spans[0]
73
+
74
+ assert_equal first_span[:s], second_span[:p]
75
+ validate_sdk_span(first_span, {:name => :sidekiqtests, :type => :intermediate})
76
+
77
+ assert_equal :'sidekiq-client', second_span[:n]
78
+ assert_equal 'some_random_queue', second_span[:data][:'sidekiq-client'][:queue]
79
+ assert_equal 'SidekiqJobOne', second_span[:data][:'sidekiq-client'][:job]
80
+ assert_equal "false", second_span[:data][:'sidekiq-client'][:retry]
81
+ assert_equal job['jid'], second_span[:data][:'sidekiq-client'][:job_id]
82
+ end
83
+
84
+ def assert_failure_trace_recorded
85
+ spans = ::Instana.processor.queued_spans
86
+ assert_equal 2, spans.length
87
+
88
+ first_span = spans[1]
89
+ second_span = spans[0]
90
+
91
+ assert_equal first_span[:s], second_span[:p]
92
+ validate_sdk_span(first_span, {:name => :sidekiqtests, :type => :intermediate})
93
+
94
+ assert_equal :'sidekiq-client', second_span[:n]
95
+ assert_equal true, second_span[:error]
96
+ assert_equal false, second_span[:stack].nil?
97
+
98
+ assert_equal 'some_random_queue', second_span[:data][:'sidekiq-client'][:queue]
99
+ assert_equal 'SidekiqJobTwo', second_span[:data][:'sidekiq-client'][:job]
100
+ assert_equal "false", second_span[:data][:'sidekiq-client'][:retry]
101
+ assert_equal 'Fail to enqueue job', second_span[:data][:log][:message]
102
+ end
103
+
104
+ SidekiqMiddlewareException = Class.new do
105
+ def call(*_args)
106
+ raise 'Fail to enqueue job'
107
+ end
108
+ end
109
+
110
+ def add_sidekiq_exception_middleware
111
+ Sidekiq.configure_client do |config|
112
+ config.client_middleware do |chain|
113
+ chain.add SidekiqMiddlewareException
114
+ end
115
+ end
116
+ end
117
+
118
+ def remove_sidekiq_exception_middleware
119
+ Sidekiq.configure_client do |config|
120
+ config.client_middleware do |chain|
121
+ chain.remove SidekiqMiddlewareException
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,173 @@
1
+ require 'test_helper'
2
+
3
+ class SidekiqServerTest < Minitest::Test
4
+ def test_config_defaults
5
+ assert ::Instana.config[:'sidekiq-worker'].is_a?(Hash)
6
+ assert ::Instana.config[:'sidekiq-worker'].key?(:enabled)
7
+ assert_equal true, ::Instana.config[:'sidekiq-worker'][:enabled]
8
+ end
9
+
10
+ def test_successful_worker_starts_new_trace
11
+ clear_all!
12
+ $sidekiq_mode = :server
13
+ inject_instrumentation
14
+
15
+ disable_redis_instrumentation
16
+ ::Sidekiq.redis_pool.with do |redis|
17
+ redis.sadd('queues'.freeze, 'important')
18
+ redis.lpush(
19
+ 'queue:important',
20
+ <<-JSON
21
+ {
22
+ "class":"SidekiqJobOne",
23
+ "args":[1,2,3],
24
+ "queue":"important",
25
+ "jid":"123456789"
26
+ }
27
+ JSON
28
+ )
29
+ end
30
+ enable_redis_instrumentation
31
+ sleep 1
32
+
33
+ spans = Instana.processor.queued_spans
34
+ worker_span = find_spans_by_name(spans, :'sidekiq-worker').first
35
+ assert_successful_worker_span(worker_span)
36
+
37
+ $sidekiq_mode = :client
38
+ end
39
+
40
+ def test_failed_worker_starts_new_trace
41
+ clear_all!
42
+ $sidekiq_mode = :server
43
+ inject_instrumentation
44
+
45
+ disable_redis_instrumentation
46
+ ::Sidekiq.redis_pool.with do |redis|
47
+ redis.sadd('queues'.freeze, 'important')
48
+ redis.lpush(
49
+ 'queue:important',
50
+ <<-JSON
51
+ {
52
+ "class":"SidekiqJobTwo",
53
+ "args":[1,2,3],
54
+ "queue":"important",
55
+ "jid":"123456789"
56
+ }
57
+ JSON
58
+ )
59
+ end
60
+ enable_redis_instrumentation
61
+
62
+ sleep 1
63
+
64
+ spans = Instana.processor.queued_spans
65
+ worker_span = find_spans_by_name(spans, :'sidekiq-worker').first
66
+ assert_failed_worker_span(worker_span)
67
+
68
+ $sidekiq_mode = :client
69
+ end
70
+
71
+ def test_successful_worker_continues_previous_trace
72
+ clear_all!
73
+ $sidekiq_mode = :server
74
+ inject_instrumentation
75
+
76
+ Instana.tracer.start_or_continue_trace(:sidekiqtests) do
77
+ disable_redis_instrumentation
78
+ ::Sidekiq::Client.push(
79
+ 'queue' => 'important',
80
+ 'class' => ::SidekiqJobOne,
81
+ 'args' => [1, 2, 3]
82
+ )
83
+ enable_redis_instrumentation
84
+ end
85
+ sleep 1
86
+ spans = Instana.processor.queued_spans
87
+
88
+ sdk_span = find_spans_by_name(spans, :sidekiqtests).first
89
+ validate_sdk_span(sdk_span)
90
+
91
+ client_span = find_spans_by_name(spans, :'sidekiq-client').first
92
+ assert_client_span(client_span, ::SidekiqJobOne)
93
+
94
+ worker_span = find_spans_by_name(spans, :'sidekiq-worker').first
95
+ assert_successful_worker_span(worker_span)
96
+
97
+ # Worker trace and client trace are in the same trace
98
+ assert_equal worker_span[:t], client_span[:t]
99
+ assert_equal worker_span[:p], client_span[:s]
100
+
101
+ $sidekiq_mode = :client
102
+ end
103
+
104
+ def test_failed_worker_continues_previous_trace
105
+ clear_all!
106
+ $sidekiq_mode = :server
107
+ inject_instrumentation
108
+
109
+ Instana.tracer.start_or_continue_trace(:sidekiqtests) do
110
+ disable_redis_instrumentation
111
+ ::Sidekiq::Client.push(
112
+ 'queue' => 'important',
113
+ 'class' => ::SidekiqJobTwo,
114
+ 'args' => [1, 2, 3]
115
+ )
116
+ enable_redis_instrumentation
117
+ end
118
+ sleep 1
119
+
120
+ spans = Instana.processor.queued_spans
121
+
122
+ sdk_span = find_spans_by_name(spans, :sidekiqtests).first
123
+ validate_sdk_span(sdk_span)
124
+
125
+ client_span = find_spans_by_name(spans, :'sidekiq-client').first
126
+ assert_client_span(client_span, ::SidekiqJobTwo)
127
+
128
+ worker_span = find_spans_by_name(spans, :'sidekiq-worker').first
129
+ assert_failed_worker_span(worker_span)
130
+
131
+ # Worker trace and client trace are in the same trace
132
+ assert_equal worker_span[:t], client_span[:t]
133
+ assert_equal worker_span[:p], client_span[:s]
134
+
135
+ $sidekiq_mode = :client
136
+ end
137
+
138
+ private
139
+
140
+ def inject_instrumentation
141
+ # Add the instrumentation again to ensure injection in server mode
142
+ ::Sidekiq.configure_server do |cfg|
143
+ cfg.server_middleware do |chain|
144
+ chain.add ::Instana::Instrumentation::SidekiqWorker
145
+ end
146
+ end
147
+ end
148
+
149
+ def assert_successful_worker_span(worker_span)
150
+ assert_equal :'sidekiq-worker', worker_span[:n]
151
+
152
+ assert_equal 'important', worker_span[:data][:'sidekiq-worker'][:queue]
153
+ assert_equal 'SidekiqJobOne', worker_span[:data][:'sidekiq-worker'][:job]
154
+ assert_equal false, worker_span[:data][:'sidekiq-worker'][:job_id].nil?
155
+ end
156
+
157
+ def assert_failed_worker_span(worker_span)
158
+ assert_equal :'sidekiq-worker', worker_span[:n]
159
+
160
+ assert_equal 'important', worker_span[:data][:'sidekiq-worker'][:queue]
161
+ assert_equal 'SidekiqJobTwo', worker_span[:data][:'sidekiq-worker'][:job]
162
+ assert_equal false, worker_span[:data][:'sidekiq-worker'][:job_id].nil?
163
+
164
+ assert_equal true, worker_span[:data][:'sidekiq-worker'][:error]
165
+ assert_equal 'Fail to execute the job', worker_span[:data][:log][:message]
166
+ end
167
+
168
+ def assert_client_span(client_span, job)
169
+ assert_equal :'sidekiq-client', client_span[:n]
170
+ assert_equal 'important', client_span[:data][:'sidekiq-client'][:queue]
171
+ assert_equal job.name, client_span[:data][:'sidekiq-client'][:job]
172
+ end
173
+ end
@@ -0,0 +1,22 @@
1
+ require "redis"
2
+ require "net/http"
3
+
4
+ class ErrorJob
5
+ @queue = :critical
6
+
7
+ def self.perform
8
+ if ENV.key?('REDIS_URL')
9
+ redis = Redis.new(:url => ENV['REDIS_URL'])
10
+ elsif ENV.key?('I_REDIS_URL')
11
+ redis = Redis.new(:url => ENV['I_REDIS_URL'])
12
+ else
13
+ redis = Redis.new(:url => 'localhost:6379')
14
+ end
15
+
16
+ dt = Time.now
17
+ redis.set('ts', dt)
18
+
19
+ raise Exception.new("Silly Rabbit, Trix are for kids.")
20
+ redis.set(:nb_id, 2)
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ require "redis"
2
+ require "net/http"
3
+
4
+ class FastJob
5
+ @queue = :critical
6
+
7
+ def self.perform
8
+ if ENV.key?('REDIS_URL')
9
+ redis = Redis.new(:url => ENV['REDIS_URL'])
10
+ elsif ENV.key?('I_REDIS_URL')
11
+ redis = Redis.new(:url => ENV['I_REDIS_URL'])
12
+ else
13
+ redis = Redis.new(:url => 'redis://localhost:6379')
14
+ end
15
+
16
+ dt = Time.now
17
+ redis.set('ts', dt)
18
+ redis.set(:nb_id, 2)
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ class SidekiqJobOne
2
+ include Sidekiq::Worker
3
+
4
+ def perform(a, b, c)
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ class SidekiqJobTwo
2
+ include Sidekiq::Worker
3
+
4
+ def perform(a, b, c)
5
+ raise 'Fail to execute the job'
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ class Block < ActiveRecord::Base
2
+ def do_work(*args)
3
+ block = Block.first
4
+ block.name = "Charlie"
5
+ block.color = "Black"
6
+ block.save
7
+ end
8
+ end
9
+
10
+ class CreateBlocks < ActiveRecord::Migration
11
+ def change
12
+ create_table :blocks do |t|
13
+ t.string :name
14
+ t.string :color
15
+ t.timestamps
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../apps/grpc_server.rb')
2
+
3
+ ::Instana.logger.info "Booting instrumented gRPC server on port 50051 for tests."
4
+
5
+ grpc_thread = Thread.new do
6
+ s = GRPC::RpcServer.new
7
+ Thread.current[:server] = s
8
+
9
+ s.add_http2_port('127.0.0.1:50051', :this_port_is_insecure)
10
+ s.handle(PingPongServer)
11
+ s.run_till_terminated
12
+ end
13
+
14
+ Minitest.after_run do
15
+ ::Instana.logger.info "Killing gRPC server"
16
+ grpc_thread[:server].stop
17
+ sleep 2
18
+ end
19
+
20
+ sleep 2
@@ -0,0 +1,27 @@
1
+ # This is a helper initializer to boot a local instrumented Sidekiq stack
2
+ # for development and testing.
3
+ #
4
+ # export BUNDLE_GEMFILE=/path/to/ruby-sensor/gemfiles/libraries.gemfile
5
+ # bundle install
6
+ # bundle exec sidekiq -c 2 -q important -r ./test/servers/helpers/sidekiq_worker_initializer.rb
7
+ #
8
+ # In another shell, you can boot a console to queue jobs:
9
+ #
10
+ # export BUNDLE_GEMFILE=/path/to/ruby-sensor/gemfiles/libraries.gemfile
11
+ # bundle install
12
+ # bundle exec rake console
13
+ # > require Dir.pwd + '/test/jobs/sidekiq_job_1.rb'
14
+ # > Instana.tracer.start_or_continue_trace(:sidekiq_demo) do
15
+ # > ::Sidekiq::Client.push( 'queue' => 'important', 'class' => ::SidekiqJobOne,
16
+ # > 'args' => [1, 2, 3], 'retry' => false)
17
+ # > end
18
+ #
19
+
20
+ # Load test jobs.
21
+ require Dir.pwd + '/test/jobs/sidekiq_job_1.rb'
22
+ require Dir.pwd + '/test/jobs/sidekiq_job_2.rb'
23
+
24
+ require "sidekiq"
25
+ require "instana"
26
+ ::Instana.logger.info "Booting instrumented sidekiq worker for tests."
27
+ ::Sidekiq.logger.level = ::Logger::DEBUG
@@ -0,0 +1,25 @@
1
+ require 'rack/handler/puma'
2
+ require 'rack/builder'
3
+ require 'instana/rack'
4
+
5
+ ::Instana.logger.info "Booting instrumented background Rackapp on port 6511 for tests."
6
+
7
+ Thread.new do
8
+ app = Rack::Builder.new {
9
+ use ::Instana::Rack
10
+ map "/" do
11
+ run Proc.new { |env|
12
+ [200, {"Content-Type" => "application/json"}, ["[\"Stan\",\"is\",\"on\",\"the\",\"scene!\"]"]]
13
+ }
14
+ end
15
+ map "/error" do
16
+ run Proc.new { |env|
17
+ [500, {"Content-Type" => "application/json"}, ["[\"Stan\",\"is\",\"on\",\"the\",\"error!\"]"]]
18
+ }
19
+ end
20
+ }
21
+
22
+ Rack::Handler::Puma.run(app, {:Host => '127.0.0.1', :Port => 6511})
23
+ end
24
+
25
+ sleep(2)