Permalink
Browse files

Merge branch 'master' of https://github.com/papertrail/papertrail-cli

Made configuration parameters cascade in a more natural order:
defaults -> YAML -> CLI

Conflicts:
	bin/papertrail
	lib/papertrail/search_client.rb
  • Loading branch information...
2 parents 828bc09 + ec72a49 commit 26a3680e51b5455f309c2ccb918e9120c36b1285 @kanevski committed Feb 14, 2012
View
@@ -1,24 +1,24 @@
-# papertrail Command-line tail & search client for Papertrail log management service
+# papertrail command-line tail & search client for Papertrail log management service
Small standalone [binary] to retrieve, search, and tail recent app
server log and system syslog messages from [Papertrail].
Supports optional Boolean search queries and polling for new events
(like "tail -f"). Example:
- papertrail -f "(www OR db) (nginx OR pgsql) -accepted"
+ $ papertrail -f "(www OR db) (nginx OR pgsql) -accepted"
Output is line-buffered so it can be fed into a pipe, like for grep.
See below for colorization setup.
-The [SearchClient] class can be used by other apps to perform one-off
+The [Connection] class can be used by other apps to perform one-off
API searches or follow (tail) events matching a given query. Interface
may change.
## Quick Start
- $ [sudo] gem install papertrail-cli
+ $ [sudo] gem install papertrail
$ echo "token: 123456789012345678901234567890ab" > ~/.papertrail.yml
$ papertrail
@@ -27,10 +27,10 @@ Retrieve token from Papertrail [User Profile].
## Installation
-Install the gem (details on [RubyGems]), which includes a binary called
+Install the gem (details on [RubyGems]), which includes a binary called
"papertrail":
- $ [sudo] gem install papertrail-cli
+ $ [sudo] gem install papertrail
## Configuration
@@ -41,7 +41,7 @@ examples/papertrail.yml.example):
token: 123456789012345678901234567890ab
-Retrieve token from Papertrail [User Profile]. For compatibility with
+Retrieve token from Papertrail [User Profile]. For compatibility with
older config files, `username` and `password` keys are also supported.
You may want to alias "trail" to "papertrail", like:
@@ -82,7 +82,7 @@ Save [colortailrc] as `~/.colortailrc` and edit it to enable:
### Shorthand
-If you're using bash, create a function that accepts arguments, then
+If you're using bash, create a function that accepts arguments, then
invoke `pt` with optional search operators:
$ function pt() { papertrail -f -d 5 $_ | colortail -g papertrail }
@@ -116,13 +116,13 @@ Enhancement or fix:
1. Fork the project:
http://github.com/papertrail/papertrail-cli
2. Make your changes with tests.
-3. Commit the changes without changing the Rakefile or other files unrelated
+3. Commit the changes without changing the Rakefile or other files unrelated
to your enhancement.
4. Send a pull request.
[binary]: https://github.com/papertrail/papertrail-cli/blob/master/bin/papertrail
[Papertrail]: http://papertrailapp.com/
-[SearchClient]: https://github.com/papertrail/papertrail-cli/blob/master/lib/papertrail/search_client.rb
+[Connection]: https://github.com/papertrail/papertrail-cli/blob/master/lib/papertrail/connection.rb
[User Profile]: https://papertrailapp.com/user/edit
[RubyGems]: https://rubygems.org/gems/papertrail-cli
[colortail]: http://rubydoc.info/gems/colortail
View
@@ -1,104 +1,8 @@
#!/usr/bin/env ruby
-
-require 'optparse'
-require 'yaml'
-
-require 'papertrail-cli'
-
-class PapertrailSearch
- def run
- options = {
- :configfile => configfile_path,
- :delay => 10,
- :follow => false
- }
-
- OptionParser.new do |opts|
- opts.banner = "papertrail - command-line tail and search for Papertrail log management service"
-
- opts.on("-h", "--help", "Show usage") do |v|
- puts opts
- exit
- end
- opts.on("-f", "--follow", "Continue running and print new events (off)") do |v|
- options[:follow] = true
- end
- opts.on("-d", "--delay SECONDS", "Delay between refresh (3)") do |v|
- options[:delay] = v.to_i
- end
- opts.on("-c", "--configfile PATH", "Path to config (~/.papertrail.yml)") do |v|
- options[:configfile] = File.expand_path(v)
- end
-
- opts.separator usage
- end.parse!
-
- configfile_options = open(options[:configfile]) do |f|
- YAML.load(f)
- end
- configfile_options = symbolize_keys(configfile_options)
- options.merge!(configfile_options)
-
- client = Papertrail::SearchClient.new(options)
-
- search_and_print(client)
-
- if options[:follow]
- loop do
- sleep options[:delay]
- search_and_print(client)
- end
- end
- end
-
- def search_and_print(client)
- events = client.search(ARGV[0])
- return unless events
-
- Papertrail::SearchClient.format_events(events) do |e|
- puts e
- $stdout.flush
- end
- end
-
- def configfile_path
- if File.exists?(file_name = '.papertrail.yml')
- file_path = File.expand_path(file_name)
- else
- file_path = File.expand_path('~/.papertrail.yml')
- end
-
- file_path
- end
-
- def symbolize_keys(hash)
- new_hash = {}
- hash.each_key do |key|
- new_hash[(key.to_sym rescue key) || key] = hash[key]
- end
- new_hash
- end
-
- def usage
- <<EOF
-
-Usage: papertrail [-f] [-d seconds] [-c /path/to/papertrail.yml] [query]
-
-Examples:
- papertrail -f
- papertrail something
- papertrail 1.2.3 Failure
- papertrail -f "(www OR db) (nginx OR pgsql) -accepted"
- papertrail -f -d 10 "ns1 OR 'connection refused'"
-
-More: https://papertrailapp.com/
-
-EOF
- end
-end
+require 'papertrail/cli'
begin
- PapertrailSearch.new.run
+ Papertrail::Cli.new.run
rescue Interrupt
exit(0)
end
@@ -1,5 +1,5 @@
-module PapertrailCli
- VERSION = "0.8.2"
+module Papertrail
+ VERSION = "0.8.4"
end
require 'papertrail/search_client'
View
@@ -0,0 +1,122 @@
+require 'optparse'
+require 'yaml'
+
+require 'papertrail/connection'
+
+module Papertrail
+ class Cli
+ def run
+ options = {
+ :configfile => nil,
+ :delay => 10,
+ :follow => false
+ }
+
+ if configfile = find_configfile
+ configfile_options = load_configfile(configfile)
+ options.merge!(configfile_options)
+ end
+
+ OptionParser.new do |opts|
+ opts.banner = "papertrail - command-line tail and search for Papertrail log management service"
+
+ opts.on("-h", "--help", "Show usage") do |v|
+ puts opts
+ exit
+ end
+ opts.on("-f", "--follow", "Continue running and print new events (off)") do |v|
+ options[:follow] = true
+ end
+ opts.on("-d", "--delay SECONDS", "Delay between refresh (2)") do |v|
+ options[:delay] = v.to_i
+ end
+ opts.on("-c", "--configfile PATH", "Path to config (~/.papertrail.yml)") do |v|
+ options[:configfile] = File.expand_path(v)
+ end
+ opts.on("-s", "--system SYSTEM", "System to search") do |v|
+ options[:system] = v
+ end
+ opts.on("-g", "--group GROUP", "Group to search") do |v|
+ options[:group] = v
+ end
+
+ opts.separator usage
+ end.parse!
+
+ if options[:configfile]
+ configfile_options = load_configfile(options[:configfile])
+ options.merge!(configfile_options)
+ end
+
+ connection = Papertrail::Connection.new(options)
+
+ query_options = {}
+
+ if options[:system]
+ query_options[:system_id] = connection.find_id_for_source(options[:system])
+ end
+
+ if options[:group]
+ query_options[:group_id] = connection.find_id_for_group(options[:group])
+ end
+
+ search_query = connection.query(ARGV[0], query_options)
+
+ if options[:follow]
+ loop do
+ search_query.search.events.each do |event|
+ $stdout.puts event
+ end
+ $stdout.flush
+ sleep options[:delay]
+ end
+ else
+ search_query.search.events.each do |event|
+ $stdout.puts event
+ end
+ end
+ end
+
+ def find_configfile
+ if File.exists?(path = File.expand_path('.papertrail.yml'))
+ return path
+ end
+ if File.exists?(path = File.expand_path('~/.papertrail.yml'))
+ return path
+ end
+
+ false
+ end
+
+ def load_configfile(file_path)
+ configfile_options = open(file_path) { |f| YAML.load(f) }
+ symbolize_keys(configfile_options)
+ end
+
+ def symbolize_keys(hash)
+ new_hash = {}
+ hash.each_key do |key|
+ new_hash[(key.to_sym rescue key) || key] = hash[key]
+ end
+
+ new_hash
+ end
+
+ def usage
+ <<-EOF
+
+ Usage: papertrail [-f] [-d seconds] [-c /path/to/papertrail.yml] [query]
+
+ Examples:
+ papertrail -f
+ papertrail something
+ papertrail 1.2.3 Failure
+ papertrail -f "(www OR db) (nginx OR pgsql) -accepted"
+ papertrail -f -d 10 "ns1 OR 'connection refused'"
+
+ More: https://papertrailapp.com/
+
+ EOF
+ end
+ end
+end
@@ -0,0 +1,66 @@
+require 'faraday'
+require 'openssl'
+require 'faraday_middleware'
+require 'yajl/json_gem'
+
+require 'papertrail/search_query'
+
+module Papertrail
+ class Connection
+ extend Forwardable
+
+ attr_reader :connection
+
+ def_delegators :@connection, :get, :put, :post
+
+ def initialize(options)
+ ssl_options = {
+ :verify => options.fetch(:verify_ssl) { OpenSSL::SSL::VERIFY_PEER }
+ }
+
+ # Make Ubuntu OpenSSL work
+ #
+ # From: https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/396818
+ # "[OpenSSL] does not presume to select a set of CAs by default."
+ if File.file?('/etc/ssl/certs/ca-certificates.crt')
+ ssl_options[:ca_file] = '/etc/ssl/certs/ca-certificates.crt'
+ end
+
+ @connection = Faraday::Connection.new(:url => 'https://papertrailapp.com', :ssl => ssl_options) do |builder|
+ builder.adapter Faraday.default_adapter
+ builder.use Faraday::Response::RaiseError
+ builder.use FaradayMiddleware::ParseJson, :content_type => /\bjson$/
+ end.tap do |conn|
+ if options[:username] && options[:password]
+ conn.basic_auth(options[:username], options[:password])
+ else
+ conn.headers['X-Papertrail-Token'] = options[:token]
+ end
+ end
+ end
+
+ def find_id_for_source(name)
+ response = @connection.get('/api/v1/systems.json')
+
+ response.body.each do |source|
+ return source['id'] if source['name'] =~ /#{Regexp.escape(name)}/i
+ end
+
+ return nil
+ end
+
+ def find_id_for_group(name)
+ response = @connection.get('/api/v1/groups.json')
+
+ response.body.each do |group|
+ return group['id'] if group['name'] =~ /#{Regexp.escape(name)}/i
+ end
+
+ return nil
+ end
+
+ def query(query = nil, options = {})
+ Papertrail::SearchQuery.new(self, query, options)
+ end
+ end
+end
View
@@ -0,0 +1,15 @@
+require 'time'
+
+module Papertrail
+ class Event
+ attr_reader :data
+
+ def initialize(data)
+ @data = data
+ end
+
+ def to_s
+ "#{Time.parse(data['received_at']).strftime('%b %e %X')} #{data['hostname']} #{data['program']}: #{data['message']}"
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit 26a3680

Please sign in to comment.