logs-cf-plugin 0.0.23.pre

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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OTI0ZDYyMGIwNjE4YTMwZjhmYWFlMDNmOTg5NmFmZGMyM2E0MjhkYQ==
5
+ data.tar.gz: !binary |-
6
+ NGI4NDQxYTUxYmM3Njc3MTBkZDVmNGI2YzM2NGY3NDYwZjY2ZTMzNw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NmYwNjE5NWE0MjRhMzBjZDBlYmVkM2FiZjg5OGMwYzZiNDE4ZjUxODQ1YTU0
10
+ NDBlZTNhM2RmNWMxYWRkZTBkZjU0YTllMTI5NTkzODc4YTY2ZjYyMTUzOGFm
11
+ YWQ0MTFjMmQyZjhhOGE4ZGRlMjE2OWQ0NWViMGY4MjYzNGZlMzE=
12
+ data.tar.gz: !binary |-
13
+ MmUyMWRkNDc5ZTFhMGRiMDM5NmI1M2EzMDE4ZWMzZDc3NGYyZjc5MTJkMDkw
14
+ NzdiNDgzNjU5NmYxYzI2OTk0MmQ4N2M3NTEyMDIyZTgyNWExMjUyMmFkZDQx
15
+ ZWM5NGI2MTZjY2E1NmY2Mjg4ZjVhZDJiZWFkOGVmZDZmNGYxYmY=
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # Logs-Cf-Plugin [![Build Status](https://travis-ci.org/cloudfoundry/logs-cf-plugin.png?branch=master)](https://travis-ci.org/cloudfoundry/logs-cf-plugin)
2
+
3
+ Plugin to cf command to add streaming application logs.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'logs-cf-plugin'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install logs-cf-plugin
18
+
19
+ ## Usage
20
+
21
+ After installing you can run cf logs and see your application's logs stream to the console.
22
+
23
+ ## Contributing
24
+
25
+ The Cloud Foundry team uses GitHub and accepts contributions via [pull request](https://help.github.com/articles/using-pull-requests)
26
+
27
+ Follow these steps to make a contribution to any of our open source repositories:
28
+
29
+ 1. Complete our CLA Agreement for [individuals](http://www.cloudfoundry.org/individualcontribution.pdf) or [corporations](http://www.cloudfoundry.org/corpcontribution.pdf)
30
+ 1. Set your name and email
31
+
32
+ git config --global user.name "Firstname Lastname"
33
+ git config --global user.email "your_email@youremail.com"
34
+
35
+ 1. Fork the repo
36
+ 1. Make your changes on a topic branch, commit, and push to github and open a pull request.
37
+
38
+ Once your commits are approved by Travis CI and reviewed by the core team, they will be merged.
39
+
40
+ #### Checkout
41
+
42
+ git clone git@github.com:cloudfoundry/logs-cf-plugin.git
43
+ cd logs-cf-plugin/
44
+ bundle
45
+
46
+ #### Running tests
47
+
48
+ rake
49
+
@@ -0,0 +1,46 @@
1
+ module LogsCfPlugin
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
@@ -0,0 +1,116 @@
1
+ require 'log_message/log_message.pb'
2
+ require 'faye/websocket'
3
+ require 'eventmachine'
4
+ require 'uri'
5
+
6
+ module LogsCfPlugin
7
+ class LoggregatorClient
8
+ include CFoundry::TraceHelpers
9
+
10
+ def initialize(loggregator_host, user_token, output, trace)
11
+ @output = output
12
+ @loggregator_host = loggregator_host
13
+ @user_token = user_token
14
+ @trace = trace
15
+ end
16
+
17
+ def listen(query_params)
18
+ websocket_address = "wss://#{loggregator_host}:4443/tail/?#{hash_to_query(query_params)}"
19
+ output.puts "websocket_address: #{websocket_address}" if trace
20
+
21
+ EM.run {
22
+ ws = Faye::WebSocket::Client.new(websocket_address, nil, :headers => {"Origin" => "http://localhost", "Authorization" => user_token})
23
+
24
+ ws.on :open do |event|
25
+ output.puts("Connected to server.")
26
+ EventMachine.add_periodic_timer(keep_alive_interval) do
27
+ ws.send([42])
28
+ end
29
+ end
30
+
31
+ ws.on :message do |event|
32
+ received_message = LogMessage.decode(event.data.pack("C*"))
33
+ MessageWriter.write(output, received_message)
34
+ end
35
+
36
+ ws.on :error do |event|
37
+ output.puts("Server error")
38
+ output.puts(event.data.inspect) if trace
39
+ end
40
+
41
+ ws.on :close do |event|
42
+ ws.close
43
+ output.puts("Server dropped connection...goodbye.")
44
+ EM.stop
45
+ ws = nil
46
+ end
47
+ }
48
+ end
49
+
50
+ def dump_messages(query_params)
51
+ uri = URI.parse("https://#{loggregator_host}/dump/?#{hash_to_query(query_params)}")
52
+ http = Net::HTTP.new(uri.host, uri.port)
53
+ http.use_ssl = true
54
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
55
+
56
+ request = Net::HTTP::Get.new(uri.request_uri)
57
+ request['Authorization'] = user_token
58
+
59
+ if trace
60
+ request_hash = {
61
+ :url => uri.request_uri,
62
+ :method => "GET",
63
+ :headers => sane_headers(request),
64
+ :body => ""
65
+ }
66
+ output.puts(request_trace(request_hash))
67
+ end
68
+
69
+ response = http.request(request)
70
+
71
+ return [] unless response.code == "200"
72
+
73
+ response_bytes = StringIO.new(response.body)
74
+ messages = []
75
+ while len = response_bytes.read(4)
76
+ len = len.unpack("N")[0] # 32-bit length, BigEndian stylie
77
+ record = response_bytes.read(len) # This returns a string even if len is 0.
78
+ msg = LogMessage.decode(record)
79
+ messages << msg
80
+ end
81
+
82
+ if trace
83
+ response_hash = {
84
+ :headers => sane_headers(response),
85
+ :status => response.code,
86
+ :body => messages
87
+ }
88
+ output.puts(response_trace(response_hash))
89
+ end
90
+
91
+ messages
92
+ end
93
+
94
+ private
95
+
96
+ def sane_headers(obj)
97
+ hds = {}
98
+
99
+ obj.each_header do |k, v|
100
+ hds[k] = v
101
+ end
102
+
103
+ hds
104
+ end
105
+
106
+ def keep_alive_interval
107
+ 25
108
+ end
109
+
110
+ def hash_to_query(hash)
111
+ return URI.encode(hash.map { |k, v| "#{k}=#{v}" }.join("&"))
112
+ end
113
+
114
+ attr_reader :output, :loggregator_host, :user_token, :trace
115
+ end
116
+ end
@@ -0,0 +1,5 @@
1
+ module MessageWriter
2
+ def self.write(output, message)
3
+ output.puts([message.app_id, message.source_id, message.message_type_name, message.message].join(" "))
4
+ end
5
+ end
@@ -0,0 +1,54 @@
1
+ require 'cf'
2
+
3
+ module LogsCfPlugin
4
+ require 'logs-cf-plugin/loggregator_client'
5
+ require 'logs-cf-plugin/log_target'
6
+ require 'logs-cf-plugin/message_writer'
7
+
8
+ class Plugin < CF::CLI
9
+ include LoginRequirements
10
+
11
+ desc "Tail or dump logs for CF applications or spaces"
12
+ group :apps
13
+ input :app, :desc => "App to tail logs from", :argument => :optional, :from_given => by_name(:app)
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
17
+
18
+ def logs
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."
31
+ end
32
+
33
+ loggregator_client = LoggregatorClient.new(loggregator_host, client.token.auth_header, STDOUT, input[:trace])
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
43
+ end
44
+
45
+ ::ManifestsPlugin.default_to_app_from_manifest(:logs, false)
46
+
47
+ private
48
+
49
+ def loggregator_host
50
+ target_base = client.target.sub(/^https?:\/\/([^\.]+\.)?(.+)\/?/, '\2')
51
+ "loggregator.#{target_base}"
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,32 @@
1
+ ## Generated from log_message.proto for logMessage
2
+ require "beefcake"
3
+
4
+
5
+ class LogMessage
6
+ include Beefcake::Message
7
+
8
+ module MessageType
9
+ OUT = 1
10
+ ERR = 2
11
+ end
12
+ module SourceType
13
+ CLOUD_CONTROLLER = 1
14
+ ROUTER = 2
15
+ UAA = 3
16
+ DEA = 4
17
+ WARDEN_CONTAINER = 5
18
+ end
19
+
20
+ required :message, :bytes, 1
21
+ required :message_type, LogMessage::MessageType, 2
22
+ required :timestamp, :sint64, 3
23
+ required :app_id, :string, 4
24
+ required :source_type, LogMessage::SourceType, 5
25
+ optional :source_id, :string, 6
26
+ optional :space_id, :string, 7
27
+ required :organization_id, :string, 8
28
+
29
+ def message_type_name
30
+ {MessageType::OUT => 'STDOUT', MessageType::ERR => 'STDERR'}[message_type]
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ package logMessage;
2
+
3
+ message LogMessage {
4
+ enum MessageType {
5
+ OUT = 1;
6
+ ERR = 2;
7
+ }
8
+
9
+ enum SourceType {
10
+ CLOUD_CONTROLLER = 1;
11
+ ROUTER = 2;
12
+ UAA = 3;
13
+ DEA = 4;
14
+ WARDEN_CONTAINER = 5;
15
+ }
16
+
17
+ required bytes message = 1;
18
+ required MessageType message_type = 2;
19
+ required sint64 timestamp = 3;
20
+ required string app_id = 4;
21
+ required SourceType source_type = 5;
22
+ optional string source_id = 6;
23
+ optional string space_id = 7;
24
+ required string organization_id = 8;
25
+ }
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logs-cf-plugin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.23.pre
5
+ platform: ruby
6
+ authors:
7
+ - Pivotal
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cf
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 4.2.5
20
+ - - <
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 4.2.5
30
+ - - <
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: faye-websocket
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ~>
38
+ - !ruby/object:Gem::Version
39
+ version: 0.6.1
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: 0.6.1
47
+ - !ruby/object:Gem::Dependency
48
+ name: beefcake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.3.7
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ version: 0.3.7
61
+ description: CF command line tool to retrieve recent and tail CF Application Logs
62
+ email:
63
+ - vcap-dev@googlegroups.com
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - lib/logs-cf-plugin/log_target.rb
69
+ - lib/logs-cf-plugin/loggregator_client.rb
70
+ - lib/logs-cf-plugin/message_writer.rb
71
+ - lib/logs-cf-plugin/plugin.rb
72
+ - vendor/log_message/log_message.pb.rb
73
+ - vendor/log_message/log_message.proto
74
+ - README.md
75
+ homepage: http://github.com/cloudfoundry/logs-cf-plugin
76
+ licenses:
77
+ - Apache 2.0
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ - vendor
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: 1.9.3
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ! '>'
92
+ - !ruby/object:Gem::Version
93
+ version: 1.3.1
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.0.6
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: CF Logs
100
+ test_files: []