NorikraQueryDebugとは
- お好きなテキストエディタでノリクラクエリを書くと
- 書きなおすたびに自動的にアップロードしてくれつつ
- クエリの結果がコンソールにながれるやつ。
コマンド
ruby norikra_query_debug.rb start_debug query.txt --host NORIKRA_HOST
クエリファイル
"@@@"で始まる行で区切って複数のクエリを書きます。
query.txt
@@@ name=query1 group=debug
SELECT ...
FROM ...
WHERE ...
@@@ name=query2 group=LOOPBACK(loopback_from_query2)
SELECT ...
FROM ...
WHERE ...
@@@ name=query3 group=debug
SELECT ...
FROM loopback_from_query2
WHERE ...
@@@ name=msg_per_second group=debug
SELECT
COUNT(1) as mps
FROM
target.win:time_batch(1sec)
コード
norikra_query_debug.rb
require "norikra-client"
require "thor"
require 'timeout'
require 'io/console'
require "ostruct"
class NorikraQueryDebug
def initialize(host,port)
@host = host
@port = port
@client = Norikra::Client.new(@host,@port)
@event_count = 0
@queries = []
end
def start_debug(query_file)
puts "Hit 'q' to quit."
next_fetch_time = Time.now
loop do
now = Time.now
case input_cmd
when :quit
break
end
if file_updated?(query_file)
@queries.each do |q|
@client.deregister(q.name)
end
@queries = parse_query_file(query_file)
@queries.each_with_index do |q,query_index|
puts "################################################################"
puts "## [#{'%03d' % [query_index+1]}] #{q.name},#{q.group} (#{query_file})"
puts q.query
if update_query(q.name, q.group, q.query)
puts "## OK name=#{q.name} group=#{q.group} host=#{@host} port=#{@port}"
puts ""
else
puts "## FAILED name=#{q.name} group=#{q.group} host=#{@host} port=#{@port}"
puts ""
end
end
puts ""
end
if next_fetch_time < now
@queries.each do |q|
events = @client.event(q.name)
events.each do |time,event|
puts("[%d] %s | %s : %s" % [@event_count, Time.at(time).strftime("%Y-%m-%d %H:%M:%S"), q.name, event.inspect])
@event_count += 1
end
end
next_fetch_time = now+1
end
end
@queries.each do |q|
@client.deregister(q.name)
end
end
def parse_query_file(filename)
queries = []
name = nil
group = nil
query = ""
query_index = 0
s = File.read(filename)
lines = ["@@@"] + s.lines
commit_query = proc do
if query!=""
queries << OpenStruct.new({:name=>name, :group=>group, :query=>query})
query_index += 1
end
name = "query#{'%03d' % [query_index+1]}_#{`whoami`.strip}@#{`hostname`.strip}"
group = "debug"
query = ""
end
lines.each do |line|
if line =~ /^@@@/
commit_query.call
if line =~ /name=(\S+)/
name = $1
end
if line =~ /group=(\S+)/
group = $1
if group=="nil"
group = nil
end
end
else
query << line
end
end
commit_query.call
return queries
end
def update_query(name, group, query)
begin
begin
@client.register(name,group,query)
rescue Norikra::RPC::ClientError => e
if e.message =~ /query name.+already exists/
@client.deregister(name)
@client.register(name,group,query)
else
raise e
end
end
return true
rescue => e
puts e.message
end
return false
end
def file_updated?(filename)
unless File.exist?(filename)
raise "not exist filename=#{filename}"
end
mtime = File.mtime(filename)
size = File.size(filename)
@file_states ||= {}
old_state = @file_states[filename]
if old_state && old_state[:mtime]==mtime && old_state[:size]==size
return false
end
@file_states[filename] = {:mtime=>mtime, :size=>size}
return true
end
def input_cmd
begin
c = Timeout::timeout(0.1) do
$stdin.getch
end
if c=="q"
return :quit
end
if c=="\r"
puts
else
putc(c)
end
rescue Timeout::Error => e
return :timeout
end
return nil
end
class CLI < Thor
desc "start_debug QUERY_FILE", "upload query for each update, and fetch result."
option :host, :type=>:string, :default=>"localhost"
option :port, :type=>:numeric, :default=>26571
def start_debug(query_file)
nqd = NorikraQueryDebug.new(options[:host], options[:port])
nqd.start_debug(query_file)
end
default_task :start_debug
end
end
NorikraQueryDebug::CLI.start