instana 1.10.1-java

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.
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)