Kouhei Sutou
null+****@clear*****
Tue May 6 18:29:12 JST 2014
Kouhei Sutou 2014-05-06 18:29:12 +0900 (Tue, 06 May 2014) New Revision: 6a2d5bae29ebf63b97d1bb6c8299eb86d5c769d6 https://github.com/groonga/groonga/commit/6a2d5bae29ebf63b97d1bb6c8299eb86d5c769d6 Message: munin: support groonga-httpd The old `[groonga_*_http]` and `[groonga_*_gqtp]` didn't work because Munin doesn't support `*` in the middle. The new style adds a prefix to environment variables for groogna-server-http, groonga-httpd and groonga-server-gqtp: * `http_` for groogna-server-http * `httpd_` for groonga-httpd * `gqtp_` for groonga-server-gqtp Here are new parameters for groonga-server-http: * `env.http_host` (env.host is used as a fallback.) * `env.http_post` (10041 is used as a fallback.) * `env.http_database_path` * `env.http_pid_path` * `env.http_query_log_path` Here are new parameters for groonga-httpd: * `env.httpd_host` (env.host is used as a fallback.) * `env.httpd_post` (10041 is used as a fallback.) * `env.httpd_database_path` * `env.httpd_pid_path` * `env.httpd_query_log_path` Here are new parameters for groonga-server-gqtp: * `env.gqtp_host` (env.host is used as a fallback.) * `env.gqtp_post` (10043 is used as a fallback.) * `env.gqtp_database_path` * `env.gqtp_pid_path` * `env.gqtp_query_log_path` Here are other obsolete parameters: * `env.pid_file`: Use `env.pid_path` instead. * `env.path`: Use `env.database_path` instead. * `env.log_path`: Use `env.query_log_path` instead. They will be removed when Groonga 5.0.0. Reported by Naoya Murakami. Thanks!!! Modified files: data/munin/groonga_cpu_load_ data/munin/groonga_cpu_time_ data/munin/groonga_disk_ data/munin/groonga_memory_ data/munin/groonga_n_records_ data/munin/groonga_query_performance_ data/munin/groonga_status_ data/munin/groonga_throughput_ packages/debian/groonga-munin-plugins.conf packages/rpm/centos/groonga.spec.in packages/rpm/fedora/groonga.spec.in Modified: data/munin/groonga_cpu_load_ (+61 -13) =================================================================== --- data/munin/groonga_cpu_load_ 2014-05-06 15:57:08 +0900 (09a308f) +++ data/munin/groonga_cpu_load_ 2014-05-06 18:29:12 +0900 (17161ac) @@ -5,20 +5,51 @@ case "$1" in autoconf|detect) - if [ -z "${pid_file}" ]; then - echo "no (PID file isn't specified by env.pid_file)" - exit 1 - elif [ -f "${pid_file}" ]; then - echo "yes" - exit 0 - else - echo "no (PID file doesn't exist: ${pid_file})" + pid_paths= + if [ -n "${pid_path}" ]; then + pid_paths="${pid_paths}${pid_paths:+ }${pid_path}" + fi + # For backward compatibility. Remove me when 5.0.0. + if [ -n "${pid_file}" ]; then + pid_paths="${pid_paths}${pid_paths:+ }${pid_file}" + fi + if [ -n "${http_pid_path}" ]; then + pid_paths="${pid_paths}${pid_paths:+ }${http_pid_path}" + fi + if [ -n "${httpd_pid_path}" ]; then + pid_paths="${pid_paths}${pid_paths:+ }${httpd_pid_path}" + fi + if [ -n "${gqtp_pid_path}" ]; then + pid_paths="${pid_paths}${pid_paths:+ }${gqtp_pid_path}" + fi + if [ -z "${pid_paths}" ]; then + message="no (No PID path is specified. Specify " + message="${message} env.pid_path, env.http_pid_path, " + message="${message} env.httpd_pid_path and/or env.gqtp_pid_path.)" + echo "${message}" exit 1 fi + + for _pid_path in ${pid_paths}; do + if [ -f "${_pid_path}" ]; then + echo "yes" + exit 0 + fi + done + + echo "no (All PID paths don't exist: ${pid_paths})" + exit 1 ;; suggest) - echo "gqtp" - echo "http" + if [ -n "${http_pid_path}" -a -f "${http_pid_path}" ]; then + echo "http" + fi + if [ -n "${httpd_pid_path}" -a -f "${httpd_pid_path}" ]; then + echo "httpd" + fi + if [ -n "${gqtp_pid_path}" -a -f "${gqtp_pid_path}" ]; then + echo "gqtp" + fi exit 0 ;; config) @@ -39,14 +70,31 @@ EOF exit 0 ;; *) + ;; esac -if [ -z "${pid_file}" ]; then - echo "PID file isn't specified by env.pid_file" +server_type="${0##*_}" +if [ -n "${server_type}" ]; then + pid_path_variable_name="${server_type}_pid_path" +else + # For backward compatibility. Remove me when 5.0.0. + if [ -z "${pid_path}" -a -n "${pid_file}" ]; then + pid_path_variable_name="pid_file" + else + pid_path_variable_name="pid_path" + fi +fi +_pid_path=$(eval "echo \${${pid_path_variable_name}}") +if [ -z "${_pid_path}" ]; then + echo "PID path isn't specified by env.${pid_path_variable_name}" 1>&2 + exit 1 +fi +if [ ! -f "${_pid_path}" ]; then + echo "PID path doesn't exist: ${_pid_path}" 1>&2 exit 1 fi -groonga_pid=$(cat ${pid_file}) +groonga_pid=$(cat ${_pid_path}) top_for_groonga=$(top -b -n 1 -p ${groonga_pid} | grep ${groonga_pid}) load_in_percent=$(echo ${top_for_groonga} | sed -r -e 's/ +/ /g' | cut -d' ' -f 9) echo "cpu_load.value ${load_in_percent}" Modified: data/munin/groonga_cpu_time_ (+74 -13) =================================================================== --- data/munin/groonga_cpu_time_ 2014-05-06 15:57:08 +0900 (bd75134) +++ data/munin/groonga_cpu_time_ 2014-05-06 18:29:12 +0900 (5c60c17) @@ -4,22 +4,87 @@ #%# capabilities=autoconf suggest label = ENV["label"] -pid_file = ENV["pid_file"] command = ARGV.shift -case command -when "autoconf", "detect" - if pid_file.nil? - puts("no (PID file isn't specified by env.pid_file)") +def autoconf + pid_path_variable_names = [ + "pid_path", + "pid_file", # For backward compatibility. Remove me when 5.0.0. + "http_pid_path", + "httpd_pid_path", + "gqtp_pid_path", + ] + pid_paths = pid_path_variable_names.collect do |variable_name| + ENV[variable_name] + end + pid_paths = pid_paths.compact + if pid_paths.empty? + variable_names = pid_path_variable_names.collect do |name| + "env.#{name}" + end + variable_names_label = variable_names[0..-2].join(", ") + variable_names_label << " and/or #{variable_names.last}" + puts("no (No PID path is specified. Specify #{variable_names_label}.)") exit(false) - elsif File.exist?(pid_file) + end + pid_paths.each do |pid_path| + next unless File.exist?(pid_path) puts("yes") exit(true) + end + pid_paths_label = pid_paths.join(", ") + puts("no (All PID paths don't exist: #{pid_paths_label})") + exit(false) +end + +def suggest + exist_p = lambda do |variable_name| + pid_path = ENV[variable_name] + pid_path and File.exist?(pid_path) + end + if exist_p.call("http_pid_path") + puts("http") + end + if exist_p.call("httpd_pid_path") + puts("httpd") + end + if exist_p.call("gqtp_pid_path") + puts("gqtp") + end + exit(true) +end + +def target_pid_path + if /_([^_]+)\z/ =~ $0 + service_type = $1 + pid_path_variable_name = "#{service_type}_pid_path" + pid_path = ENV[pid_path_variable_name] else - puts("no (PID file doesn't exist: #{pid_file})") + pid_path_variable_name = "pid_path" + pid_path = ENV[pid_path_variable_name] + # For backward compatibility. Remove me when 5.0.0. + pid_path ||= ENV["pid_file"] + end + + if pid_path.nil? + $stderr.puts("PID path isn't specified by env.#{pid_path_variable_name}") exit(false) end + + unless File.exist?(pid_path) + $stderr.puts("PID path doesn't exist: #{pid_path}") + exit(false) + end + + pid_path +end + +case command +when "autoconf", "detect" + autoconf +when "suggest" + suggest when "config" if label title = "groonga: #{label}: CPU time" @@ -36,13 +101,9 @@ cpu_time.label CPU time cpu_time.type GAUGE EOF exit(true) -when "suggest" - puts("gqtp") - puts("http") - exit(true) end -groonga_pid = File.read(pid_file).strip +groonga_pid = File.read(target_pid_path).strip time = `ps h -o time -p #{groonga_pid}`.chomp if /\A(?:(\d+)-)?(\d+):(\d+):(\d+)\z/ =~ time day, hours, minutes, seconds, = $1, $2, $3, $4 @@ -56,6 +117,6 @@ if /\A(?:(\d+)-)?(\d+):(\d+):(\d+)\z/ =~ time cpu_time_in_day = day + fraction_in_day puts("cpu_time.value #{cpu_time_in_day}") else - puts("invalid time format: <#{time}>") + $stderr.puts("invalid time format: <#{time}>") exit(false) end Modified: data/munin/groonga_disk_ (+84 -18) =================================================================== --- data/munin/groonga_disk_ 2014-05-06 15:57:08 +0900 (0e97343) +++ data/munin/groonga_disk_ 2014-05-06 18:29:12 +0900 (c65aad5) @@ -15,7 +15,6 @@ require 'English' label = ENV["label"] @groonga = ENV["groonga"] || "groonga" @du = ENV["du"] || "du" - �� path = ENV["path"] command = ARGV.shift @@ -38,8 +37,8 @@ def parse(success, result) end def run(command, *args) - path = Shellwords.shellescape(@path) - result = `#{@groonga} #{path} #{command} #{args.join(' ')} 2>&1` + database_path = Shellwords.shellescape(@database_path) + result = `#{@groonga} #{database_path} #{command} #{args.join(' ')} 2>&1` parse($?.success?, result) end @@ -100,17 +99,87 @@ def compute_size(usages, base_path) usage end -case command -when "autoconf", "detect" - success, body = run("status") - if success - puts("yes") - exit(true) +def setup_database_path + if /_([^_]+)\z/ =~ $0 + service_type = $1 + database_path_variable_name = "#{service_type}_database_path" + database_path = ENV[database_path_variable_name] else - puts("no (#{body})") + database_path_variable_name = "database_path" + database_path = ENV[database_path_variable_name] + # For backward compatibility. Remove me when 5.0.0. + database_path ||= ENV["path"] + end + + if database_path.nil? + key = "env.#{database_path_variable_name}" + $stderr.puts("Database path isn't specified by #{key}") + exit(false) + end + + unless File.exist?(database_path) + $stderr.puts("Database path doesn't exist: #{database_path}") exit(false) end + + @database_path = database_path +end + +def autoconf + database_path_variable_names = [ + "database_path", + "path", # For backward compatibility. Remove me when 5.0.0. + "http_database_path", + "httpd_database_path", + "gqtp_database_path", + ] + database_paths = database_path_variable_names.collect do |variable_name| + ENV[variable_name] + end + database_paths = database_paths.compact + if database_paths.empty? + variable_names = database_path_variable_names.collect do |name| + "env.#{name}" + end + variable_names_label = variable_names[0..-2].join(", ") + variable_names_label << " and/or #{variable_names.last}" + puts("no (No database path is specified. Specify #{variable_names_label}.)") + exit(false) + end + database_paths.each do |database_path| + next unless File.exist?(database_path) + puts("yes") + exit(true) + end + database_paths_label = database_paths.join(", ") + puts("no (All database paths don't exist: #{database_paths_label})") + exit(false) +end + +def suggest + exist_p = lambda do |variable_name| + database_path = ENV[variable_name] + database_path and File.exist?(database_path) + end + if exist_p.call("http_database_path") + puts("http") + end + if exist_p.call("httpd_database_path") + puts("httpd") + end + if exist_p.call("gqtp_database_path") + puts("gqtp") + end + exit(true) +end + +case command +when "autoconf", "detect" + autoconf +when "suggest" + suggest when "config" + setup_database_path if label.nil? title = "groonga: disk usage" else @@ -146,20 +215,17 @@ EOF end end exit(true) -when "suggest" - puts("gqtp") - puts("http") - exit(true) end -path = Shellwords.shellescape(@path) -du_result = `#{@du} -B1 #{path}*` +setup_database_path +database_path = Shellwords.shellescape(@database_path) +du_result = `#{@du} -B1 #{database_path}*` unless $?.success? - puts("error: #{du_result}") + $stderr.puts("error: #{du_result}") exit(false) end usages = parse_du_result(du_result) -usage = compute_size(usages, @path) +usage = compute_size(usages, @database_path) puts(<<EOF) database.value #{usage} EOF Modified: data/munin/groonga_memory_ (+64 -16) =================================================================== --- data/munin/groonga_memory_ 2014-05-06 15:57:08 +0900 (62690ab) +++ data/munin/groonga_memory_ 2014-05-06 18:29:12 +0900 (675154b) @@ -5,16 +5,52 @@ case "$1" in autoconf|detect) - if [ -z "${pid_file}" ]; then - echo "no (PID file isn't specified by env.pid_file)" - exit 1 - elif [ -f "${pid_file}" ]; then - echo "yes" - exit 0 - else - echo "no (PID file doesn't exist: ${pid_file})" + pid_paths= + if [ -n "${pid_path}" ]; then + pid_paths="${pid_paths}${pid_paths:+ }${pid_path}" + fi + # For backward compatibility. Remove me when 5.0.0. + if [ -n "${pid_file}" ]; then + pid_paths="${pid_paths}${pid_paths:+ }${pid_file}" + fi + if [ -n "${http_pid_path}" ]; then + pid_paths="${pid_paths}${pid_paths:+ }${http_pid_path}" + fi + if [ -n "${httpd_pid_path}" ]; then + pid_paths="${pid_paths}${pid_paths:+ }${httpd_pid_path}" + fi + if [ -n "${gqtp_pid_path}" ]; then + pid_paths="${pid_paths}${pid_paths:+ }${gqtp_pid_path}" + fi + if [ -z "${pid_paths}" ]; then + message="no (No PID path is specified. Specify " + message="${message} env.pid_path, env.http_pid_path, " + message="${message} env.httpd_pid_path and/or env.gqtp_pid_path.)" + echo "${message}" exit 1 fi + + for _pid_path in ${pid_paths}; do + if [ -f "${_pid_path}" ]; then + echo "yes" + exit 0 + fi + done + + echo "no (All PID paths don't exist: ${pid_paths})" + exit 1 + ;; + suggest) + if [ -n "${http_pid_path}" -a -f "${http_pid_path}" ]; then + echo "http" + fi + if [ -n "${httpd_pid_path}" -a -f "${httpd_pid_path}" ]; then + echo "httpd" + fi + if [ -n "${gqtp_pid_path}" -a -f "${gqtp_pid_path}" ]; then + echo "gqtp" + fi + exit 0 ;; config) if [ -z "${label}" ]; then @@ -35,20 +71,32 @@ vsz.type GAUGE EOF exit 0 ;; - suggest) - echo "gqtp" - echo "http" - exit 0 - ;; *) + ;; esac -if [ -z "${pid_file}" ]; then - echo "PID file isn't specified by env.pid_file" +server_type="${0##*_}" +if [ -n "${server_type}" ]; then + pid_path_variable_name="${server_type}_pid_path" +else + # For backward compatibility. Remove me when 5.0.0. + if [ -z "${pid_path}" -a -n "${pid_file}" ]; then + pid_path_variable_name="pid_file" + else + pid_path_variable_name="pid_path" + fi +fi +_pid_path=$(eval "echo \${${pid_path_variable_name}}") +if [ -z "${_pid_path}" ]; then + echo "PID path isn't specified by env.${pid_path_variable_name}" 1>&2 + exit 1 +fi +if [ ! -f "${_pid_path}" ]; then + echo "PID path doesn't exist: ${_pid_path}" 1>&2 exit 1 fi -groonga_pid=$(cat ${pid_file}) +groonga_pid=$(cat ${_pid_path}) read rss_in_kb vsz_in_kb <<EOC $(ps h -o rss,vsz -p ${groonga_pid}) EOC Modified: data/munin/groonga_n_records_ (+155 -22) =================================================================== --- data/munin/groonga_n_records_ 2014-05-06 15:57:08 +0900 (f0e3c56) +++ data/munin/groonga_n_records_ 2014-05-06 18:29:12 +0900 (c131c48) @@ -4,6 +4,8 @@ #%# capabilities=autoconf suggest require 'shellwords' +require 'net/http' +require 'erb' begin require 'json' rescue LoadError @@ -13,10 +15,10 @@ end label = ENV["label"] @groonga = ENV["groonga"] || "groonga" - �� host = ENV["host"] || "localhost" - �� port = ENV["port"] || 10041 - �� path = ENV["path"] - �� exclude_tables = (ENV["exclude_tables"] || "").split(/\s*,\s*/) + �� default_host = ENV["host"] || "127.0.0.1" + �� default_http_port = 10041 + �� default_gqtp_port = 10043 + �� database_path = nil command = ARGV.shift @@ -31,24 +33,70 @@ def parse(success, result) [false, error_message] end rescue JSON::ParserError - [false, $!.message] + [false, "#{$!.message}: #{result}"] end else [success, result] end end -def run(command, *args) - if @path - path = Shellwords.shellescape(@path) - result = `#{@groonga} #{path} #{command} #{args.join(' ')} 2>&1` +def run_http(host, port, command, *args) + path = "/d/#{command}" + unless args.empty? + parameters = args.each_slice(2).collect do |key, value| + key = key.gsub(/\A--/, "") + "#{ERB::Util.u(key)}=#{ERB::Util.u(value)}" + end + path << "?" << parameters.join("&") + end + response = Net::HTTP.start(host, port) do |http| + http.get(path) + end + if response.is_a?(Net::HTTPSuccess) + parse(true, response.body) else - groonga = "#{@groonga} -p #{@port} -c #{@host}" - result = `#{groonga} #{command} #{args.join(' ')} 2>&1` + [false, "#{response.code}: #{response.body}"] end +end + +def run_gqtp(host, port, command, *args) + groonga = "#{@groonga} -p #{port} -c #{host}" + result = `#{groonga} #{command} #{args.join(' ')} 2>&1` parse($?.success?, result) end +def run_command_line(database_path, command, *args) + database_path = Shellwords.shellescape(database_path) + result = `#{@groonga} #{database_path} #{command} #{args.join(' ')} 2>&1` + parse($?.success?, result) +end + +def run(command, *args) + case @service_type + when "http" + run_http(@http_host, @http_port, command, *args) + when "httpd" + run_http(@httpd_host, @httpd_port, command, *args) + when "gqtp" + run_gqtp(@gqtp_host, @gqtp_port, command, *args) + else + run_command_line(@database_path, command, *args) + end +end + +def exclude_tables + case @service_type + when "http" + @http_exclude_tables + when "httpd" + @httpd_exclude_tables + when "gqtp" + @gqtp_exclude_tables + else + @exclude_tables + end +end + def parse_list(header, list) list.collect do |item| parsed_item = {} @@ -68,20 +116,109 @@ def table_list tables = parse_list(body[0], body[1..-1]) tables.reject do |table| name = table["name"] - @exclude_tables.include?(name) + exclude_tables.include?(name) end end -case command -when "autoconf", "detect" - success, body = run("status") - if success +def setup_service_type + if /_([^_]+)\z/ =~ $0 + @service_type = $1 + else + @service_type = nil + end +end + +def parse_exclude_tables(raw_exclude_tables_value) + (raw_exclude_tables_value || "").split(/\s*,\s*/) +end + +def setup_command_line + @database_path = ENV["database_path"] + # For backward compatibility. Remove me when 5.0.0. + @database_path ||= ENV["path"] + @exclude_tables = parse_exclude_tables(ENV["exclude_tables"]) +end + +def setup_http + @http_host = ENV["http_host"] || @default_host + @http_port = (ENV["http_port"] || @default_http_port).to_i + @http_exclude_tables = parse_exclude_tables(ENV["http_exclude_tables"]) +end + +def setup_httpd + @httpd_host = ENV["httpd_host"] || @default_host + @httpd_port = (ENV["httpd_port"] || @default_http_port).to_i + @httpd_exclude_tables = parse_exclude_tables(ENV["httpd_exclude_tables"]) +end + +def setup_gqtp + @gqtp_host = ENV["gqtp_host"] || @default_host + @gqtp_port = (ENV["gqtp_port"] || @default_gqtp_port).to_i + @gqtp_exclude_tables = parse_exclude_tables(ENV["gqtp_exclude_tables"]) +end + +def setup + setup_service_type + setup_command_line + setup_http + setup_httpd + setup_gqtp +end + +def autoconf + results = [] + + if @database_path and File.exist?(@database_path) + results << run_command_line(@database_path, "status") + end + + if @http_host and @http_port + results << run_http(@http_host, @http_port, "status") + end + + if @httpd_host and @httpd_port + results << run_http(@httpd_host, @httpd_port, "status") + end + + if @gqtp_host and @gqtp_port + results << run_gqtp(@gqtp_host, @gqtp_port, "status") + end + + if results.any? {|success, _| success} puts("yes") exit(true) else - puts("no (#{body})") + errors = results.collect do |_, result| + result + end + error_detail = errors.join(", ") + puts("no (#{error_detail})") exit(false) end +end + +def suggest + if @http_host and @http_port + success, _ = run_http(@http_host, @http_port, "status") + puts("http") if success + end + if @httpd_host and @httpd_port + success, _ = run_http(@httpd_host, @httpd_port, "status") + puts("httpd") if success + end + if @gqtp_host and @gqtp_port + success, _ = run_gqtp(@gqtp_host, @gqtp_port, "status") + puts("gqtp") if success + end + exit(true) +end + +setup +case command +when "autoconf", "detect" + autoconf +when "suggest" + suggest when "config" if label.nil? title = "groonga: number of records" @@ -103,15 +240,11 @@ EOF EOF end exit(true) -when "suggest" - puts("gqtp") - puts("http") - exit(true) end table_list.each do |table| name = table["name"] - success, body = run("select", "#{name} --limit 0") + success, body = run("select", "--table", name, "--limit", "0") unless success puts("error: #{body}") exit(false) Modified: data/munin/groonga_query_performance_ (+90 -29) =================================================================== --- data/munin/groonga_query_performance_ 2014-05-06 15:57:08 +0900 (e0de5b0) +++ data/munin/groonga_query_performance_ 2014-05-06 18:29:12 +0900 (1e3a33b) @@ -8,43 +8,80 @@ require 'strscan' label = ENV["label"] - �� log_path = ENV["log_path"] - command = ARGV.shift -case command -when "autoconf", "detect" - if @log_path.nil? - puts("no (query log file path isn't specified by env.log_path)") - exit(false) +def autoconf + query_log_path_variable_names = [ + "query_log_path", + "log_path", # For backward compatibility. Remove me when 5.0.0. + "http_query_log_path", + "httpd_query_log_path", + "gqtp_query_log_path", + ] + query_log_paths = query_log_path_variable_names.collect do |variable_name| + ENV[variable_name] end - unless File.readable?(@log_path) - puts("no (query log file isn't readable: <#{@log_path}>)") + query_log_paths = query_log_paths.compact + if query_log_paths.empty? + variable_names = query_log_path_variable_names.collect do |name| + "env.#{name}" + end + variable_names_label = variable_names[0..-2].join(", ") + variable_names_label << " and/or #{variable_names.last}" + puts("no (No query log path is specified. Specify #{variable_names_label}.)") exit(false) end - puts("yes") + query_log_paths.each do |query_log_path| + next unless File.exist?(query_log_path) + puts("yes") + exit(true) + end + query_log_paths_label = query_log_paths.join(", ") + puts("no (All query log paths don't exist: #{query_log_paths_label})") + exit(false) +end + +def suggest + exist_p = lambda do |variable_name| + query_log_path = ENV[variable_name] + query_log_path and File.exist?(query_log_path) + end + if exist_p.call("http_query_log_path") + puts("http") + end + if exist_p.call("httpd_query_log_path") + puts("httpd") + end + if exist_p.call("gqtp_query_log_path") + puts("gqtp") + end exit(true) -when "config" - if label.nil? - title = "groonga: query performance" +end + +def target_query_log_path + if /_([^_]+)\z/ =~ $0 + service_type = $1 + query_log_path_variable_name = "#{service_type}_query_log_path" + query_log_path = ENV[query_log_path_variable_name] else - title = "groonga: #{label}: query performance" + query_log_path_variable_name = "query_log_path" + query_log_path = ENV[query_log_path_variable_name] + # For backward compatibility. Remove me when 5.0.0. + query_log_path ||= ENV["log_file"] end - puts(<<EOF) -graph_title #{title} -graph_vlabel seconds -graph_category groonga -graph_info groonga query performance -longest.label Longest -average.label Average -median.label Median -EOF - exit(true) -when "suggest" - puts("gqtp") - puts("http") - exit(true) + if query_log_path.nil? + key = "env.#{query_log_path_variable_name}" + $stderr.puts("Query log path isn't specified by #{key}") + exit(false) + end + + unless File.exist?(query_log_path) + $stderr.puts("Query log path doesn't exist: #{query_log_path}") + exit(false) + end + + query_log_path end class ReverseLineReader @@ -101,11 +138,35 @@ class ReverseLineReader end end +case command +when "autoconf", "detect" + autoconf +when "suggest" + suggest +when "config" + if label.nil? + title = "groonga: query performance" + else + title = "groonga: #{label}: query performance" + end + puts(<<EOF) +graph_title #{title} +graph_vlabel seconds +graph_category groonga +graph_info groonga query performance + +longest.label Longest +average.label Average +median.label Median +EOF + exit(true) +end + span = 60 * 5 # 5min mega = 1_000_000.0 now = Time.now elapsed_times = [] -File.open(@log_path) do |log_file| +File.open(target_query_log_path) do |log_file| ReverseLineReader.new(log_file).each do |line| case line when /\A(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)\.(\d+)\|([\da-f])+\|<(\d+) rc=0$/ Modified: data/munin/groonga_status_ (+102 -29) =================================================================== --- data/munin/groonga_status_ 2014-05-06 15:57:08 +0900 (79a43ab) +++ data/munin/groonga_status_ 2014-05-06 18:29:12 +0900 (22cdde2) @@ -13,9 +13,9 @@ end label = ENV["label"] @groonga = ENV["groonga"] || "groonga" - �� host = ENV["host"] || "localhost" - �� protocol = ENV["protocol"] || "http" - �� port = ENV["port"] || 10041 + �� default_host = ENV["host"] || "127.0.0.1" + �� default_http_port = 10041 + �� default_gqtp_port = 10043 command = ARGV.shift @@ -37,40 +37,117 @@ def parse(success, result) end end -def run(command, *args) - case @protocol - when "gqtp" - groonga = "#{@groonga} -p #{@port} -c #{@host}" - result = `#{groonga} #{command} #{args.join(' ')} 2>&1` - parse($?.success?, result) +def run_http(host, port, command) + path = "/d/#{command}" + response = Net::HTTP.start(host, port) do |http| + http.get(path) + end + if response.is_a?(Net::HTTPSuccess) + parse(true, response.body) + else + [false, "#{response.code}: #{response.body}"] + end +end + +def run_gqtp(host, port, command) + groonga = "#{@groonga} -p #{port} -c #{host}" + result = `#{groonga} #{command} 2>&1` + parse($?.success?, result) +end + +def run(command) + case @service_type when "http" - response = Net::HTTP.start(@host, @port) do |http| - http.get("/d/#{command}") - end - parse(response.is_a?(Net::HTTPSuccess), response.body) + run_http(@http_host, @http_port, command) + when "httpd" + run_http(@httpd_host, @httpd_port, command) + when "gqtp" + run_gqtp(@gqtp_host, @gqtp_port, command) + else + [false, "unknown service type: #{@service_type}"] end end -def parse_list(header, list) - list.collect do |item| - parsed_item = {} - header.each_with_index do |(name, type), i| - parsed_item[name] = item[i] - end - parsed_item +def setup_service_type + if /_([^_]+)\z/ =~ $0 + @service_type = $1 + else + @service_type = nil end end -case command -when "autoconf", "detect" - success, body = run("status") - if success +def setup_http + @http_host = ENV["http_host"] || @default_host + @http_port = (ENV["http_port"] || @default_http_port).to_i +end + +def setup_httpd + @httpd_host = ENV["httpd_host"] || @default_host + @httpd_port = (ENV["httpd_port"] || @default_http_port).to_i +end + +def setup_gqtp + @gqtp_host = ENV["gqtp_host"] || @default_host + @gqtp_port = (ENV["gqtp_port"] || @default_gqtp_port).to_i +end + +def setup + setup_service_type + setup_http + setup_httpd + setup_gqtp +end + +def autoconf + results = [] + + if @http_host and @http_port + results << run_http(@http_host, @http_port, "status") + end + + if @httpd_host and @httpd_port + results << run_http(@httpd_host, @httpd_port, "status") + end + + if @gqtp_host and @gqtp_port + results << run_gqtp(@gqtp_host, @gqtp_port, "status") + end + + if results.any? {|success, _| success} puts("yes") exit(true) else - puts("no (#{body})") + errors = results.collect do |_, result| + result + end + error_detail = errors.join(", ") + puts("no (#{error_detail})") exit(false) end +end + +def suggest + if @http_host and @http_port + success, _ = run_http(@http_host, @http_port, "status") + puts("http") if success + end + if @httpd_host and @httpd_port + success, _ = run_http(@httpd_host, @httpd_port, "status") + puts("httpd") if success + end + if @gqtp_host and @gqtp_port + success, _ = run_gqtp(@gqtp_host, @gqtp_port, "status") + puts("gqtp") if success + end + exit(true) +end + +setup +case command +when "autoconf", "detect" + autoconf +when "suggest" + suggest when "config" if label.nil? title = "groonga: status" @@ -87,10 +164,6 @@ alloc_count.label alloc count alloc_count.type GAUGE EOF exit(true) -when "suggest" - puts("gqtp") - puts("http") - exit(true) end success, body = run("status") Modified: data/munin/groonga_throughput_ (+103 -39) =================================================================== --- data/munin/groonga_throughput_ 2014-05-06 15:57:08 +0900 (ba0c2e1) +++ data/munin/groonga_throughput_ 2014-05-06 18:29:12 +0900 (241ae8e) @@ -3,6 +3,7 @@ #%# family=auto #%# capabilities=autoconf suggest +require 'net/http' begin require 'json' rescue LoadError @@ -12,9 +13,9 @@ end label = ENV["label"] @groonga = ENV["groonga"] || "groonga" - �� host = ENV["host"] || "localhost" - �� port = ENV["port"] || 10041 - �� protocol = ENV["protocol"] || "gqtp" + �� default_host = ENV["host"] || "127.0.0.1" + �� default_http_port = 10041 + �� default_gqtp_port = 10043 command = ARGV.shift @@ -36,50 +37,117 @@ def parse(success, result) end end -def run(command, *args) - if @protocol == "http" - require "net/http" - begin - response = Net::HTTP.start(@host, @port) do |http| - http.get("/d/status.json") - end - if response.is_a?(Net::HTTPSuccess) - parse(true, response.body) - else - parse(false, "#{response.code}: #{response.body}") - end - rescue Exception - message = "#{$!.class}: #{$!.message}\n" - message << $@.join("\n") - parse(false, message) - end +def run_http(host, port, command) + path = "/d/#{command}" + response = Net::HTTP.start(host, port) do |http| + http.get(path) + end + if response.is_a?(Net::HTTPSuccess) + parse(true, response.body) else - groonga = "#{@groonga} -p #{@port} -c #{@host}" - result = `#{groonga} #{command} #{args.join(' ')} 2>&1` - parse($?.success?, result) + [false, "#{response.code}: #{response.body}"] end end -def parse_list(header, list) - list.collect do |item| - parsed_item = {} - header.each_with_index do |(name, type), i| - parsed_item[name] = item[i] - end - parsed_item +def run_gqtp(host, port, command) + groonga = "#{@groonga} -p #{port} -c #{host}" + result = `#{groonga} #{command} 2>&1` + parse($?.success?, result) +end + +def run(command) + case @service_type + when "http" + run_http(@http_host, @http_port, command) + when "httpd" + run_http(@httpd_host, @httpd_port, command) + when "gqtp" + run_gqtp(@gqtp_host, @gqtp_port, command) + else + [false, "unknown service type: #{@service_type}"] end end -case command -when "autoconf", "detect" - success, body = run("status") - if success +def setup_service_type + if /_([^_]+)\z/ =~ $0 + @service_type = $1 + else + @service_type = nil + end +end + +def setup_http + @http_host = ENV["http_host"] || @default_host + @http_port = (ENV["http_port"] || @default_http_port).to_i +end + +def setup_httpd + @httpd_host = ENV["httpd_host"] || @default_host + @httpd_port = (ENV["httpd_port"] || @default_http_port).to_i +end + +def setup_gqtp + @gqtp_host = ENV["gqtp_host"] || @default_host + @gqtp_port = (ENV["gqtp_port"] || @default_gqtp_port).to_i +end + +def setup + setup_service_type + setup_http + setup_httpd + setup_gqtp +end + +def autoconf + results = [] + + if @http_host and @http_port + results << run_http(@http_host, @http_port, "status") + end + + if @httpd_host and @httpd_port + results << run_http(@httpd_host, @httpd_port, "status") + end + + if @gqtp_host and @gqtp_port + results << run_gqtp(@gqtp_host, @gqtp_port, "status") + end + + if results.any? {|success, _| success} puts("yes") exit(true) else - puts("no (#{body})") + errors = results.collect do |_, result| + result + end + error_detail = errors.join(", ") + puts("no (#{error_detail})") exit(false) end +end + +def suggest + if @http_host and @http_port + success, _ = run_http(@http_host, @http_port, "status") + puts("http") if success + end + if @httpd_host and @httpd_port + success, _ = run_http(@httpd_host, @httpd_port, "status") + puts("httpd") if success + end + if @gqtp_host and @gqtp_port + success, _ = run_gqtp(@gqtp_host, @gqtp_port, "status") + puts("gqtp") if success + end + exit(true) +end + +setup +case command +when "autoconf", "detect" + autoconf +when "suggest" + suggest when "config" if label.nil? title = "groonga: throughput" @@ -96,10 +164,6 @@ n_queries.label N queries n_queries.type COUNTER EOF exit(true) -when "suggest" - puts("gqtp") - puts("http") - exit(true) end success, body = run("status") Modified: packages/debian/groonga-munin-plugins.conf (+17 -10) =================================================================== --- packages/debian/groonga-munin-plugins.conf 2014-05-06 15:57:08 +0900 (434ce1a) +++ packages/debian/groonga-munin-plugins.conf 2014-05-06 18:29:12 +0900 (4bb7a2a) @@ -2,16 +2,23 @@ user groonga group groonga env.PATH /usr/bin:/bin:/usr/local/bin - env.path /var/lib/groonga/db/db + env.database_path /var/lib/groonga/db/db env.host 127.0.0.1 - env.port 10041 - env.protocol http - env.pid_file /var/run/groonga/groonga-http.pid - env.log_path /var/log/groonga/query-http.log -[groonga_*_gqtp] - env.protocol gqtp - env.port 10043 - env.pid_file /var/run/groonga/groonga-gqtp.pid - env.log_path /var/log/groonga/query-gqtp.log + env.http_host 127.0.0.1 + env.http_port 10041 + env.http_database_path /var/lib/groonga/db/db + env.http_pid_path /var/run/groonga/groonga-http.pid + env.http_query_log_path /var/log/groonga/query-http.log + env.httpd_host 127.0.0.1 + env.httpd_port 10041 + env.httpd_database_path /var/lib/groonga/db/db + env.httpd_pid_path /var/run/groonga/groonga-httpd.pid + env.httpd_query_log_path /var/log/groonga/httpd/groonga-query.log + + env.gqtp_host 127.0.0.1 + env.gqtp_port 10043 + env.gqtp_database_path /var/lib/groonga/db/db + env.gqtp_pid_path /var/run/groonga/groonga-gqtp.pid + env.gqtp_query_log_path /var/log/groonga/query-gqtp.log Modified: packages/rpm/centos/groonga.spec.in (+20 -11) =================================================================== --- packages/rpm/centos/groonga.spec.in 2014-05-06 15:57:08 +0900 (e9f9156) +++ packages/rpm/centos/groonga.spec.in 2014-05-06 18:29:12 +0900 (e4f8d94) @@ -197,18 +197,27 @@ cat <<EOC > $RPM_BUILD_ROOT%{_sysconfdir}/munin/plugin-conf.d/groonga [groonga_*] user groonga group groonga - env.PATH %{_bindir} - env.pid_file %{_localstatedir}/run/groonga/groonga-http.pid - env.path %{_localstatedir}/lib/groonga/db/db + env.PATH ${_bindir} + env.database_path %{_localstatedir}/lib/groonga/db/db env.host 127.0.0.1 - env.protocol http - env.port 10041 - env.log_path %{_localstatedir}/log/groonga/query-http.log -[groonga_*_gqtp] - env.protocol gqtp - env.port 10043 - env.pid_file %{_localstatedir}/run/groonga/groonga-gqtp.pid - env.log_path %{_localstatedir}/log/groonga/query-gqtp.log + + env.http_host 127.0.0.1 + env.http_port 10041 + env.http_database_path %{_localstatedir}/lib/groonga/db/db + env.http_pid_path %{_localstatedir}/run/groonga/groonga-http.pid + env.http_query_log_path %{_localstatedir}/log/groonga/query-http.log + + env.httpd_host 127.0.0.1 + env.httpd_port 10041 + env.httpd_database_path %{_localstatedir}/lib/groonga/db/db + env.httpd_pid_path %{_localstatedir}/run/groonga/groonga-httpd.pid + env.httpd_query_log_path %{_localstatedir}/log/groonga/httpd/groonga-query.log + + env.gqtp_host 127.0.0.1 + env.gqtp_port 10043 + env.gqtp_database_path %{_localstatedir}/lib/groonga/db/db + env.gqtp_pid_path %{_localstatedir}/run/groonga/groonga-gqtp.pid + env.gqtp_query_log_path %{_localstatedir}/log/groonga/query-gqtp.log EOC %clean Modified: packages/rpm/fedora/groonga.spec.in (+20 -11) =================================================================== --- packages/rpm/fedora/groonga.spec.in 2014-05-06 15:57:08 +0900 (efae352) +++ packages/rpm/fedora/groonga.spec.in 2014-05-06 18:29:12 +0900 (3fbe7e4) @@ -218,18 +218,27 @@ cat <<EOC > $RPM_BUILD_ROOT%{_sysconfdir}/munin/plugin-conf.d/groonga [groonga_*] user groonga group groonga - env.PATH %{_bindir} - env.pid_file %{_localstatedir}/run/groonga/groonga-http.pid - env.path %{_localstatedir}/lib/groonga/db/db + env.PATH ${_bindir} + env.database_path %{_localstatedir}/lib/groonga/db/db env.host 127.0.0.1 - env.protocol http - env.port 10041 - env.log_path %{_localstatedir}/log/groonga/query-http.log -[groonga_*_gqtp] - env.protocol gqtp - env.port 10043 - env.pid_file %{_localstatedir}/run/groonga/groonga-gqtp.pid - env.log_path %{_localstatedir}/log/groonga/query-gqtp.log + + env.http_host 127.0.0.1 + env.http_port 10041 + env.http_database_path %{_localstatedir}/lib/groonga/db/db + env.http_pid_path %{_localstatedir}/run/groonga/groonga-http.pid + env.http_query_log_path %{_localstatedir}/log/groonga/query-http.log + + env.httpd_host 127.0.0.1 + env.httpd_port 10041 + env.httpd_database_path %{_localstatedir}/lib/groonga/db/db + env.httpd_pid_path %{_localstatedir}/run/groonga/groonga-httpd.pid + env.httpd_query_log_path %{_localstatedir}/log/groonga/httpd/groonga-query.log + + env.gqtp_host 127.0.0.1 + env.gqtp_port 10043 + env.gqtp_database_path %{_localstatedir}/lib/groonga/db/db + env.gqtp_pid_path %{_localstatedir}/run/groonga/groonga-gqtp.pid + env.gqtp_query_log_path %{_localstatedir}/log/groonga/query-gqtp.log EOC # install python binding -------------- next part -------------- HTML����������������������������...Download