- Add twitter backend support. This isn't intended for use.

The point of writing this was to make it easy to show a real use case
  that implements a logstash-web search backend other than
  ElasticSearch.
This commit is contained in:
Jordan Sissel 2011-02-13 01:25:02 -08:00
parent c852a9eb4b
commit 9c6a1495d9
3 changed files with 108 additions and 6 deletions

View file

@ -0,0 +1,90 @@
require "em-http-request"
require "logstash/namespace"
require "logstash/logging"
require "logstash/event"
require "logstash/search/base"
require "logstash/search/query"
require "logstash/search/result"
require "logstash/search/facetresult"
require "logstash/search/facetresult/histogram"
class LogStash::Search::Twitter < LogStash::Search::Base
public
def initialize(settings={})
@host = (settings[:host] || "search.twitter.com")
@port = (settings[:port] || 80).to_i
@logger = LogStash::Logger.new(STDOUT)
end
public
def search(query)
raise "No block given for search call." if !block_given?
if query.is_a?(String)
query = LogStash::Search::Query.parse(query)
end
# TODO(sissel): only search a specific index?
http = EventMachine::HttpRequest.new("http://#{@host}:#{@port}/search.json?q=#{URI.escape(query.query_string)}&rpp=#{URI.escape(query.count) rescue query.count}")
@logger.info(["Query", query])
start_time = Time.now
req = http.get
result = LogStash::Search::Result.new
req.callback do
data = JSON.parse(req.response)
result.duration = Time.now - start_time
hits = (data["results"] || nil) rescue nil
if hits.nil? or !data["error"].nil?
# Use the error message if any, otherwise, return the whole
# data object as json as the error message for debugging later.
result.error_message = (data["error"] rescue false) || data.to_json
yield result
next
end
hits.each do |hit|
hit["@message"] = hit["text"]
hit["@timestamp"] = hit["created_at"]
hit.delete("text")
end
@logger.info(["Got search results",
{ :query => query.query_string, :duration => data["duration"],
:result_count => hits.size }])
if req.response_header.status != 200
result.error_message = data["error"] || req.inspect
@error = data["error"] || req.inspect
end
# We want to yield a list of LogStash::Event objects.
hits.each do |hit|
result.events << LogStash::Event.new(hit)
end
# Total hits this search could find if not limited
result.total = hits.size
result.offset = 0
yield result
end
req.errback do
@logger.warn(["Query failed", query, req, req.response])
result.duration = Time.now - start_time
result.error_message = req.response
yield result
end
end # def search
def histogram(query, field, interval=nil)
# Nothing to histogram.
result = LogStash::Search::FacetResult.new
yield result
end
end # class LogStash::Search::ElasticSearch

View file

@ -148,7 +148,9 @@
var result_row_selector = "table.results tr.event";
$(result_row_selector).live("click", function() {
var data = eval($("td.message", this).data("full"));
var data_json =$("td.message", this).data("full");
//console.log(data_json);
var data = JSON.parse(data_json);
/* Apply template to the dialog */
var query = $("#query").val().replace(/^\s+|\s+$/g, "")

View file

@ -36,12 +36,22 @@ class LogStash::Web::Server < Sinatra::Base
super
# TODO(sissel): Support alternate backends
backend_url = URI.parse(settings.backend_url)
@backend = LogStash::Search::ElasticSearch.new(
:host => backend_url.host,
:port => backend_url.port
)
end
case backend_url.scheme
when "elasticsearch"
@backend = LogStash::Search::ElasticSearch.new(
:host => backend_url.host,
:port => backend_url.port
)
when "twitter"
require "logstash/search/twitter"
@backend = LogStash::Search::Twitter.new(
:host => backend_url.host,
:port => backend_url.port
)
end # backend_url.scheme
end # def initialize
aget '/style.css' do
headers "Content-Type" => "text/css; charset=utf8"
body sass :style