tail-cf-plugin 0.0.20.pre → 0.0.21.pre
Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,46 @@
|
|
1
|
+
module TailCfPlugin
|
2
|
+
class LogTarget
|
3
|
+
def initialize(target_organization, target_space, ids)
|
4
|
+
raise ArgumentError, "Requires 3 ids" unless ids.size == 3
|
5
|
+
@target_organization = target_organization
|
6
|
+
@target_space = target_space
|
7
|
+
|
8
|
+
@org_id = ids[0]
|
9
|
+
@space_id = ids[1]
|
10
|
+
@app_id = ids[2]
|
11
|
+
end
|
12
|
+
|
13
|
+
def ambiguous?
|
14
|
+
@target_organization && @target_space
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid?
|
18
|
+
!!target
|
19
|
+
end
|
20
|
+
|
21
|
+
def query_params
|
22
|
+
case target
|
23
|
+
when :org
|
24
|
+
{org: @org_id}
|
25
|
+
when :space
|
26
|
+
{org: @org_id, space: @space_id}
|
27
|
+
when :app
|
28
|
+
{org: @org_id, space: @space_id, app: @app_id}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def target
|
35
|
+
return nil if ambiguous?
|
36
|
+
case
|
37
|
+
when @target_organization
|
38
|
+
:org
|
39
|
+
when @target_space
|
40
|
+
:space
|
41
|
+
when @app_id
|
42
|
+
:app
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,16 +1,18 @@
|
|
1
1
|
require 'log_message/log_message.pb'
|
2
2
|
require 'faye/websocket'
|
3
3
|
require 'eventmachine'
|
4
|
+
require 'uri'
|
4
5
|
|
5
6
|
module TailCfPlugin
|
6
7
|
class LoggregatorClient
|
7
|
-
def initialize(output)
|
8
|
+
def initialize(loggregator_host, user_token, output)
|
8
9
|
@output = output
|
10
|
+
@loggregator_host = loggregator_host
|
11
|
+
@user_token = user_token
|
9
12
|
end
|
10
13
|
|
11
|
-
def listen(
|
12
|
-
websocket_address = "wss://#{loggregator_host}:4443/tail
|
13
|
-
websocket_address += "/apps/#{app_id}" if app_id
|
14
|
+
def listen(query_params)
|
15
|
+
websocket_address = "wss://#{loggregator_host}:4443/tail/?#{hash_to_query(query_params)}"
|
14
16
|
|
15
17
|
EM.run {
|
16
18
|
ws = Faye::WebSocket::Client.new(websocket_address, nil, :headers => {"Origin" => "http://localhost", "Authorization" => user_token})
|
@@ -24,7 +26,7 @@ module TailCfPlugin
|
|
24
26
|
|
25
27
|
ws.on :message do |event|
|
26
28
|
received_message = LogMessage.decode(event.data.pack("C*"))
|
27
|
-
|
29
|
+
MessageWriter.write(output, received_message)
|
28
30
|
end
|
29
31
|
|
30
32
|
ws.on :error do |event|
|
@@ -40,12 +42,40 @@ module TailCfPlugin
|
|
40
42
|
}
|
41
43
|
end
|
42
44
|
|
45
|
+
def dump_messages(query_params)
|
46
|
+
uri = URI.parse("https://#{loggregator_host}/dump/?#{hash_to_query(query_params)}")
|
47
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
48
|
+
http.use_ssl = true
|
49
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
50
|
+
|
51
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
52
|
+
request['Authorization'] = user_token
|
53
|
+
|
54
|
+
response = http.request(request)
|
55
|
+
|
56
|
+
return [] unless response.code == "200"
|
57
|
+
|
58
|
+
response_bytes = StringIO.new(response.body)
|
59
|
+
messages = []
|
60
|
+
while len = response_bytes.read(4)
|
61
|
+
len = len.unpack("N")[0] # 32-bit length, BigEndian stylie
|
62
|
+
record = response_bytes.read(len) # This returns a string even if len is 0.
|
63
|
+
msg = LogMessage.decode(record)
|
64
|
+
messages << msg
|
65
|
+
end
|
66
|
+
messages
|
67
|
+
end
|
68
|
+
|
43
69
|
private
|
44
70
|
|
45
71
|
def keep_alive_interval
|
46
72
|
25
|
47
73
|
end
|
48
74
|
|
49
|
-
|
75
|
+
def hash_to_query(hash)
|
76
|
+
return URI.encode(hash.map{|k,v| "#{k}=#{v}"}.join("&"))
|
77
|
+
end
|
78
|
+
|
79
|
+
attr_reader :output, :loggregator_host, :user_token
|
50
80
|
end
|
51
81
|
end
|
@@ -2,28 +2,44 @@ require 'cf'
|
|
2
2
|
|
3
3
|
module TailCfPlugin
|
4
4
|
require 'tail-cf-plugin/loggregator_client'
|
5
|
+
require 'tail-cf-plugin/log_target'
|
6
|
+
require 'tail-cf-plugin/message_writer'
|
5
7
|
|
6
8
|
class Plugin < CF::CLI
|
7
9
|
include LoginRequirements
|
8
10
|
|
9
|
-
desc "Tail logs for CF applications or spaces"
|
11
|
+
desc "Tail or dump logs for CF applications or spaces"
|
10
12
|
group :apps
|
11
13
|
input :app, :desc => "App to tail logs from", :argument => :optional, :from_given => by_name(:app)
|
12
14
|
input :space, :type => :boolean, :desc => "Logs of all apps in the current space", :default => false
|
15
|
+
input :org, :type => :boolean, :desc => "Logs of all apps and spaces in the current organization", :default => false
|
16
|
+
input :recent, :type => :boolean, :desc => "Dump recent logs instead of tailing", :default => false
|
13
17
|
|
14
18
|
def logs
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
guids = [client.current_organization.guid, client.current_space.guid, input[:app].try(:guid)]
|
20
|
+
|
21
|
+
log_target = LogTarget.new(input[:org], input[:space], guids)
|
22
|
+
|
23
|
+
if log_target.ambiguous?
|
24
|
+
Mothership::Help.command_help(@@commands[:logs])
|
25
|
+
fail "Please provide either --space or --org, but not both."
|
26
|
+
end
|
27
|
+
|
28
|
+
unless log_target.valid?
|
29
|
+
Mothership::Help.command_help(@@commands[:logs])
|
30
|
+
fail "Please provide an application to log."
|
23
31
|
end
|
24
32
|
|
25
|
-
loggregator_client = LoggregatorClient.new(STDOUT)
|
26
|
-
|
33
|
+
loggregator_client = LoggregatorClient.new(loggregator_host, client.token.auth_header, STDOUT)
|
34
|
+
|
35
|
+
if input[:recent]
|
36
|
+
loggregator_client.dump_messages(log_target.query_params).each do |m|
|
37
|
+
MessageWriter.write(STDOUT, m)
|
38
|
+
end
|
39
|
+
|
40
|
+
else
|
41
|
+
loggregator_client.listen(log_target.query_params)
|
42
|
+
end
|
27
43
|
end
|
28
44
|
|
29
45
|
::ManifestsPlugin.default_to_app_from_manifest(:logs, false)
|
@@ -34,6 +50,5 @@ module TailCfPlugin
|
|
34
50
|
target_base = client.target.sub(/^https?:\/\/([^\.]+\.)?(.+)\/?/, '\2')
|
35
51
|
"loggregator.#{target_base}"
|
36
52
|
end
|
37
|
-
|
38
53
|
end
|
39
54
|
end
|
@@ -23,6 +23,8 @@ class LogMessage
|
|
23
23
|
required :app_id, :string, 4
|
24
24
|
required :source_type, LogMessage::SourceType, 5
|
25
25
|
optional :source_id, :string, 6
|
26
|
+
optional :space_id, :string, 7
|
27
|
+
required :organization_id, :string, 8
|
26
28
|
|
27
29
|
def message_type_name
|
28
30
|
{MessageType::OUT => 'STDOUT', MessageType::ERR => 'STDERR'}[message_type]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tail-cf-plugin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.21.pre
|
5
5
|
prerelease: 7
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cf
|
@@ -72,7 +72,9 @@ executables: []
|
|
72
72
|
extensions: []
|
73
73
|
extra_rdoc_files: []
|
74
74
|
files:
|
75
|
+
- lib/tail-cf-plugin/log_target.rb
|
75
76
|
- lib/tail-cf-plugin/loggregator_client.rb
|
77
|
+
- lib/tail-cf-plugin/message_writer.rb
|
76
78
|
- lib/tail-cf-plugin/plugin.rb
|
77
79
|
- vendor/log_message/log_message.pb.rb
|
78
80
|
- vendor/log_message/log_message.proto
|