pry-remote-em 1.1.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +150 -0
- data/README.md +920 -0
- data/bin/pry-remote-em +89 -0
- data/bin/pry-remote-em-broker +28 -0
- data/lib/pry-remote-em.rb +74 -0
- data/lib/pry-remote-em/broker.rb +229 -0
- data/lib/pry-remote-em/client.rb +233 -0
- data/lib/pry-remote-em/client/broker.rb +39 -0
- data/lib/pry-remote-em/client/generic.rb +74 -0
- data/lib/pry-remote-em/client/interactive_menu.rb +193 -0
- data/lib/pry-remote-em/client/keyboard.rb +42 -0
- data/lib/pry-remote-em/client/proxy.rb +33 -0
- data/lib/pry-remote-em/metrics.rb +39 -0
- data/lib/pry-remote-em/proto.rb +148 -0
- data/lib/pry-remote-em/sandbox.rb +88 -0
- data/lib/pry-remote-em/server.rb +511 -0
- data/lib/pry-remote-em/server/shell_cmd.rb +20 -0
- data/lib/pry-remote-em/version.rb +3 -0
- metadata +121 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b1af987d05e68bf782a2ac2672ecfe92dd862214
|
4
|
+
data.tar.gz: 0d34fd8cf9d034311cb7cce6f9373f36d420b7d2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 61a62fd396c249185ae09765980f71fc4cf0fc111a5e70e9d6c491cc167274f6de466e4415e8621d0cf3fcf1eac4fbc918cf76be4a4f3f861606385289f239fd
|
7
|
+
data.tar.gz: 60533d9f975f4077504d98eb13d1bd38dee3b5039db95f20d90cdbc2e320e414f8a0602b949f24eb3a2a5a3ce2e9219152560dc72dfcb0e4d26f44bca6c45850
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,150 @@
|
|
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
|
+
|
10
|
+
# 1.0.0
|
11
|
+
|
12
|
+
## Breaking changes
|
13
|
+
|
14
|
+
* **BREAKING CHANGE** Change `!` and `!!` messaging commands to `^` and `^^` to avoid confusing with Pry's built in `!` command and Ruby's `not` semantics
|
15
|
+
* **BREAKING CHANGE** Change `PryRemoteEm::Server.run` method signature to hash-only form (`remote_pry_em` method's signature didn't changed)
|
16
|
+
* **BREAKING CHANGE** Change `allow_shell_cmds` setting to `true` by default instead of `false`, because most of projects does not use $SAFE and any shell command can be run from Ruby code with `system` call or backticks, so this option is illusion in most cases
|
17
|
+
* **BREAKING CHANGE** `PryRemoteEm::Server.run` returns whole server description instead of URL
|
18
|
+
* **BREAKING CHANGE** Rename public constants to avoid confusing
|
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
|
21
|
+
|
22
|
+
## Features
|
23
|
+
|
24
|
+
* Add `PryRemoteEm::Sandbox` as target by default, see Readme for details
|
25
|
+
* Add proxy-by-default setting to CLI
|
26
|
+
* Add possibility to use environment variables on CLI connection
|
27
|
+
* Add more environment variables to control server without code changing (described in readme)
|
28
|
+
* Add support for empty environment variables and nil arguments on server start
|
29
|
+
* Add possibility to set external url for server (to use lib with NAT or Docker) using `PRYEMURL` or `external_url` option
|
30
|
+
* Add ability to use custom server name using `PRYEMNAME` environment variable or `name` option (and displaying it in the prompt)
|
31
|
+
* Add ability to start server without starting broker using `PRYEMREMOTEBROKER` environment variable or `remote_broker` option
|
32
|
+
* Add `pry-remote-em-broker` binary to start broker without starting server
|
33
|
+
* Add `Object#pry_remote_em` alias to `Object#remote_pry_em` to avoid common confusing
|
34
|
+
* Add support for options hash as first argument instead of third in `Object#remote_pry_em`
|
35
|
+
* Add local history loading on session start
|
36
|
+
* Add support for `pry-coolline` (just install this gem to make it work)
|
37
|
+
* Add support for several URIs per one server (when binding to 0.0.0.0)
|
38
|
+
* Add option to ignore localhost urls in the list (useful when server binding to 0.0.0.0 in Docker, where localhost is useless)
|
39
|
+
* Add support for `details` option on server start and corresponding CLI option to display some usefull information about server instead or url in broker table (for example, health status, which can be updated on every heartbeat via details hash mutating)
|
40
|
+
|
41
|
+
## Fixes
|
42
|
+
|
43
|
+
* Fix proxy, it didn't work at all
|
44
|
+
* Fix interative shell commands, they didn't work at all
|
45
|
+
* Fix `libc++abi.dylib: Pure virtual function called!` error on client disconnecting
|
46
|
+
* Fix strange buffer bugs on long output over network using MessagePack protocol instead of JSON
|
47
|
+
* Fix console crash on pager quit
|
48
|
+
* Fix console crash on Ctrl+C (now it's clears the buffer like in native Pry)
|
49
|
+
* Fix IPv6 localhost crash
|
50
|
+
* Fix missing requires when using broker without server
|
51
|
+
* Fix port access check when using environment variables
|
52
|
+
* Fix strange effects when registering in broker from Docker (now broker use UUID as a key instead of URI)
|
53
|
+
* Fix message `broker connection unbound starting a new one` on EventMachine stopping
|
54
|
+
* Fix unregistering in broker by timeout only, now servers unregister instantly after closing connection
|
55
|
+
* Fix interative shell commands echo printing
|
56
|
+
* Fix unknown shell command problem (now valid `command not found` message is printing)
|
57
|
+
* Fix behaviour on empty input, now it's exactly like as in native Pry
|
58
|
+
* Fix saving empty strings in history
|
59
|
+
|
60
|
+
## Chore
|
61
|
+
|
62
|
+
* Add ruby-termios to runtime dependencies to avoid confusing `unable to load keyboard dependencies` message
|
63
|
+
* Bump dependencies versions
|
64
|
+
* Remove useless return values from inner methods
|
65
|
+
* Add stable 3 seconds timeout on broker reconnection, not random one
|
66
|
+
* Require `pry-remote-em/server` by defaults
|
67
|
+
* Correct README for default broker port
|
68
|
+
* Use single quotes by default
|
69
|
+
* Use Ruby 1.9 hash syntax by default
|
70
|
+
* Use semantic versioning, starting at 1.0.0 (since we're using it in production for a long time already)
|
71
|
+
|
72
|
+
# 0.7.5
|
73
|
+
|
74
|
+
* [#42](https://github.com/gruis/pry-remote-em/pull/42) - Use bytesize String method instead of length in protocol. [distorhead](https://github.com/distorhead)
|
75
|
+
|
76
|
+
# 0.7.4
|
77
|
+
|
78
|
+
* [#40](https://github.com/gruis/pry-remote-em/pull/40) - require 'pry', not its parts [rking](https://github.com/rking)
|
79
|
+
* [#39](https://github.com/gruis/pry-remote-em/pull/39) - stagger_output needs Pry::Pager to be loaded in the parent scope [pcmantz](https://github.com/pcmantz)
|
80
|
+
|
81
|
+
# 0.7.3
|
82
|
+
|
83
|
+
* Broker listens at 6462 everything else starts at 6463
|
84
|
+
* cli assumes port 6462 when not specified
|
85
|
+
|
86
|
+
# 0.7.2
|
87
|
+
|
88
|
+
* Broker.run yields to a block when broker connection has been established
|
89
|
+
|
90
|
+
# 0.7.1
|
91
|
+
|
92
|
+
* server list can be filtered by host, port, name, or SSL support
|
93
|
+
* server list can be sorted by host, port, name, or SSL support
|
94
|
+
* cli assumes port 6461 when not specified
|
95
|
+
* cli accepts -c and -p options to immediately connect or proxy from the broker to a server matching the name specified on the command line
|
96
|
+
* closes #37 loosens pry version requirement
|
97
|
+
* client sorts server list by host address
|
98
|
+
* when registering 0.0.0.0 with a Broker register each interface instead
|
99
|
+
|
100
|
+
# 0.7.0
|
101
|
+
|
102
|
+
* fixes #21 version matching between client and server allow differences in patch levels
|
103
|
+
* fixes #31 client reports own version when incompatible with server
|
104
|
+
* client supports vi mode: rb-readline replaced by readline
|
105
|
+
* fixes #31 termios is no longer a hard requirement: shell commands will be disabled without it
|
106
|
+
* adds PryRemoteEm.servers and PryRemoteEm.stop_server
|
107
|
+
* broker can proxy requests to local or remote servers that have registered with it
|
108
|
+
* closes #11 all servers will attempt to register with a broker; client will retrieve list of servers from the broker and present a menu to the user by default
|
109
|
+
* when specifying a specific port to listen on the option :port_fail can be set to :auto; if binding fails attempt to bind on the next port
|
110
|
+
* server.run returns a url (String) with the scheme, host and port of the listening server
|
111
|
+
* json specific parts of wire protocol are abstracted away from client and server
|
112
|
+
* json proto is a bit more robust: delimeter can be a part of data and CRC is performed
|
113
|
+
|
114
|
+
# 0.6.2
|
115
|
+
|
116
|
+
* handle reset command appropriately
|
117
|
+
|
118
|
+
# 0.6.1
|
119
|
+
|
120
|
+
* messages are tagged with user that sent them if authentication is being used
|
121
|
+
|
122
|
+
# 0.6.0
|
123
|
+
|
124
|
+
* adds shell command support
|
125
|
+
* adds auth event callbacks
|
126
|
+
* adds configurable logger
|
127
|
+
|
128
|
+
# 0.5.0
|
129
|
+
|
130
|
+
* adds simple messaging with '!' and '!!'
|
131
|
+
|
132
|
+
# 0.4.3
|
133
|
+
|
134
|
+
* fixes https://github.com/gruis/pry-remote-em/issues/26
|
135
|
+
* fixes https://github.com/gruis/pry-remote-em/issues/24
|
136
|
+
|
137
|
+
# 0.4.2
|
138
|
+
|
139
|
+
* fixes https://github.com/gruis/pry-remote-em/issues/23
|
140
|
+
|
141
|
+
# 0.4.1
|
142
|
+
|
143
|
+
* empty lines don't cause termination
|
144
|
+
|
145
|
+
# 0.4.0
|
146
|
+
|
147
|
+
* User/Pass authentication
|
148
|
+
* TLS support
|
149
|
+
* Paging support
|
150
|
+
* Tab completion
|
data/README.md
ADDED
@@ -0,0 +1,920 @@
|
|
1
|
+
[PryRemoteEm](https://rubygems.org/gems/pry-remote-em) enables you to
|
2
|
+
start instances of Pry in a running
|
3
|
+
[EventMachine](http://rubyeventmachine.com/) program and connect to
|
4
|
+
those Pry instances over a network or the Internet. Once connected you
|
5
|
+
can interact with the internal state of the program.
|
6
|
+
|
7
|
+
It's based off of [Mon-Ouie's](https://github.com/Mon-Ouie) [pry-remote](https://github.com/Mon-Ouie/pry-remote) for DRb.
|
8
|
+
|
9
|
+
It adds user authentication and SSL support along with tab-completion
|
10
|
+
and paging. It's compatble with MRI 1.9, or any other VM with support
|
11
|
+
for Fibers and EventMachine.
|
12
|
+
|
13
|
+
|
14
|
+
# Installation
|
15
|
+
|
16
|
+
```bash
|
17
|
+
gem install pry-remote-em
|
18
|
+
```
|
19
|
+
|
20
|
+
# Usage
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
require 'pry-remote-em/server'
|
24
|
+
|
25
|
+
class Foo
|
26
|
+
def initialize(x, y)
|
27
|
+
binding.remote_pry_em
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
EM.run { Foo.new 10, 20 }
|
32
|
+
```
|
33
|
+
|
34
|
+
Running it will print out a message telling you Pry is waiting for a
|
35
|
+
program to connect itself to it:
|
36
|
+
|
37
|
+
[pry-remote-em] listening for connections on pryem://127.0.0.1:6462/
|
38
|
+
|
39
|
+
You can then connect to the pry session using ``pry-remote-em``:
|
40
|
+
|
41
|
+
$ pry-remote-em pryem://127.0.0.1:6462/
|
42
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6462/
|
43
|
+
[pry-remote-em] remote is PryRemoteEm 0.1.0
|
44
|
+
[1] pry(#<Foo>)> stat
|
45
|
+
Method Information:
|
46
|
+
--
|
47
|
+
Name: initialize
|
48
|
+
Owner: Foo
|
49
|
+
Visibility: private
|
50
|
+
Type: Bound
|
51
|
+
Arity: 2
|
52
|
+
Method Signature: initialize(x, y)
|
53
|
+
Source Location: (irb):2
|
54
|
+
|
55
|
+
[2] pry(#<Foo>)> self
|
56
|
+
=> #<Foo:0x007fe66a426fa0>
|
57
|
+
|
58
|
+
[3] pry(#<Foo>)> ls
|
59
|
+
locals: _ _dir_ _ex_ _file_ _in_ _out_ _pry_ x y
|
60
|
+
[4] pry(#<Foo>)> x
|
61
|
+
=> 10
|
62
|
+
|
63
|
+
[5] pry(#<Foo>)> x = 12
|
64
|
+
=> 12
|
65
|
+
|
66
|
+
[6] pry(#<Foo>)> x
|
67
|
+
=> 12
|
68
|
+
|
69
|
+
[7] pry(#<Foo>)> exit
|
70
|
+
[pry-remote-em] session terminated
|
71
|
+
|
72
|
+
$ pry-remote-em pryem://127.0.0.1:6462/
|
73
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6462/
|
74
|
+
[pry-remote-em] remote is PryRemoteEm 0.1.0
|
75
|
+
[1] pry(#<Foo>)> x
|
76
|
+
=> 12
|
77
|
+
|
78
|
+
[2] pry(#<Foo>)> exit
|
79
|
+
[pry-remote-em] session terminated
|
80
|
+
|
81
|
+
# Features
|
82
|
+
|
83
|
+
## Multiple Servers
|
84
|
+
|
85
|
+
It's easy to run more than one PryRemoteEm service on a single machine,
|
86
|
+
or even in the same process. When you start the service via
|
87
|
+
*#remote_pry_em*, just specify *:auto* as the port to use. The service
|
88
|
+
will automatically take the next free port from 6462.
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
require 'pry-remote-em/server'
|
92
|
+
|
93
|
+
os = ObjectSpace.each_object
|
94
|
+
expose = []
|
95
|
+
while expose.length < 5
|
96
|
+
o = os.next
|
97
|
+
expose.push(o) unless o.frozen?
|
98
|
+
end
|
99
|
+
|
100
|
+
EM.run do
|
101
|
+
expose.each {|o| o.remote_pry_em('localhost', :auto) }
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
$ ruby test/auto-demo.rb
|
106
|
+
[pry-remote-em] listening for connections on pryem://localhost:6462/
|
107
|
+
[pry-remote-em] listening for connections on pryem://localhost:6463/
|
108
|
+
[pry-remote-em] listening for connections on pryem://localhost:6464/
|
109
|
+
[pry-remote-em] listening for connections on pryem://localhost:6465/
|
110
|
+
[pry-remote-em] listening for connections on pryem://localhost:6466/
|
111
|
+
|
112
|
+
```shell
|
113
|
+
|
114
|
+
$ pry-remote-em pryem://127.0.0.1:6462/
|
115
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6462/
|
116
|
+
[pry-remote-em] remote is PryRemoteEm 0.4.0 pryem
|
117
|
+
[1] pry("pretty_print")>
|
118
|
+
|
119
|
+
$ pry-remote-em pryem://127.0.0.1:6463/
|
120
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6463/
|
121
|
+
[pry-remote-em] remote is PryRemoteEm 0.4.0 pryem
|
122
|
+
[1] pry("pack")>
|
123
|
+
|
124
|
+
$ pry-remote-em pryem://127.0.0.1:6464/
|
125
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6464/
|
126
|
+
[pry-remote-em] remote is PryRemoteEm 0.4.0 pryem
|
127
|
+
[1] pry("to_json")>
|
128
|
+
|
129
|
+
$ pry-remote-em pryem://127.0.0.1:6465/
|
130
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6465/
|
131
|
+
[pry-remote-em] remote is PryRemoteEm 0.4.0 pryem
|
132
|
+
[1] pry("to_json")>
|
133
|
+
|
134
|
+
$ pry-remote-em pryem://127.0.0.1:6466/
|
135
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6466/
|
136
|
+
[pry-remote-em] remote is PryRemoteEm 0.4.0 pryem
|
137
|
+
[1] pry(#<RubyVM::InstructionSequence>)>
|
138
|
+
```
|
139
|
+
|
140
|
+
## Server Broker
|
141
|
+
|
142
|
+
When more than one server is running on a given host and each server is
|
143
|
+
started with :auto it can be time consuming to manually figure out which
|
144
|
+
port each server is running on. The Broker which listens on port 6462
|
145
|
+
keeps track of which server is running on which port.
|
146
|
+
|
147
|
+
By default the pry-remote-em cli utility will connect to the broker and
|
148
|
+
retrieve a list of known servers. You can then select one to connect to
|
149
|
+
by its id, name or url. You can also choose to proxy your connection
|
150
|
+
through the broker to the selected server.
|
151
|
+
|
152
|
+
```shell
|
153
|
+
|
154
|
+
$ bin/pry-remote-em
|
155
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6462/
|
156
|
+
[pry-remote-em] remote is PryRemoteEm 0.7.0 pryem
|
157
|
+
-----------------------------------------------------------------------------
|
158
|
+
| id | name | url |
|
159
|
+
-----------------------------------------------------------------------------
|
160
|
+
| 1 | #<#<Class:0x007f924b9bbee8>> | pryem://127.0.0.1:6462/ |
|
161
|
+
| 2 | #<Foo> | pryem://127.0.0.1:1337/ |
|
162
|
+
| 3 | #<#<Class:0x007f924b9bbee8>> | pryems://127.0.0.1:6463/ |
|
163
|
+
| 4 | #<#<Class:0x007f924b9bbee8>> | pryems://127.0.0.1:6464/ |
|
164
|
+
| 5 | #<#<Class:0x007f924b9bbee8>> | pryems://127.0.0.1:6465/ |
|
165
|
+
| 6 | #<#<Class:0x007f924b9bbee8>> | pryems://127.0.0.1:6466/ |
|
166
|
+
| 7 | #<#<Class:0x007f924b9bbee8>> | pryems://127.0.0.1:6467/ |
|
167
|
+
| 8 | #<#<Class:0x007f924b9bbee8>> | pryem://127.0.0.1:6468/ |
|
168
|
+
| 9 | #<#<Class:0x007f924b9bbee8>> | pryem://127.0.0.1:6469/ |
|
169
|
+
-----------------------------------------------------------------------------
|
170
|
+
(q) to quit; (r) to refresh (p) to proxy
|
171
|
+
connect to: 3
|
172
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6463/
|
173
|
+
[pry-remote-em] remote is PryRemoteEm 0.7.0 pryems
|
174
|
+
[pry-remote-em] negotiating TLS
|
175
|
+
[pry-remote-em] TLS connection established
|
176
|
+
[1] pry(#<#<Class:0x007f924b9bbee8>>)>
|
177
|
+
```
|
178
|
+
|
179
|
+
By default the Broker will listen on 127.0.0.1:6462. To change the ip
|
180
|
+
address that the Broker binds to specify it in a PRYEMBROKER environment
|
181
|
+
variable, or in :broker_host option passed to #remote_pry_em.
|
182
|
+
|
183
|
+
```shell
|
184
|
+
|
185
|
+
$ PRYEMBROKER=0.0.0.0 be ./test/service.rb
|
186
|
+
I, [2012-07-13T21:10:00.936993 #88528] INFO -- : [pry-remote-em] listening for connections on pryem://0.0.0.0:6462/
|
187
|
+
I, [2012-07-13T21:10:00.937132 #88528] INFO -- : [pry-remote-em broker] listening on pryem://0.0.0.0:6462
|
188
|
+
I, [2012-07-13T21:10:00.937264 #88528] INFO -- : [pry-remote-em] listening for connections on pryem://0.0.0.0:1337/
|
189
|
+
I, [2012-07-13T21:10:00.937533 #88528] INFO -- : [pry-remote-em] listening for connections on pryems://0.0.0.0:6463/
|
190
|
+
I, [2012-07-13T21:10:00.937804 #88528] INFO -- : [pry-remote-em] listening for connections on pryems://0.0.0.0:6464/
|
191
|
+
I, [2012-07-13T21:10:00.938126 #88528] INFO -- : [pry-remote-em] listening for connections on pryems://0.0.0.0:6465/
|
192
|
+
I, [2012-07-13T21:10:00.938471 #88528] INFO -- : [pry-remote-em] listening for connections on pryems://0.0.0.0:6466/
|
193
|
+
I, [2012-07-13T21:10:00.938835 #88528] INFO -- : [pry-remote-em] listening for connections on pryems://0.0.0.0:6467/
|
194
|
+
I, [2012-07-13T21:10:00.939230 #88528] INFO -- : [pry-remote-em] listening for connections on pryem://0.0.0.0:6468/
|
195
|
+
I, [2012-07-13T21:10:00.939640 #88528] INFO -- : [pry-remote-em] listening for connections on pryem://0.0.0.0:6469/
|
196
|
+
I, [2012-07-13T21:10:01.031576 #88528] INFO -- : [pry-remote-em broker] received client connection from 127.0.0.1:62288
|
197
|
+
I, [2012-07-13T21:10:01.031931 #88528] INFO -- : [pry-remote-em] client connected to pryem://127.0.0.1:6462/
|
198
|
+
I, [2012-07-13T21:10:01.032120 #88528] INFO -- : [pry-remote-em] remote is PryRemoteEm 0.7.0 pryem
|
199
|
+
I, [2012-07-13T21:10:01.032890 #88528] INFO -- : [pry-remote-em broker] registered pryem://127.0.0.1:6462/ - "#<#<Class:0x007f924b9bbee8>>"
|
200
|
+
I, [2012-07-13T21:10:01.125123 #88528] INFO -- : [pry-remote-em broker] registered pryem://127.0.0.1:6469/ - "#<#<Class:0x007f924b9bbee8>>"
|
201
|
+
I, [2012-07-13T21:10:01.125487 #88528] INFO -- : [pry-remote-em broker] registered pryems://127.0.0.1:6467/ - "#<#<Class:0x007f924b9bbee8>>"
|
202
|
+
I, [2012-07-13T21:10:01.490729 #88528] INFO -- : [pry-remote-em broker] registered pryems://127.0.0.1:6464/ - "#<#<Class:0x007f924b9bbee8>>"
|
203
|
+
I, [2012-07-13T21:10:01.583015 #88528] INFO -- : [pry-remote-em broker] registered pryem://127.0.0.1:1337/ - "#<Foo>"
|
204
|
+
I, [2012-07-13T21:10:01.674842 #88528] INFO -- : [pry-remote-em broker] registered pryems://127.0.0.1:6466/ - "#<#<Class:0x007f924b9bbee8>>"
|
205
|
+
I, [2012-07-13T21:10:01.766813 #88528] INFO -- : [pry-remote-em broker] registered pryem://127.0.0.1:6468/ - "#<#<Class:0x007f924b9bbee8>>"
|
206
|
+
I, [2012-07-13T21:10:01.858423 #88528] INFO -- : [pry-remote-em broker] registered pryems://127.0.0.1:6465/ - "#<#<Class:0x007f924b9bbee8>>"
|
207
|
+
```
|
208
|
+
|
209
|
+
It is possible to have a pry-remote-em server register with a Broker
|
210
|
+
running on a different host. Just specify the Brokers address in the
|
211
|
+
PRYEMBROKER environment variable or the :broker_host option passed to #remote_pry_em.
|
212
|
+
|
213
|
+
To connect to a broker running on a seperate host with the cli client
|
214
|
+
just specify it on the command line ``bin/pry-remote-em preym://10.0.0.2:6462/``.
|
215
|
+
You can then proxy your client connections to remote servers through
|
216
|
+
that Broker.
|
217
|
+
|
218
|
+
The Broker will not run in TLS mode, but it can proxy connections to a
|
219
|
+
TLS enabled server.
|
220
|
+
|
221
|
+
|
222
|
+
## TLS Encryption
|
223
|
+
|
224
|
+
When creating a server pass the tls: true option to enable TLS.
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
obj.remote_pry_em('localhost', :auto, tls: true)
|
228
|
+
```
|
229
|
+
|
230
|
+
If you pass a Hash it will be used to configure the internal TLS handler.
|
231
|
+
|
232
|
+
```ruby
|
233
|
+
obj.remote_pry_em('localhost', :auto, tls: { private_key_file: '/tmp/server.key' })
|
234
|
+
```
|
235
|
+
See [EventMachine::Connection#start_tls](http://eventmachine.rubyforge.org/EventMachine/Connection.html#M000296) for the available options.
|
236
|
+
|
237
|
+
|
238
|
+
When the command line client connects to a TLS enabled server it will
|
239
|
+
automatically use TLS mode even if the user didn't request it.
|
240
|
+
|
241
|
+
```bash
|
242
|
+
$ pry-remote-em pryem://localhost:6462/
|
243
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6462/
|
244
|
+
[pry-remote-em] remote is PryRemoteEm 0.4.0 pryems
|
245
|
+
[pry-remote-em] negotiating TLS
|
246
|
+
[pry-remote-em] TLS connection established
|
247
|
+
[1] pry(#<Hash>)>
|
248
|
+
```
|
249
|
+
|
250
|
+
To always require a TLS connection give pry-remote-em a pryem*s* URL. If
|
251
|
+
the server doesn't support TLS the connection will be terminated.
|
252
|
+
|
253
|
+
```bash
|
254
|
+
$ pry-remote-em pryems://localhost:6468/
|
255
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6468/
|
256
|
+
[pry-remote-em] remote is PryRemoteEm 0.4.0 pryem
|
257
|
+
[pry-remote-em] connection failed
|
258
|
+
[pry-remote-em] server doesn't support required scheme "pryems"
|
259
|
+
[pry-remote-em] session terminated
|
260
|
+
```
|
261
|
+
|
262
|
+
|
263
|
+
## User Authentication
|
264
|
+
|
265
|
+
### Server
|
266
|
+
|
267
|
+
If the service is started with the :auth option it will require all
|
268
|
+
clients to authenticate on connect. The :auth option can be a Hash, proc
|
269
|
+
or any object that responds to #call.
|
270
|
+
|
271
|
+
#### Auth with a Hash
|
272
|
+
```ruby
|
273
|
+
auth_hash = { 'caleb' => 'crane', 'john' => 'lowski' }
|
274
|
+
obj = { encoding: __ENCODING__, weather: :cloudy }
|
275
|
+
EM.run do
|
276
|
+
obj.remote_pry_em('localhost', :auto, tls: true, auth: auth_hash)
|
277
|
+
end
|
278
|
+
```
|
279
|
+
|
280
|
+
#### Auth with a lambda
|
281
|
+
```ruby
|
282
|
+
require 'net/ldap'
|
283
|
+
ldap_anon = lambda do |user, pass|
|
284
|
+
ldap = Net::LDAP.new host: '10.0.0.1', port: 389, auth: { method: :simple, username: user, password: pass }
|
285
|
+
ldap.bind
|
286
|
+
end
|
287
|
+
obj = { encoding: __ENCODING__, weather: :cloudy }
|
288
|
+
EM.run do
|
289
|
+
obj.remote_pry_em('localhost', :auto, tls: true, auth: ldap_anon)
|
290
|
+
end
|
291
|
+
```
|
292
|
+
|
293
|
+
#### Auth with an object
|
294
|
+
```ruby
|
295
|
+
class Authenticator
|
296
|
+
def initialize(db)
|
297
|
+
@db = db
|
298
|
+
end
|
299
|
+
def call(user, pass)
|
300
|
+
@db[user] && @db[user] == pass
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
obj = { encoding: __ENCODING__, weather: :cloudy }
|
305
|
+
EM.run do
|
306
|
+
obj.remote_pry_em('localhost', :auto, tls: true, auth: Authenticator.new(auth_hash))
|
307
|
+
end
|
308
|
+
```
|
309
|
+
|
310
|
+
|
311
|
+
### Client
|
312
|
+
|
313
|
+
The included command line client ``pry-remote-em`` can take a username
|
314
|
+
and/or password as part of the url argument. If either a username or
|
315
|
+
password is not supplied, but required by the server it will prompt for
|
316
|
+
them.
|
317
|
+
|
318
|
+
```shell
|
319
|
+
$ pry-remote-em pryems://localhost:6464/
|
320
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6464/
|
321
|
+
[pry-remote-em] remote is PryRemoteEm 0.4.0 pryems
|
322
|
+
[pry-remote-em] negotiating TLS
|
323
|
+
[pry-remote-em] TLS connection established
|
324
|
+
user: caleb
|
325
|
+
caleb's password: *****
|
326
|
+
[1] pry(#<Hash>)>
|
327
|
+
```
|
328
|
+
|
329
|
+
|
330
|
+
```shell
|
331
|
+
$ pry-remote-em pryems://caleb@localhost:6464
|
332
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6464/
|
333
|
+
[pry-remote-em] remote is PryRemoteEm 0.4.0 pryems
|
334
|
+
[pry-remote-em] negotiating TLS
|
335
|
+
[pry-remote-em] TLS connection established
|
336
|
+
caleb's password: *****
|
337
|
+
[1] pry(#<Hash>)> exit
|
338
|
+
```
|
339
|
+
|
340
|
+
```shell
|
341
|
+
$ pry-remote-em pryems://caleb:crane@localhost:6464
|
342
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6464/
|
343
|
+
[pry-remote-em] remote is PryRemoteEm 0.4.0 pryems
|
344
|
+
[pry-remote-em] negotiating TLS
|
345
|
+
[pry-remote-em] TLS connection established
|
346
|
+
[1] pry(#<Hash>)> exit
|
347
|
+
```
|
348
|
+
|
349
|
+
|
350
|
+
## Tab Completion
|
351
|
+
|
352
|
+
Tab completion candidates will be retrieved from the server and
|
353
|
+
presented on the client side.
|
354
|
+
|
355
|
+
```ruby
|
356
|
+
$ bin/pry-remote-em pryems:///
|
357
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6462/
|
358
|
+
[pry-remote-em] remote is PryRemoteEm 0.2.0 pryems
|
359
|
+
[1] pry(#<Hash>)> key (^TAB ^TAB)
|
360
|
+
key key? keys
|
361
|
+
[1] pry(#<Hash>)> keys
|
362
|
+
=> [:encoding]
|
363
|
+
```
|
364
|
+
|
365
|
+
## Paging
|
366
|
+
|
367
|
+
The standard Pry pager is supported through the included client.
|
368
|
+
|
369
|
+
```ruby
|
370
|
+
[1] pry(#<Hash>)> ENV
|
371
|
+
=> {"COMMAND_MODE"=>"unix2003",
|
372
|
+
"DISPLAY"=>"/tmp/launch-0EGhJW/org.x:0",
|
373
|
+
"EDITOR"=>"mvim -f --nomru -c \"au VimLeave * !open -a Terminal\"",
|
374
|
+
"GEM_HOME"=>"/Users/caleb/.rvm/gems/ruby-1.9.2-p290",
|
375
|
+
"GEM_PATH"=>
|
376
|
+
"/Users/caleb/.rvm/gems/ruby-1.9.2-p290:/Users/caleb/.rvm/gems/ruby-1.9.2-p290@global",
|
377
|
+
"GREP_COLOR"=>"1;32",
|
378
|
+
"GREP_OPTIONS"=>"--color=auto",
|
379
|
+
"HOME"=>"/Users/caleb",
|
380
|
+
"IRBRC"=>"/Users/caleb/.rvm/rubies/ruby-1.9.2-p290/.irbrc",
|
381
|
+
"LC_CTYPE"=>"",
|
382
|
+
"LOGNAME"=>"caleb",
|
383
|
+
"LSCOLORS"=>"Gxfxcxdxbxegedabagacad",
|
384
|
+
:
|
385
|
+
```
|
386
|
+
|
387
|
+
## Sandbox
|
388
|
+
|
389
|
+
The `PryRemoteEm::Sandbox` class introduced to help in case when you
|
390
|
+
do not mush interested in console's executing context but just want to
|
391
|
+
access a remote server's "control panel" with usefull methods and
|
392
|
+
without worrying about breaking some object's internal state.
|
393
|
+
|
394
|
+
To use sandbox just run `PryRemoteEm::Server.run` instead of
|
395
|
+
`binding.remote_pry_em`. You can include any modules with your
|
396
|
+
application's business logic in this class to get real "control panel"
|
397
|
+
for your program.
|
398
|
+
|
399
|
+
The simple example:
|
400
|
+
|
401
|
+
```ruby
|
402
|
+
# Microservice A, a.rb
|
403
|
+
|
404
|
+
require 'bundler'
|
405
|
+
Bundler.require
|
406
|
+
|
407
|
+
DB = Sequel.sqlite
|
408
|
+
|
409
|
+
module ControlPanel
|
410
|
+
def u(id)
|
411
|
+
DB[:users].find(id)
|
412
|
+
end
|
413
|
+
|
414
|
+
def ban(id)
|
415
|
+
DB[:users].where(id: id).update u(id).merge('status' => 'banned')
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
PryRemoteEm::Sandbox.include ControlPanel
|
420
|
+
|
421
|
+
EventMachine.run do
|
422
|
+
trap(:INT) { EventMachine.stop }
|
423
|
+
|
424
|
+
PryRemoteEm::Server.run name: 'Microservice A', port: :auto, remote_broker: true, details: { environment: 'staging' }
|
425
|
+
end
|
426
|
+
```
|
427
|
+
|
428
|
+
```ruby
|
429
|
+
# Microservice B, b.rb
|
430
|
+
|
431
|
+
require 'bundler'
|
432
|
+
Bundler.require
|
433
|
+
|
434
|
+
module Transport
|
435
|
+
# ...
|
436
|
+
end
|
437
|
+
|
438
|
+
module ControlPanel
|
439
|
+
def ping(microservice)
|
440
|
+
Transport.send_ping(microservice)
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
PryRemoteEm::Sandbox.include ControlPanel
|
445
|
+
|
446
|
+
EventMachine.run do
|
447
|
+
trap(:INT) { EventMachine.stop }
|
448
|
+
|
449
|
+
PryRemoteEm::Server.run name: 'Microservice B', port: :auto, remote_broker: true, details: { environment: 'staging' }
|
450
|
+
end
|
451
|
+
```
|
452
|
+
|
453
|
+
Then, in shell:
|
454
|
+
|
455
|
+
```shell
|
456
|
+
$ pry-remote-em-broker > /dev/null &
|
457
|
+
$ ruby a.rb > /dev/null &
|
458
|
+
$ ruby b.rb > /dev/null &
|
459
|
+
$
|
460
|
+
$ pry-remote-em -P --sn -d environment
|
461
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6462/
|
462
|
+
[pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
|
463
|
+
------------------------------------------
|
464
|
+
| | name | environment |
|
465
|
+
------------------------------------------
|
466
|
+
| 1 | Microservice A | staging |
|
467
|
+
| 2 | Microservice B | staging |
|
468
|
+
------------------------------------------
|
469
|
+
(q) to quit; (r) to refresh; (c) to connect without proxy
|
470
|
+
proxy to: 1
|
471
|
+
[pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
|
472
|
+
|
473
|
+
Server details:
|
474
|
+
environment: staging
|
475
|
+
|
476
|
+
[1] Microservice A (sandbox)> u 13
|
477
|
+
=> {"id"=>13, "violations"=>4, "status"=>"active"}
|
478
|
+
[2] Microservice A (sandbox)> @my_bad_user = _
|
479
|
+
=> {"id"=>13, "violations"=>4, "status"=>"active"}
|
480
|
+
[3] Microservice A (sandbox)> ban 13 # You can use control panel to work with some business cases
|
481
|
+
=> 1
|
482
|
+
[4] Microservice A (sandbox)> exit
|
483
|
+
[pry-remote-em] session terminated
|
484
|
+
$
|
485
|
+
$ pry-remote-em pryem://127.0.0.1:6463
|
486
|
+
[pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
|
487
|
+
|
488
|
+
Server details:
|
489
|
+
environment: staging
|
490
|
+
|
491
|
+
[1] Microservice A (sandbox)> @my_bad_user
|
492
|
+
=> {"id"=>13, "violations"=>4, "status"=>"banned"}
|
493
|
+
[2] Microservice A (sandbox)> exit
|
494
|
+
[pry-remote-em] session terminated
|
495
|
+
$
|
496
|
+
$ pry-remote-em pryem://127.0.0.1:6464
|
497
|
+
[pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
|
498
|
+
|
499
|
+
Server details:
|
500
|
+
environment: staging
|
501
|
+
|
502
|
+
[1] Microservice A (sandbox)> ping :A # Or you can use it to check infrastructure and perform custom communications between servers
|
503
|
+
=> "pong"
|
504
|
+
[2] Microservice A (sandbox)> exit
|
505
|
+
[pry-remote-em] session terminated
|
506
|
+
```
|
507
|
+
|
508
|
+
In sandbox you have those possibilities "out of the box":
|
509
|
+
|
510
|
+
* `puts`, `putc`, `print`, `p` and `pp` methods works almost as you
|
511
|
+
expected. In other contexts they will use server's STDOUT, but in
|
512
|
+
sandbox they will send all the data to client. Remember, you'll lost
|
513
|
+
those methods out of the sandbox context:
|
514
|
+
|
515
|
+
```shell
|
516
|
+
$ pry-remote-em pryem://127.0.0.1:6463
|
517
|
+
[pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
|
518
|
+
[1] Demo Server (sandbox)> puts 'Hello World' # It works!
|
519
|
+
Hello World
|
520
|
+
=> nil
|
521
|
+
[2] Demo Server (sandbox)> Object.new.instance_eval { puts "Hello World" } # Do not work
|
522
|
+
=> nil
|
523
|
+
[3] Demo Server (sandbox)> cd Object.new
|
524
|
+
[4] Demo Server (#<Object>):1> puts "Hello World" # Do not work
|
525
|
+
=> nil
|
526
|
+
```
|
527
|
+
|
528
|
+
* `any_errors?`, `last_error` and `last_errors` methods in sandbox
|
529
|
+
context with `PryRemoteEm::Sandbox.add_error` method from your code
|
530
|
+
to help you store all the bugs and debug it in the bug's execution
|
531
|
+
context. It also integrated with `wtf?` command. For example:
|
532
|
+
|
533
|
+
```ruby
|
534
|
+
require 'bundler'
|
535
|
+
Bundler.require
|
536
|
+
|
537
|
+
def safe_handler(source_binding)
|
538
|
+
yield
|
539
|
+
rescue => exception
|
540
|
+
PryRemoteEm::Sandbox.add_error(exception, source_binding)
|
541
|
+
raise
|
542
|
+
end
|
543
|
+
|
544
|
+
def danger_mathod(a, b)
|
545
|
+
safe_handler(binding) do
|
546
|
+
a / b
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
550
|
+
EventMachine.run do
|
551
|
+
trap(:INT) { EventMachine.stop }
|
552
|
+
|
553
|
+
EventMachine.error_handler do |exception|
|
554
|
+
PryRemoteEm::Sandbox.add_error(exception)
|
555
|
+
end
|
556
|
+
|
557
|
+
EventMachine.add_timer(5) { danger_mathod 1, 0 }
|
558
|
+
|
559
|
+
PryRemoteEm::Server.run name: 'Demo Server', details: { hostname: 'local' }
|
560
|
+
end
|
561
|
+
```
|
562
|
+
|
563
|
+
Then, in shell:
|
564
|
+
|
565
|
+
```shell
|
566
|
+
$ pry-remote-em -P --sn -d hostname
|
567
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6462/
|
568
|
+
[pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
|
569
|
+
---------------------------------------------
|
570
|
+
| | name | hostname | errors |
|
571
|
+
---------------------------------------------
|
572
|
+
| 1 | Demo Server | local | 1 |
|
573
|
+
---------------------------------------------
|
574
|
+
(q) to quit; (r) to refresh; (c) to connect without proxy
|
575
|
+
proxy to: 1
|
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
|
+
|
584
|
+
[1] Demo Server (sandbox)> any_errors?
|
585
|
+
=> true
|
586
|
+
[2] Demo Server (sandbox)> last_error
|
587
|
+
=> #<ZeroDivisionError: divided by 0>
|
588
|
+
[3] Demo Server (sandbox)> last_error.source_timestamp
|
589
|
+
=> 2018-08-09 14:53:19 UTC
|
590
|
+
[4] Demo Server (sandbox)> wtf?
|
591
|
+
Exception: ZeroDivisionError: divided by 0
|
592
|
+
--
|
593
|
+
0: demo_server.rb:13:in `/'
|
594
|
+
1: demo_server.rb:13:in `block in danger_mathod'
|
595
|
+
2: demo_server.rb:5:in `safe_handler'
|
596
|
+
3: demo_server.rb:12:in `danger_mathod'
|
597
|
+
4: demo_server.rb:24:in `block (2 levels) in <main>'
|
598
|
+
5: /usr/local/lib/ruby/gems/2.4.0/gems/eventmachine-1.2.7/lib/eventmachine.rb:195:in `run_machine'
|
599
|
+
6: /usr/local/lib/ruby/gems/2.4.0/gems/eventmachine-1.2.7/lib/eventmachine.rb:195:in `run'
|
600
|
+
7: demo_server.rb:17:in `<main>'
|
601
|
+
[5] Demo Server (sandbox)> cd last_error.source_binding
|
602
|
+
[6] Demo Server (main):1> whereami
|
603
|
+
|
604
|
+
From: /Users/user/Projects/demo/demo_server.rb @ line 12 Object#danger_mathod:
|
605
|
+
|
606
|
+
11: def danger_mathod(a, b)
|
607
|
+
=> 12: safe_handler(binding) do
|
608
|
+
13: a / b
|
609
|
+
14: end
|
610
|
+
15: end
|
611
|
+
|
612
|
+
[7] Demo Server (main):1> ls
|
613
|
+
self.methods: inspect to_s
|
614
|
+
locals: _ __ _dir_ _ex_ _file_ _in_ _out_ _pry_ a b
|
615
|
+
[8] Demo Server (main):1> a
|
616
|
+
=> 1
|
617
|
+
[9] Demo Server (main):1> b
|
618
|
+
=> 0
|
619
|
+
```
|
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
|
+
|
746
|
+
* `server` method to access PryRemoteEm::Server description object.
|
747
|
+
For example, it can be useful for changing `details`:
|
748
|
+
|
749
|
+
```ruby
|
750
|
+
require 'bundler'
|
751
|
+
Bundler.require
|
752
|
+
|
753
|
+
module HealthChecker
|
754
|
+
# ...
|
755
|
+
end
|
756
|
+
|
757
|
+
EventMachine.run do
|
758
|
+
trap(:INT) { EventMachine.stop }
|
759
|
+
|
760
|
+
PryRemoteEm::Server.run name: 'Demo Server', heartbeat_interval: 1, details: { hand_check: false }
|
761
|
+
end
|
762
|
+
```
|
763
|
+
|
764
|
+
Then, in shell:
|
765
|
+
|
766
|
+
```shell
|
767
|
+
$ pry-remote-em -P --sn -d hand_check
|
768
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6462/
|
769
|
+
[pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
|
770
|
+
--------------------------------------
|
771
|
+
| | name | hand_check |
|
772
|
+
--------------------------------------
|
773
|
+
| 1 | Demo Server | true |
|
774
|
+
| 2 | Demo Server | true |
|
775
|
+
| 3 | Demo Server | false |
|
776
|
+
| 4 | Demo Server | false |
|
777
|
+
| 5 | Demo Server | false |
|
778
|
+
--------------------------------------
|
779
|
+
(q) to quit; (r) to refresh; (c) to connect without proxy
|
780
|
+
proxy to: 3
|
781
|
+
|
782
|
+
Server details:
|
783
|
+
hand_check: false
|
784
|
+
|
785
|
+
[1] Demo Server (sandbox)> HealthChecker.all_ok?
|
786
|
+
=> true
|
787
|
+
[2] Demo Server (sandbox)> server[:details][:hand_check] = true
|
788
|
+
=> true
|
789
|
+
[3] Demo Server (sandbox)> exit
|
790
|
+
[pry-remote-em] session terminated
|
791
|
+
$
|
792
|
+
$ sleep 1
|
793
|
+
$ pry-remote-em -P --sn -d hand_check
|
794
|
+
[pry-remote-em] client connected to pryem://127.0.0.1:6462/
|
795
|
+
[pry-remote-em] remote is PryRemoteEm 1.0.0 pryem
|
796
|
+
--------------------------------------
|
797
|
+
| | name | hand_check |
|
798
|
+
--------------------------------------
|
799
|
+
| 1 | Demo Server | true |
|
800
|
+
| 2 | Demo Server | true |
|
801
|
+
| 3 | Demo Server | true |
|
802
|
+
| 4 | Demo Server | false |
|
803
|
+
| 5 | Demo Server | false |
|
804
|
+
--------------------------------------
|
805
|
+
(q) to quit; (r) to refresh; (c) to connect without proxy
|
806
|
+
proxy to:
|
807
|
+
```
|
808
|
+
|
809
|
+
## Messaging
|
810
|
+
It is possible for each pry-remote-em service to host multiple
|
811
|
+
simultaneous connections. You can send messages to other connections
|
812
|
+
with the '^' and '^^' prefix.
|
813
|
+
|
814
|
+
The '^' prefix will send the message to connections on the same object.
|
815
|
+
the '^^' prefix will send the message to all connections in the current
|
816
|
+
process.
|
817
|
+
|
818
|
+
Message will not be displayed by the clients until the presses enter.
|
819
|
+
|
820
|
+
## Authentication Event Callbacks
|
821
|
+
Available events are:
|
822
|
+
|
823
|
+
- auth_attempt - called each time authentication is attempted
|
824
|
+
- auth_fail - called each time authentication fails
|
825
|
+
- auth_ok - called each time authentication succeeds
|
826
|
+
|
827
|
+
```ruby
|
828
|
+
log = ::Logger.new('/var/log/auth.pry.log')
|
829
|
+
obj.new.remote_pry_em('0.0.0.0', :auto, tls: true, auth: auth_hash) do |pry|
|
830
|
+
pry.auth_attempt do |user, ip|
|
831
|
+
log.info("got an authentication attempt for #{user} from #{ip}")
|
832
|
+
end
|
833
|
+
pry.auth_fail do |user, ip|
|
834
|
+
log.fatal("failed authentication attempt for #{user} from #{ip}")
|
835
|
+
end
|
836
|
+
pry.auth_ok do |user, ip|
|
837
|
+
log.info("successful authentication for #{user} from #{ip}")
|
838
|
+
end
|
839
|
+
end
|
840
|
+
```
|
841
|
+
|
842
|
+
## Shell Commands
|
843
|
+
Unless the pry-remote-em service is started with the ``allow_shell_cmds:
|
844
|
+
false`` option set it will spawn sub processes for any command prefixed
|
845
|
+
with a '.'.
|
846
|
+
|
847
|
+
```
|
848
|
+
[1] pry(#<#<Class:0x007fe0be072618>>)> .uname -a
|
849
|
+
Darwin kiff.local 11.3.0 Darwin Kernel Version 11.3.0: Thu Jan 12 18:47:41 PST 2012; root:xnu-1699.24.23~1/RELEASE_X86_64 x86_64
|
850
|
+
```
|
851
|
+
|
852
|
+
Interactive commands like ``vim`` will probably not behave
|
853
|
+
appropriately.
|
854
|
+
|
855
|
+
|
856
|
+
If the server was started with the ``allow_shell_cmds: false`` option then
|
857
|
+
all shell commands will be met with a rejection notice.
|
858
|
+
|
859
|
+
```
|
860
|
+
[1] pry(#<#<Class:0x007fe0be072618>>)> .ls
|
861
|
+
shell commands are not allowed by this server
|
862
|
+
```
|
863
|
+
|
864
|
+
The server will also log whenever a user attempts to execute a shell command.
|
865
|
+
|
866
|
+
```
|
867
|
+
W, [2012-02-11T19:21:27.663941 #36471] WARN -- : executing shell command 'ls -al' for (127.0.0.1:63878)
|
868
|
+
```
|
869
|
+
|
870
|
+
```
|
871
|
+
E, [2012-02-11T19:23:40.770380 #36471] ERROR -- : refused to execute shell command 'ls' for caleb (127.0.0.1:63891)
|
872
|
+
```
|
873
|
+
|
874
|
+
# Environment variables
|
875
|
+
|
876
|
+
* PRYEMNAME - pry server name to show in broker's list, default - target object's inspect
|
877
|
+
* PRYEMURL - pry server URL to show in broker's list, default - pryem://#{server_host}:#{server_port}/
|
878
|
+
* PRYEMHOST - host to bind pry server, default - 127.0.0.1
|
879
|
+
* PRYEMPORT - port to bind pry server, default - 6463
|
880
|
+
* PRYEMBROKER - host to bind pry broker, default - 127.0.0.1
|
881
|
+
* PRYEMBROKERPORT - port to bind pry broker, default - 6462
|
882
|
+
* PRYEMREMOTEBROKER - start server without starting broker, default - broker starting with server
|
883
|
+
* PRYEMNOPAGER - disable paging on long output, default - pager enabled
|
884
|
+
* PRYEMNEGOTIMEOUT - connection negotiation timeout in seconds, default - 15
|
885
|
+
* PRYEMHBSEND - server to broker heartbeat interval in seconds, default - 15
|
886
|
+
* PRYEMHBCHECK - heartbeat check on broker interval in seconds, default - 20
|
887
|
+
* PRYEMBROKERTIMEOUT - reconnect to broker timeout in seconds, default - 3
|
888
|
+
* PRYEMSANDBOXERRORS - number of errors to store in sandbox, default - 100
|
889
|
+
|
890
|
+
# Missing Features
|
891
|
+
|
892
|
+
- HTTP Transport ([ticket](https://github.com/gruis/pry-remote-em/issues/12))
|
893
|
+
- SSH key based authentication
|
894
|
+
- Looking for connected users and their history
|
895
|
+
|
896
|
+
# Issues
|
897
|
+
|
898
|
+
Please post any bug reports or feature requests on [Github](https://github.com/gruis/pry-remote-em/issues)
|
899
|
+
|
900
|
+
# Copyright
|
901
|
+
|
902
|
+
Copyright (c) 2012 Caleb Crane
|
903
|
+
|
904
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
905
|
+
copy of this software and associated documentation files (the "Software"),
|
906
|
+
to deal in the Software without restriction, including without limitation
|
907
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
908
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
909
|
+
Software is furnished to do so, subject to the following conditions:
|
910
|
+
|
911
|
+
The above copyright notice and this permission notice shall be included
|
912
|
+
in all copies or substantial portions of the Software.
|
913
|
+
|
914
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
915
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
916
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
917
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
918
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
919
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
920
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|