Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
233 lines (184 sloc) 6.12 KB
require 'forwardable'
require 'openssl'
require 'papertrail/http_client'
require 'papertrail/search_query'
module Papertrail
class Connection
extend Forwardable
attr_reader :connection
def_delegators :@connection, :get, :put, :post, :delete
def initialize(options)
ssl_options = {
:verify => options.fetch(:verify_ssl) { OpenSSL::SSL::VERIFY_PEER }
}
unless (options[:username] && options[:password]) || options[:token]
raise ArgumentError, "Must provide a username and password or a token"
end
# 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 = Papertrail::HttpClient.new(ssl_options).tap do |conn|
if options[:username] && options[:password]
conn.basic_auth(options[:username], options[:password])
else
conn.token_auth(options[:token])
end
end
end
def start
if block_given?
@connection.start { yield self }
else
@connection.start
self
end
end
def finish
@connection.finish
end
def find_id_for_source(name)
response = @connection.get('systems.json', :system_name => name)
find_id_for_item(response.body, name)
end
def find_id_for_group(name)
response = @connection.get('groups.json', :group_name => name)
find_id_for_item(response.body, name)
end
def find_search(name, group_id = nil)
response = @connection.get('searches.json', :search_name => name)
candidates = find_items_by_name(response.body, name)
return nil if candidates.empty?
candidates.each do |item|
if !group_id || group_id == item['group_id']
return item
end
end
return candidates.first
end
def find_items_by_name(items, name_wanted)
results = []
items.each do |item|
results << item if item['name'] == name_wanted
end
items.each do |item|
results << item if item['name'] =~ /#{Regexp.escape(name_wanted)}/i
end
results
end
def find_item_by_name(items, name_wanted)
find_items_by_name(items, name_wanted).first
end
def find_id_for_item(items, name_wanted)
item = find_item_by_name(items, name_wanted)
if item
return item['id']
end
return nil
end
def create_group(name, system_wildcard = nil)
group = { :group => { :name => name } }
if system_wildcard
group[:group][:system_wildcard] = system_wildcard
end
@connection.post("groups.json", group)
end
def show_group(name)
if id = find_id_for_group(name)
@connection.get("groups/#{id}.json").body
end
end
def show_source(name)
if id = find_id_for_source(name)
@connection.get("systems/#{id}.json").body
end
end
def join_group(source_name, group_name)
source_id = find_id_for_source(source_name)
group_id = find_id_for_group(group_name)
if source_id && group_id
@connection.post("systems/#{source_id}/join.json", :group_id => group_id)
end
end
def leave_group(source_name, group_name)
source_id = find_id_for_source(source_name)
group_id = find_id_for_group(group_name)
if source_id && group_id
@connection.post("systems/#{source_id}/leave.json", :group_id => group_id)
end
end
def register_source(name, *args)
options = args.last.is_a?(Hash) ? args.pop.dup : {}
if ip_address = args.shift
options[:ip_address] = ip_address
end
if hostname = args.shift
options[:hostname] = hostname
end
request = {
:system => {
:name => name
}
}
if options[:ip_address]
request[:system][:ip_address] = options[:ip_address]
end
if options[:hostname]
request[:system][:hostname] = options[:hostname]
end
if options[:destination_port]
request[:destination_port] = options[:destination_port]
end
@connection.post("systems.json", request)
end
def unregister_source(name)
if source_id = find_id_for_source(name)
@connection.delete("systems/#{source_id}.json")
end
end
def each_event(query_term = nil, options = {}, &block)
# If there was no query but there were options, shuffle around
# the parameters
if query_term.is_a?(Hash)
options, query_term = query_term, nil
end
# Remove all of the options that shouldn't be in each query
options = { :tail => false }.merge(options)
min_id = options.delete(:min_id)
max_id = options.delete(:max_id)
min_time = options.delete(:min_time)
max_time = options.delete(:max_time)
# Figure out where to start querying
if min_id
search = search_query(query_term, options.merge(:min_id => min_id))
elsif min_time
search = search_query(query_term, options.merge(:min_time => min_time.to_i))
else
raise ArgumentError, "Either :min_id or :min_time must be specified"
end
# Start processing events
loop do
search_results = search.next_results_page
search_results.events.each do |event|
# If we've found an event beyond what we were looking for, we're done
break if max_time && event.received_at > max_time
break if max_id && event.id > max_id
block.call(event)
end
# If we've found the end of what we're looking for, we're done
break if max_time && search_results.max_time_at > max_time
break if max_id && search_results.max_id > max_id
# If we've reached the most current log message, we're done
break if search_results.reached_end?
end
nil
end
private
def search_query(query = nil, options = {})
Papertrail::SearchQuery.new(self, query, options)
end
end
end
You can’t perform that action at this time.