pry-remote-em 1.0.0 → 1.1.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
  SHA1:
3
- metadata.gz: 9891306377f0196004da3a9bd1c69beb92d49756
4
- data.tar.gz: d09d7572adf27c19d9b8f8fdf69290c4dc25264e
3
+ metadata.gz: e7817acab9f7eb7e0b26f10041062cfac6accfba
4
+ data.tar.gz: ad682bae7ee316f05debf4a80d73fa773415c0fb
5
5
  SHA512:
6
- metadata.gz: b15649c543deaa0b4e48fdb3ec1f8db2b7296709c50c62ac1e6e69f2b2cbf4abcaf3af61ca9270a7c850422f9afd940cd9fc38a5b2a3bfdd506e12f5bf0600ae
7
- data.tar.gz: e15c4019739eef9f214a63c6b064ca33564a12f8051da4cf25889885cfa31fca497c23b4a22110bbcb3d5a6bc15b9bbc4ed61dce7ce83ef85c5f233f1ea39c70
6
+ metadata.gz: 7da5179c0b004e65fdad81fa8706158d30cfd38275cb7710382acca32a8db54a1a85e27ac468eb20d4aa8ec15fc4fe6b24eecf14aeb353520cba1f42fcf620bf
7
+ data.tar.gz: ff0752cbb02b7c9ddc281b05c6f8feec007b09b29c50e1c30610ebb676f51fbf85b5b0f89fbf87293465fc2c18a7ad74d3521c1abe9ab66a4a8489e347bc3806
@@ -1,3 +1,12 @@
1
+ # 1.1.0
2
+
3
+ * Release separated gem version for JRuby because ruby-termios does not work on this platform
4
+ * Add `source_timestamp` to errors stored in sandbox
5
+ * Add `error_history` and `error_classes` methods to sandbox to view error list with comfort
6
+ * Add `PryRemoteEm::Sandbox.ignore_errors` to avoid capturing useless errors
7
+ * Add simple metrics collector, default `errors` metric from sandbox catcher, option to view metrics in the broker list (see Readme)
8
+ * Show server details and metrics on connect if any
9
+
1
10
  # 1.0.0
2
11
 
3
12
  ## Breaking changes
@@ -8,6 +17,7 @@
8
17
  * **BREAKING CHANGE** `PryRemoteEm::Server.run` returns whole server description instead of URL
9
18
  * **BREAKING CHANGE** Rename public constants to avoid confusing
10
19
  * **BREAKING CHANGE** Drop support for eventmachine prior to 1.0.0.beta4
20
+ * **BREAKING CHANGE** Inner transport protocol was changed, so broker, client and server of version 1.0.0 cannot work with brokers, clients and servers of previous versions
11
21
 
12
22
  ## Features
13
23
 
data/README.md CHANGED
@@ -469,6 +469,10 @@ $ pry-remote-em -P --sn -d environment
469
469
  (q) to quit; (r) to refresh; (c) to connect without proxy
470
470
  proxy to: 1
