pry-remote-em 1.0.0 → 1.1.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 +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +161 -11
- data/bin/pry-remote-em +4 -0
- data/lib/pry-remote-em/broker.rb +11 -4
- data/lib/pry-remote-em/client/interactive_menu.rb +35 -13
- data/lib/pry-remote-em/client/keyboard.rb +2 -2
- data/lib/pry-remote-em/metrics.rb +39 -0
- data/lib/pry-remote-em/proto.rb +3 -3
- data/lib/pry-remote-em/sandbox.rb +54 -13
- data/lib/pry-remote-em/server.rb +24 -4
- data/lib/pry-remote-em/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7817acab9f7eb7e0b26f10041062cfac6accfba
|
4
|
+
data.tar.gz: ad682bae7ee316f05debf4a80d73fa773415c0fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7da5179c0b004e65fdad81fa8706158d30cfd38275cb7710382acca32a8db54a1a85e27ac468eb20d4aa8ec15fc4fe6b24eecf14aeb353520cba1f42fcf620bf
|
7
|
+
data.tar.gz: ff0752cbb02b7c9ddc281b05c6f8feec007b09b29c50e1c30610ebb676f51fbf85b5b0f89fbf87293465fc2c18a7ad74d3521c1abe9ab66a4a8489e347bc3806
|
data/CHANGELOG.md
CHANGED
@@ -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)>
|
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
|
-
[
|
581
|
-
[
|
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
|
-
[
|
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
|
-
[
|
615
|
+
[8] Demo Server (main):1> a
|
595
616
|
=> 1
|
596
|
-
[
|
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
|
data/bin/pry-remote-em
CHANGED
@@ -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
|
data/lib/pry-remote-em/broker.rb
CHANGED
@@ -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(
|
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
|
-
|
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
|
-
|
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
|
-
|
33
|
+
lines = show_th_col ? [second_column.size, third_column.size].max : second_column.size
|
24
34
|
|
25
|
-
|
26
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
data/lib/pry-remote-em/proto.rb
CHANGED
@@ -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
|
-
|
15
|
-
'sandbox'
|
16
|
-
end
|
16
|
+
# Working with errors
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
@@last_errors = []
|
19
|
+
@@ignore_errors = []
|
20
|
+
@@error_classes = Hash.new { |hash, key| hash[key] = 0 }
|
21
21
|
|
22
|
-
def
|
23
|
-
|
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
|
27
|
-
|
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
|
data/lib/pry-remote-em/server.rb
CHANGED
@@ -147,7 +147,7 @@ module PryRemoteEm
|
|
147
147
|
else
|
148
148
|
description[:custom_name] = true
|
149
149
|
end
|
150
|
-
description[:name]
|
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 = {
|
193
|
-
|
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) }) :
|
417
|
+
@auth_required ? (after_auth { send_prompt(@last_prompt) }) : send_prompt(@last_prompt)
|
398
418
|
end
|
399
419
|
|
400
420
|
def after_auth(&blk)
|
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.
|
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-
|
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
|