logs-cf-plugin 0.0.23.pre

Sign up to get free protection for your applications and to get access to all the features.
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: []