diff --git a/web/lib/elasticsearch.rb b/web/lib/elasticsearch.rb new file mode 100644 index 000000000..2051a4528 --- /dev/null +++ b/web/lib/elasticsearch.rb @@ -0,0 +1,57 @@ + +require "em-http-request" +require "logstash/namespace" +require "logstash/logging" + +module LogStash::Web; end +class LogStash::Web::ElasticSearch + def initialize + @logger = LogStash::Logger.new(STDOUT) + end + + def search(params) + http = EventMachine::HttpRequest.new("http://localhost:9200/_search") + params[:offset] ||= 0 + params[:count] ||= 20 + + @logger.info(["Query", params]) + esreq = { + "sort" => [ + { "@timestamp" => "desc" } + ], + "query" => { + "query_string" => { + "query" => params[:q] + } # query_string + }, # query + "facets" => { + "by_hour" => { + "histogram" => { + "field" => "@timestamp", + "time_interval" => "1h", + }, # histogram + }, # by_hour + }, # facets + "from" => params[:offset], + "size" => params[:count], + } + #@logger.info(["ElasticSearch Query", esreq]) + start_time = Time.now + req = http.get :body => esreq.to_json + req.callback do + #headers req.response_header + data = JSON.parse(req.response) + data["duration"] = Time.now - start_time + @logger.info(["Got search results", + { :query => params[:q], :duration => data["duration"]}]) + if req.response_header.status != 200 + @error = data["error"] + end + yield data + end + req.errback do + @logger.warn(["Query failed", params, req.response]) + yield :failure + end + end # def search +end diff --git a/web/server.rb b/web/server.rb index 0687ec4d8..ce9709a88 100755 --- a/web/server.rb +++ b/web/server.rb @@ -1,15 +1,14 @@ #!/usr/bin/env ruby ##rackup -Ilib:../lib -s thin +$:.unshift("%s/../lib" % File.dirname(__FILE__)) + require "rubygems" require "json" require "eventmachine" -require "em-http-request" require "rack" require "sinatra/async" -#require "haml" -require "erb" -#require"sass/plugin/rack" +require "lib/elasticsearch" class EventMachine::ConnectionError < RuntimeError; end @@ -18,6 +17,7 @@ class LogStashWeb < Sinatra::Base set :haml, :format => :html5 set :logging, true set :public, "./public" + elasticsearch = LogStash::Web::ElasticSearch.new aget '/style.css' do headers "Content-Type" => "text/css; charset=utf8" @@ -31,50 +31,25 @@ class LogStashWeb < Sinatra::Base aget '/search' do headers({"Content-Type" => "text/html" }) if params[:q] and params[:q] != "" - search :results + elasticsearch.search(params) do |@results| + @hits = (@results["hits"]["hits"] rescue []) + body haml :"search/results", :layout => !request.xhr? + end else @hits = [] - body haml :"search/results" + body haml :"search/results", :layout => !request.xhr? end end apost '/search/ajax' do headers({"Content-Type" => "text/html" }) - search :ajax + elasticsearch.search(params) do |@results| + @hits = (@results["hits"]["hits"] rescue []) + @facets = (@results["facets"] or {}) + body haml :"search/ajax", :layout => !request.xhr? + end end - def search(type) - http = EventMachine::HttpRequest.new("http://localhost:9200/_search") - params[:offset] ||= 0 - params[:count] ||= 20 - - puts "Query: #{params[:q]}" - esreq = { - "sort" => [ - { "@timestamp" => "desc" } - ], - "query" => { - "query_string" => { - "query" => params[:q] - } - }, - "from" => params[:offset], - "size" => params[:count], - } - req = http.get :body => esreq.to_json - req.callback do - #headers req.response_header - data = JSON.parse(req.response) - if req.response_header.status != 200 - @error = data["error"] - end - @hits = data["hits"]["hits"] rescue [] - body haml :"search/#{type.to_s}", :layout => !request.xhr? - end - req.errback do - body "Failed. #{req.response}" - end - end # def search end # class LogStashWeb Rack::Handler::Thin.run(