471
471
  [pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
472
+
473
+ Server details:
474
+ environment: staging
475
+
472
476
  [1] Microservice A (sandbox)> u 13
473
477
  => {"id"=>13, "violations"=>4, "status"=>"active"}
474
478
  [2] Microservice A (sandbox)> @my_bad_user = _
@@ -480,6 +484,10 @@ proxy to: 1
480
484
  $
481
485
  $ pry-remote-em pryem://127.0.0.1:6463
482
486
  [pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
487
+
488
+ Server details:
489
+ environment: staging
490
+
483
491
  [1] Microservice A (sandbox)> @my_bad_user
484
492
  => {"id"=>13, "violations"=>4, "status"=>"banned"}
485
493
  [2] Microservice A (sandbox)> exit
@@ -487,6 +495,10 @@ $ pry-remote-em pryem://127.0.0.1:6463
487
495
  $
488
496
  $ pry-remote-em pryem://127.0.0.1:6464
489
497
  [pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
498
+
499
+ Server details:
500
+ environment: staging
501
+
490
502
  [1] Microservice A (sandbox)> ping :A # Or you can use it to check infrastructure and perform custom communications between servers
491
503
  => "pong"
492
504
  [2] Microservice A (sandbox)> exit
@@ -554,19 +566,28 @@ Then, in shell:
554
566
  $ pry-remote-em -P --sn -d hostname
555
567
  [pry-remote-em] client connected to pryem://127.0.0.1:6462/
556
568
  [pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
557
- ------------------------------------
558
- | | name | hostname |
559
- ------------------------------------
560
- | 1 | Demo Server | local |
561
- ------------------------------------
569
+ ---------------------------------------------
570
+ | | name | hostname | errors |
571
+ ---------------------------------------------
572
+ | 1 | Demo Server | local | 1 |
573
+ ---------------------------------------------
562
574
  (q) to quit; (r) to refresh; (c) to connect without proxy
563
575
  proxy to: 1
564
576
  [pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
577
+
578
+ Server details:
579
+ hostname: local
580
+
581
+ Server metrics:
582
+ errors: 1
583
+
565
584
  [1] Demo Server (sandbox)> any_errors?
566
585
  => true
567
586
  [2] Demo Server (sandbox)> last_error
568
587
  => #<ZeroDivisionError: divided by 0>
569
- [3] Demo Server (sandbox)> wtf?
588
+ [3] Demo Server (sandbox)> last_error.source_timestamp
589
+ => 2018-08-09 14:53:19 UTC
590
+ [4] Demo Server (sandbox)> wtf?
570
591
  Exception: ZeroDivisionError: divided by 0
571
592
  --
572
593
  0: demo_server.rb:13:in `/'
@@ -577,8 +598,8 @@ Exception: ZeroDivisionError: divided by 0
577
598
  5: /usr/local/lib/ruby/gems/2.4.0/gems/eventmachine-1.2.7/lib/eventmachine.rb:195:in `run_machine'
578
599
  6: /usr/local/lib/ruby/gems/2.4.0/gems/eventmachine-1.2.7/lib/eventmachine.rb:195:in `run'
579
600
  7: demo_server.rb:17:in `<main>'
580
- [4] Demo Server (sandbox)> cd last_error.source_binding
581
- [5] Demo Server (main):1> whereami
601
+ [5] Demo Server (sandbox)> cd last_error.source_binding
602
+ [6] Demo Server (main):1> whereami
582
603
 
583
604
  From: /Users/user/Projects/demo/demo_server.rb @ line 12 Object#danger_mathod:
584
605
 
@@ -588,15 +609,140 @@ From: /Users/user/Projects/demo/demo_server.rb @ line 12 Object#danger_mathod:
588
609
  14: end
589
610
  15: end
590
611
 
591
- [6] Demo Server (main):1> ls
612
+ [7] Demo Server (main):1> ls
592
613
  self.methods: inspect to_s
593
614
  locals: _ __ _dir_ _ex_ _file_ _in_ _out_ _pry_ a b
594
- [7] Demo Server (main):1> a
615
+ [8] Demo Server (main):1> a
595
616
  => 1
596
- [8] Demo Server (main):1> b
617
+ [9] Demo Server (main):1> b
597
618
  => 0
598
619
  ```
599
620
 
621
+ There is maximum number of errors to store in sandbox to avoid
622
+ memory leaks. It is 100 by default, but you can tune it with
623
+ PRYEMSANDBOXERRORS environment variable. You can see simple log
624
+ about errors in memory (not from server start) and also statistics
625
+ about errors class from server start (not in memory):
626
+
627
+ ```shell
628
+ [1] Demo Server (sandbox)> error_history
629
+ No errors, yay!
630
+ [2] Demo Server (sandbox)> 3.times { 1/0 rescue PryRemoteEm::Sandbox.add_error($!) }
631
+ => nil
632
+ [3] Demo Server (sandbox)> undefined_method rescue PryRemoteEm::Sandbox.add_error($!)
633
+ => nil
634
+ [4] Demo Server (sandbox)> error_history
635
+ 2018-08-10 10:25:21 +0300 ZeroDivisionError: divided by 0
636
+ 2018-08-10 10:25:21 +0300 ZeroDivisionError: divided by 0
637
+ 2018-08-10 10:25:21 +0300 ZeroDivisionError: divided by 0
638
+ 2018-08-10 10:25:32 +0300 NameError: undefined local variable or method `unde...
639
+ => nil
640
+ [5] Demo Server (sandbox)> error_classes
641
+ ZeroDivisionError: 3
642
+ NameError: 1
643
+ => nil
644
+ [6] Demo Server (sandbox)> 100.times { undefined_method rescue PryRemoteEm::Sandbox.add_error($!) }
645
+ => 100
646
+ [7] Demo Server (sandbox)> last_errors.size
647
+ => 100
648
+ [8] Demo Server (sandbox)> error_classes
649
+ ZeroDivisionError: 3
650
+ NameError: 101
651
+ [9] Demo Server (sandbox)> error_history
652
+ 2018-08-10 10:35:17 +0300 NameError: undefined local variable or method `unde...
653
+ 2018-08-10 10:35:17 +0300 NameError: undefined local variable or method `unde...
654
+ ... 100 entries total
655
+ ```
656
+
657
+ You can also ignore some error classes. For example, you already
658
+ monitor database disconnections with another tool and don't
659
+ interested in user's NotFound excaptions:
660
+
661
+ ```ruby
662
+ PryRemoteEm::Sandbox.ignore_errors.push ActiveRecord::ConnectionTimeoutError, ActiveRecord::RecordNotFound
663
+ User.find(-1) rescue PryRemoteEm::Sandbox.add_error($!)
664
+ PryRemoteEm::Sandbox.last_errors # => []
665
+ ```
666
+
667
+ * Simple metrics collector. It can store some instance-specific
668
+ integers like requests or errors counts, number of connected users,
669
+ latencies, reconnections, cache size etc. It is not full-featured
670
+ monitoring solution, but much better than nothing, and also it is
671
+ super-simple to use. Just call following methods from anywhere
672
+ in your code:
673
+
674
+ ```ruby
675
+ Metrics = PryRemoteEm::Metrics # Just simplify naming, not necessarily
676
+ Metrics.add :requests # Add 1 to `requests` metric, starting from 0
677
+ Metrics.add :profit, 42 # Add custom value
678
+ Metrics.reduce :waiting_jobs # Using custom value is possible too (pass positive numbers)
679
+ Metrics.maximum :daily_online, current_online # Set new value only if it is bigger than current
680
+ EM.add_periodic_timer(1.day) { Metrics.set :daily_online, 0 } # Set some value explicitly
681
+ Metrics.minimum :best_latency, last_latency # Set new value only if it is smaller than current
682
+ Metrics.any? # => true
683
+ Metrics.get :requests # => 100500
684
+ Metrics.list # Hash with current values
685
+ ```
686
+
687
+ You can see all the metrics when connecting to a server and also
688
+ in the sandbox console with `show_metrics` method:
689
+
690
+ ```shell
691
+ $ pry-remote-em pryem://127.0.0.1:6463
692
+ [pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
693
+
694
+ Server details:
695
+ hostname: local
696
+
697
+ Server metrics:
698
+ requests: 100500
699
+ profit: 300000000
700
+ waiting_jobs: 0
701
+ daily_online: 70000
702
+ best_latency: 0.003
703
+
704
+ [1] Demo Server (sandbox)> show_metrics
705
+ requests: 100500
706
+ profit: 300000000
707
+ waiting_jobs: 0
708
+ daily_online: 70000
709
+ best_latency: 0.003
710
+ ```
711
+
712
+ You also can see the metrics in the broker's table with a new option:
713
+
714
+ ```shell
715
+ $ pry-remote-em -P --sn -d hostname -m requests
716
+ [pry-remote-em] client connected to pryem://127.0.0.1:6462/
717
+ [pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
718
+ -----------------------------------------------
719
+ | | name | hostname | requests |
720
+ -----------------------------------------------
721
+ | 1 | Demo Server | local | 100500 |
722
+ -----------------------------------------------
723
+ (q) to quit; (r) to refresh; (c) to connect without proxy
724
+ proxy to: q
725
+ $
726
+ $ pry-remote-em -P --sn -d hostname -m @
727
+ [pry-remote-em] client connected to pryem://127.0.0.1:6462/
728
+ [pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
729
+ ----------------------------------------------------------
730
+ | | name | hostname | metrics |
731
+ ----------------------------------------------------------
732
+ | 1 | Demo Server | local | requests: 100500 |
733
+ | | | | profit: 300000000 |
734
+ | | | | waiting_jobs: 0 |
735
+ | | | | daily_online: 70000 |
736
+ | | | | best_latency: 0.003 |
737
+ ----------------------------------------------------------
738
+ (q) to quit; (r) to refresh; (c) to connect without proxy
739
+ proxy to:
740
+ ```
741
+
742
+ One metric, `errors`, is enabled by default and will be shown in the
743
+ broker's table if it was incremented at least once. It will be
744
+ incremented on `PryRemoteEm::Sandbox.add_error` call.
745
+
600
746
  * `server` method to access PryRemoteEm::Server description object.
601
747
  For example, it can be useful for changing `details`:
602
748
 
@@ -632,6 +778,10 @@ $ pry-remote-em -P --sn -d hand_check
632
778
  --------------------------------------
633
779
  (q) to quit; (r) to refresh; (c) to connect without proxy
634
780
  proxy to: 3
781
+
782
+ Server details:
783
+ hand_check: false
784
+
635
785
  [1] Demo Server (sandbox)> HealthChecker.all_ok?
636
786
  => true
637
787
  [2] Demo Server (sandbox)> server[:details][:hand_check] = true
@@ -45,6 +45,10 @@ OptionParser.new do |opts|
45
45
  options[:show_details] = key
46
46
  end
47
47
 
48
+ opts.on('-m', '--metrics KEY', "show value from server's metrics by given key in a third column, use @ to show all metrics, default - errors (if any)") do |key|
49
+ options[:show_metrics] = key
50
+ end
51
+
48
52
  opts.on('-i', '--ignore-localhost', 'filter out localhost urls from list') do
49
53
  options[:ignore_localhost] = true
50
54
  end
@@ -34,7 +34,13 @@ module PryRemoteEm
34
34
  run(@host, @port, @opts) do
35
35
  PryRemoteEm.servers.each do |id, description|
36
36
  next unless EM.get_sockname(description[:server])
37
- register(id: description[:id], urls: description[:urls], name: description[:name], details: description[:details])
37
+ register(
38
+ id: description[:id],
39
+ urls: description[:urls],
40
+ name: description[:name],
41
+ details: description[:details],
42
+ metrics: PryRemoteEm::Metrics.list
43
+ )
38
44
  end
39
45
  end
40
46
  end
@@ -53,7 +59,7 @@ module PryRemoteEm
53
59
  end
54
60
 
55
61
  def register(description)
56
- client { |c| c.send_register_server(description[:id], description[:urls], description[:name], description[:details]) }
62
+ client { |c| c.send_register_server(description[:id], description[:urls], description[:name], description[:details], description[:metrics]) }
57
63
  end
58
64
 
59
65
  def unregister(id)
@@ -69,6 +75,7 @@ module PryRemoteEm
69
75
  def update_server(server, description)
70
76
  server.update(urls: description[:urls], name: description[:name])
71
77
  server[:details].update(description[:details])
78
+ server[:metrics].update(description[:metrics])
72
79
  end
73
80
 
74
81
  def unregister_server(id)
@@ -148,9 +155,9 @@ module PryRemoteEm
148
155
  send_server_list(Broker.servers)
149
156
  end
150
157
 
151
- def receive_register_server(id, urls, name, details)
158
+ def receive_register_server(id, urls, name, details, metrics)
152
159
  @ids.push(id)
153
- description = { urls: urls, name: name, details: details }
160
+ description = { urls: urls, name: name, details: details, metrics: metrics }
154
161
  Broker.hbeats[id] = Time.new
155
162
  server = Broker.servers[id]
156
163
  if server
@@ -11,21 +11,29 @@ module PryRemoteEm
11
11
  sc_col = list.map { |id, server| second_column_for_server(server) }
12
12
  sc_col_name = opts[:show_details] == '@' ? 'details' : opts[:show_details] || 'url'
13
13
  sc_col_len = [sc_col.flatten.map(&:size).max || 1, sc_col_name.size].max
14
- header = sprintf("| %-3s | %-#{nm_col_len}s | %-#{sc_col_len}s |", '', 'name', sc_col_name)
14
+ show_th_col = opts[:show_metrics] || list.any? { |id, server| server.has_key?('metrics') && server['metrics']['errors'] }
15
+ if show_th_col
16
+ th_col = list.map { |id, server| third_column_for_server(server) }
17
+ th_col_name = opts[:show_metrics] == '@' ? 'metrics' : opts[:show_metrics] || 'errors'
18
+ th_col_len = [th_col.flatten.map(&:size).max || 1, th_col_name.size].max
19
+ end
20
+ formatter = "| %-3s | %-#{nm_col_len}s | %-#{sc_col_len}s |#{" %-#{th_col_len}s |" if show_th_col}"
21
+ header = sprintf(formatter, '', 'name', sc_col_name, *th_col_name)
15
22
  border = ('-' * header.length)
16
23
  table = [border, header, border]
17
24
  list = list.to_a
18
25
  list = filter_server_list(list)
19
26
  list = sort_server_list(list)
20
27
  list.each.with_index do |(id, server), index|
21
- column = second_column_for_server(server)
28
+ index_column = [(index + 1).to_s]
29
+ first_column = [server['name']]
30
+ second_column = second_column_for_server(server)
31
+ third_column = third_column_for_server(server) if show_th_col
22
32
 
23
- table << sprintf("| %-2d | %-#{nm_col_len}s | %-#{sc_col_len}s |", index + 1, server['name'], column.first)
33
+ lines = show_th_col ? [second_column.size, third_column.size].max : second_column.size
24
34
 
25
- if column.size > 1
26
- column[1..-1].each do |element|
27
- table << sprintf("| %-2s | %-#{nm_col_len}s | %-#{sc_col_len}s |", '', '', element)
28
- end
35
+ lines.times do |index|
36
+ table << sprintf(formatter, index_column[index] || '', first_column[index] || '', second_column[index] || '', *(show_th_col ? third_column[index] || '' : nil))
29
37
  end
30
38
  end
31
39
  table << border
@@ -150,22 +158,36 @@ module PryRemoteEm
150
158
  end
151
159
 
152
160
  def second_column_for_server(server)
153
- column = case opts[:show_details]
161
+ data = case opts[:show_details]
154
162
  when nil then filtered_urls_list_for_server(server)
155
163
  when '@' then server['details']
156
164
  else server['details'][opts[:show_details]]
157
165
  end
158
166
 
159
- case column
160
- when Array then column.map(&:to_s)
161
- when Hash then column.map { |key, value| "#{key}: #{value}" }
162
- else [column.to_s]
163
- end
167
+ prepare_data_for_table(data)
164
168
  end
165
169
 
166
170
  def filtered_urls_list_for_server(server)
167
171
  opts[:ignore_localhost] ? server['urls'].reject { |url| %w[localhost 127.0.0.1 ::1].include?(URI.parse(url).host) } : server['urls']
168
172
  end
173
+
174
+ def third_column_for_server(server)
175
+ data = case opts[:show_metrics]
176
+ when nil then server['metrics']['errors']
177
+ when '@' then server['metrics']
178
+ else server['metrics'][opts[:show_metrics]]
179
+ end
180
+
181
+ prepare_data_for_table(data)
182
+ end
183
+
184
+ def prepare_data_for_table(data)
185
+ case data
186
+ when Array then data.map(&:to_s)
187
+ when Hash then data.map { |key, value| "#{key}: #{value}" }
188
+ else [data.to_s]
189
+ end
190
+ end
169
191
  end # module::InteractiveMenu
170
192
  end # module::Client
171
193
  end # module PryRemoteEm
@@ -1,4 +1,4 @@
1
- require 'termios'
1
+ require 'termios' unless RUBY_PLATFORM =~ /java/
2
2
 
3
3
  module PryRemoteEm
4
4
  module Client
@@ -31,7 +31,7 @@ module PryRemoteEm
31
31
  # In unbuffered mode read and select will not wait for "\n"; also will not echo characters.
32
32
  # This probably does not work on Windows.
33
33
  def bufferio(enable)
34
- return if (enable && @buff_enabled) || (!enable && !@buff_enabled)
34
+ return if !defined?(Termios) || enable && @buff_enabled || !enable && !@buff_enabled
35
35
  attr = Termios.getattr($stdin)
36
36
  enable ? (attr.c_lflag |= Termios::ICANON | Termios::ECHO) : (attr.c_lflag &= ~(Termios::ICANON|Termios::ECHO))
37
37
  Termios.setattr($stdin, Termios::TCSANOW, attr)
@@ -0,0 +1,39 @@
1
+ module PryRemoteEm
2
+ # Simple metrics system
3
+ # See Sandbox section in Readme for guide
4
+ module Metrics
5
+ def list
6
+ @list ||= Hash.new { |hash, key| hash[key] = 0 }
7
+ end
8
+
9
+ def add(name, value = 1)
10
+ list[name] += value
11
+ end
12
+
13
+ def reduce(name, value = 1)
14
+ add(name, -value)
15
+ end
16
+
17
+ def maximum(name, value)
18
+ list[name] = value if list[name] < value
19
+ end
20
+
21
+ def minimum(name, value)
22
+ list[name] = value if list[name] > value
23
+ end
24
+
25
+ def set(name, value)
26
+ list[name] = value
27
+ end
28
+
29
+ def get(name)
30
+ list[name]
31
+ end
32
+
33
+ def any?
34
+ list.any?
35
+ end
36
+
37
+ extend self
38
+ end
39
+ end
@@ -77,7 +77,7 @@ module PryRemoteEm
77
77
 
78
78
  def receive_start_tls; end
79
79
 
80
- def receive_register_server(id, urls, name, details); end
80
+ def receive_register_server(id, urls, name, details, metrics); end
81
81
  def receive_unregister_server(id); end
82
82
  def receive_server_list(list); end
83
83
  def receive_server_reload_list; end
@@ -125,8 +125,8 @@ module PryRemoteEm
125
125
  send_object({tls: true})
126
126
  end
127
127
 
128
- def send_register_server(id, urls, name, details)
129
- send_object({rs: [id, urls, name, details]})
128
+ def send_register_server(id, urls, name, details, metrics)
129
+ send_object({rs: [id, urls, name, details, metrics]})
130
130
  end
131
131
  def send_unregister_server(id)
132
132
  send_object({urs: id})
@@ -1,30 +1,32 @@
1
+ require 'pry-remote-em/metrics'
2
+
1
3
  module PryRemoteEm
2
4
  # See Readme for Sandbox using guide
3
5
  class Sandbox
4
- @@last_errors = []
5
-
6
6
  attr_accessor :pry, :server
7
7
 
8
+ # Use output methods as expected
9
+
8
10
  %w[puts putc print p pp].each do |method|
9
11
  define_method method do |*arguments|
10
12
  pry.output.puts(*arguments)
11
13
  end
12
14
  end
13
15
 
14
- def inspect
15
- 'sandbox'
16
- end
16
+ # Working with errors
17
17
 
18
- def any_errors?
19
- last_errors.any?
20
- end
18
+ @@last_errors = []
19
+ @@ignore_errors = []
20
+ @@error_classes = Hash.new { |hash, key| hash[key] = 0 }
21
21
 
22
- def last_error
23
- last_errors.last
22
+ def error_classes
23
+ return puts 'No errors, yay!' if @@error_classes.empty?
24
+ puts @@error_classes.map { |key, value| "#{key}: #{value}" }
24
25
  end
25
26
 
26
- def last_errors
27
- @@last_errors
27
+ def error_history
28
+ return puts 'No errors, yay!' unless any_errors?
29
+ puts @@last_errors.map { |error| "#{error.source_timestamp} #{"#{error.class}: #{error.message}".sub(/(?<=^.{51}).{4,}$/, '...')}" }
28
30
  end
29
31
 
30
32
  def self.add_error(exception, source_binding = nil)
@@ -32,16 +34,55 @@ module PryRemoteEm
32
34
  raise ArgumentError, 'exception with backtrace and optional binding expected'
33
35
  end
34
36
 
35
- return if @@last_errors.include?(exception)
37
+ return if @@last_errors.map(&:object_id).include?(exception.object_id) || @@ignore_errors.include?(exception.class)
38
+
39
+ timestamp = Time.now
40
+ exception.define_singleton_method(:source_timestamp) { timestamp }
36
41
 
37
42
  exception.define_singleton_method(:source_binding) { source_binding } if source_binding
38
43
 
39
44
  @@last_errors.push(exception)
45
+ @@error_classes[exception.class] += 1
46
+ Metrics.add(:errors)
40
47
 
41
48
  maximum_errors = ENV['PRYEMSANDBOXERRORS'].nil? || ENV['PRYEMSANDBOXERRORS'].empty? ? MAXIMUM_ERRORS_IN_SANDBOX : ENV['PRYEMSANDBOXERRORS'].to_i
42
49
  @@last_errors.shift if @@last_errors.size > maximum_errors
43
50
  end
44
51
 
52
+ def self.last_errors
53
+ @@last_errors
54
+ end
55
+
56
+ def self.any_errors?
57
+ @@last_errors.any?
58
+ end
59
+
60
+ def self.last_error
61
+ @@last_errors.last
62
+ end
63
+
64
+ def self.ignore_errors
65
+ @@ignore_errors
66
+ end
67
+
68
+ %w[any_errors? last_errors last_error ignore_errors].each do |method|
69
+ define_method(method) do |*arguments|
70
+ self.class.send(method, *arguments)
71
+ end
72
+ end
73
+
74
+ # Metrics related methods
75
+
76
+ def show_metrics
77
+ puts Metrics.list.map { |key, value| "#{key}: #{value}" }
78
+ end
79
+
80
+ # Safely show in Pry prompt
81
+
82
+ def inspect
83
+ 'sandbox'
84
+ end
85
+
45
86
  Pry.config.prompt_safe_objects.push(self)
46
87
  end
47
88
  end
@@ -147,7 +147,7 @@ module PryRemoteEm
147
147
  else
148
148
  description[:custom_name] = true
149
149
  end
150
- description[:name] = description[:name].first(57) + '...' if description[:name].size > 60
150
+ description[:name].sub!(/(?<=^.{57}).{4,}$/, '...')
151
151
  end
152
152
 
153
153
  def expand_url(url)
@@ -189,8 +189,18 @@ module PryRemoteEm
189
189
  end
190
190
 
191
191
  def register_in_broker(description)
192
- broker_description = { id: description[:id], urls: description[:urls], name: description[:name], details: description[:details] }
193
- broker_options = { tls: description[:tls], remote_broker: description[:remote_broker], logger: description[:logger] }
192
+ broker_description = {
193
+ id: description[:id],
194
+ urls: description[:urls],
195
+ name: description[:name],
196
+ details: description[:details],
197
+ metrics: PryRemoteEm::Metrics.list
198
+ }
199
+ broker_options = {
200
+ tls: description[:tls],
201
+ remote_broker: description[:remote_broker],
202
+ logger: description[:logger]
203
+ }
194
204
  Broker.run(description[:broker_host], description[:broker_port], broker_options) do |broker|
195
205
  broker.register(broker_description)
196
206
 
@@ -248,6 +258,16 @@ module PryRemoteEm
248
258
  @log.info("[pry-remote-em] received client connection from #{@ip}:#{@port}")
249
259
  # TODO include first level prompt in banner
250
260
  send_banner("PryRemoteEm #{VERSION} #{@opts[:tls] ? 'pryems' : 'pryem'}")
261
+ need_new_line = false
262
+ if @opts[:details].any?
263
+ send_raw("\nServer details:\n#{@opts[:details].map { |key, value| " #{key}: #{value}" } * "\n"}\n")
264
+ need_new_line = true
265
+ end
266
+ if PryRemoteEm::Metrics.any?
267
+ send_raw("\nServer metrics:\n#{PryRemoteEm::Metrics.list.map { |key, value| " #{key}: #{value}" } * "\n"}\n")
268
+ need_new_line = true
269
+ end
270
+ send_raw("\n") if need_new_line
251
271
  @log.info("#{url} PryRemoteEm #{VERSION} #{@opts[:tls] ? 'pryems' : 'pryem'}")
252
272
  @opts[:tls] ? start_tls : (@auth_required && send_auth(false))
253
273
  PryRemoteEm::Server.register(@obj, self)
@@ -394,7 +414,7 @@ module PryRemoteEm
394
414
  end
395
415
 
396
416
  def send_last_prompt
397
- @auth_required ? (after_auth { send_prompt(@last_prompt) }) : send_prompt(@last_prompt)
417
+ @auth_required ? (after_auth { send_prompt(@last_prompt) }) : send_prompt(@last_prompt)
398
418
  end
399
419
 
400
420
  def after_auth(&blk)
@@ -1,3 +1,3 @@
1
1
  module PryRemoteEm
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pry-remote-em
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Caleb Crane
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-08-09 00:00:00.000000000 Z
12
+ date: 2018-08-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -102,6 +102,7 @@ files:
102
102
  - lib/pry-remote-em/client/interactive_menu.rb
103
103
  - lib/pry-remote-em/client/keyboard.rb
104
104
  - lib/pry-remote-em/client/proxy.rb
105
+ - lib/pry-remote-em/metrics.rb
105
106
  - lib/pry-remote-em/proto.rb
106
107
  - lib/pry-remote-em/sandbox.rb
107
108
  - lib/pry-remote-em/server.rb