summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgarren smith <garren.smith@gmail.com>2019-03-06 14:34:12 +0200
committerGitHub <noreply@github.com>2019-03-06 14:34:12 +0200
commitaee2fd9859c14aed1cb28f458a846064c58cf782 (patch)
treea907f3ea95e9507a52bc0ebeeb1ba9431dbe9cc4
parenta36ec91e0542a153fead1f0c5224fed5b80d039d (diff)
downloadcouchdb-aee2fd9859c14aed1cb28f458a846064c58cf782.tar.gz
Add stats in fabric for partition and normal views (#1963)
Add metrics for partition queries This adds httpd metrics to monitor the number of request for partition queries. It also adds metrics to record the number of timeouts for partition and global query requests
-rw-r--r--src/chttpd/src/chttpd.erl37
-rw-r--r--src/chttpd/src/chttpd_db.erl15
-rw-r--r--src/couch/priv/stats_descriptions.cfg48
-rw-r--r--src/mango/src/mango_httpd.erl9
4 files changed, 104 insertions, 5 deletions
diff --git a/src/chttpd/src/chttpd.erl b/src/chttpd/src/chttpd.erl
index 631eb77c9..ac371a2e5 100644
--- a/src/chttpd/src/chttpd.erl
+++ b/src/chttpd/src/chttpd.erl
@@ -810,7 +810,8 @@ send_delayed_error(#delayed_resp{req=Req,resp=nil}=DelayedResp, Reason) ->
{Code, ErrorStr, ReasonStr} = error_info(Reason),
{ok, Resp} = send_error(Req, Code, ErrorStr, ReasonStr),
{ok, DelayedResp#delayed_resp{resp=Resp}};
-send_delayed_error(#delayed_resp{resp=Resp}, Reason) ->
+send_delayed_error(#delayed_resp{resp=Resp, req=Req}, Reason) ->
+ update_timeout_stats(Reason, Req),
log_error_with_stack_trace(Reason),
throw({http_abort, Resp, Reason}).
@@ -1025,12 +1026,15 @@ error_headers(_, Code, _, _) ->
send_error(_Req, {already_sent, Resp, _Error}) ->
{ok, Resp};
-send_error(Req, Error) ->
+send_error(#httpd{} = Req, Error) ->
+ update_timeout_stats(Error, Req),
+
{Code, ErrorStr, ReasonStr} = error_info(Error),
{Code1, Headers} = error_headers(Req, Code, ErrorStr, ReasonStr),
send_error(Req, Code1, Headers, ErrorStr, ReasonStr, json_stack(Error)).
-send_error(Req, Code, ErrorStr, ReasonStr) ->
+send_error(#httpd{} = Req, Code, ErrorStr, ReasonStr) ->
+ update_timeout_stats(ErrorStr, Req),
send_error(Req, Code, [], ErrorStr, ReasonStr, []).
send_error(Req, Code, Headers, ErrorStr, ReasonStr, []) ->
@@ -1045,6 +1049,33 @@ send_error(Req, Code, Headers, ErrorStr, ReasonStr, Stack) ->
case Stack of [] -> []; _ -> [{<<"ref">>, stack_hash(Stack)}] end
]}).
+update_timeout_stats(<<"timeout">>, #httpd{requested_path_parts = PathParts}) ->
+ update_timeout_stats(PathParts);
+update_timeout_stats(timeout, #httpd{requested_path_parts = PathParts}) ->
+ update_timeout_stats(PathParts);
+update_timeout_stats(_, _) ->
+ ok.
+
+update_timeout_stats([_, <<"_partition">>, _, <<"_design">>, _,
+ <<"_view">> | _]) ->
+ couch_stats:increment_counter([couchdb, httpd, partition_view_timeouts]);
+update_timeout_stats([_, <<"_partition">>, _, <<"_find">>| _]) ->
+ couch_stats:increment_counter([couchdb, httpd, partition_find_timeouts]);
+update_timeout_stats([_, <<"_partition">>, _, <<"_explain">>| _]) ->
+ couch_stats:increment_counter([couchdb, httpd, partition_explain_timeouts]);
+update_timeout_stats([_, <<"_partition">>, _, <<"_all_docs">> | _]) ->
+ couch_stats:increment_counter([couchdb, httpd, partition_all_docs_timeouts]);
+update_timeout_stats([_, <<"_design">>, _, <<"_view">> | _]) ->
+ couch_stats:increment_counter([couchdb, httpd, view_timeouts]);
+update_timeout_stats([_, <<"_find">>| _]) ->
+ couch_stats:increment_counter([couchdb, httpd, find_timeouts]);
+update_timeout_stats([_, <<"_explain">>| _]) ->
+ couch_stats:increment_counter([couchdb, httpd, explain_timeouts]);
+update_timeout_stats([_, <<"_all_docs">> | _]) ->
+ couch_stats:increment_counter([couchdb, httpd, all_docs_timeouts]);
+update_timeout_stats(_) ->
+ ok.
+
% give the option for list functions to output html or other raw errors
send_chunked_error(Resp, {_Error, {[{<<"body">>, Reason}]}}) ->
send_chunk(Resp, Reason),
diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl
index 5a0911559..c6404b04d 100644
--- a/src/chttpd/src/chttpd_db.erl
+++ b/src/chttpd/src/chttpd_db.erl
@@ -298,6 +298,7 @@ handle_partition_req(#httpd{path_parts=[DbName, _, PartId | Rest]}=Req, Db) ->
path_parts = [DbName | Rest],
qs = NewQS
},
+ update_partition_stats(Rest),
case Rest of
[OP | _] when OP == <<"_all_docs">> orelse ?IS_MANGO(OP) ->
case chttpd_handlers:db_handler(OP, fun db_req/2) of
@@ -318,6 +319,20 @@ handle_partition_req(#httpd{path_parts=[DbName, _, PartId | Rest]}=Req, Db) ->
handle_partition_req(Req, _Db) ->
chttpd:send_error(Req, not_found).
+update_partition_stats(PathParts) ->
+ case PathParts of
+ [<<"_design">> | _] ->
+ couch_stats:increment_counter([couchdb, httpd, partition_view_requests]);
+ [<<"_all_docs">> | _] ->
+ couch_stats:increment_counter([couchdb, httpd, partition_all_docs_requests]);
+ [<<"_find">> | _] ->
+ couch_stats:increment_counter([couchdb, httpd, partition_find_requests]);
+ [<<"_explain">> | _] ->
+ couch_stats:increment_counter([couchdb, httpd, partition_explain_requests]);
+ _ ->
+ ok % ignore path that do not match
+ end.
+
handle_design_req(#httpd{
path_parts=[_DbName, _Design, Name, <<"_",_/binary>> = Action | _Rest]
diff --git a/src/couch/priv/stats_descriptions.cfg b/src/couch/priv/stats_descriptions.cfg
index e5ac9d722..0e2271350 100644
--- a/src/couch/priv/stats_descriptions.cfg
+++ b/src/couch/priv/stats_descriptions.cfg
@@ -78,6 +78,54 @@
{type, counter},
{desc, <<"number of HTTP requests">>}
]}.
+{[couchdb, httpd, view_timeouts], [
+ {type, counter},
+ {desc, <<"number of HTTP view timeouts">>}
+]}.
+{[couchdb, httpd, find_timeouts], [
+ {type, counter},
+ {desc, <<"number of HTTP find timeouts">>}
+]}.
+{[couchdb, httpd, explain_timeouts], [
+ {type, counter},
+ {desc, <<"number of HTTP _explain timeouts">>}
+]}.
+{[couchdb, httpd, all_docs_timeouts], [
+ {type, counter},
+ {desc, <<"number of HTTP all_docs timeouts">>}
+]}.
+{[couchdb, httpd, partition_view_requests], [
+ {type, counter},
+ {desc, <<"number of partition HTTP view requests">>}
+]}.
+{[couchdb, httpd, partition_find_requests], [
+ {type, counter},
+ {desc, <<"number of partition HTTP _find requests">>}
+]}.
+{[couchdb, httpd, partition_explain_requests], [
+ {type, counter},
+ {desc, <<"number of partition HTTP _explain requests">>}
+]}.
+{[couchdb, httpd, partition_all_docs_requests], [
+ {type, counter},
+ {desc, <<"number of partition HTTP _all_docs requests">>}
+]}.
+{[couchdb, httpd, partition_view_timeouts], [
+ {type, counter},
+ {desc, <<"number of partition HTTP view timeouts">>}
+]}.
+{[couchdb, httpd, partition_find_timeouts], [
+ {type, counter},
+ {desc, <<"number of partition HTTP find timeouts">>}
+]}.
+{[couchdb, httpd, partition_explain_timeouts], [
+ {type, counter},
+ {desc, <<"number of partition HTTP _explain timeouts">>}
+]}.
+{[couchdb, httpd, partition_all_docs_timeouts], [
+ {type, counter},
+ {desc, <<"number of partition HTTP all_docs timeouts">>}
+]}.
{[couchdb, httpd, temporary_view_reads], [
{type, counter},
{desc, <<"number of temporary view reads">>}
diff --git a/src/mango/src/mango_httpd.erl b/src/mango/src/mango_httpd.erl
index d73ec6cb5..379d2e127 100644
--- a/src/mango/src/mango_httpd.erl
+++ b/src/mango/src/mango_httpd.erl
@@ -186,8 +186,13 @@ handle_find_req(#httpd{method='POST'}=Req, Db) ->
{ok, Opts0} = mango_opts:validate_find(Body),
{value, {selector, Sel}, Opts} = lists:keytake(selector, 1, Opts0),
{ok, Resp0} = start_find_resp(Req),
- {ok, AccOut} = run_find(Resp0, Db, Sel, Opts),
- end_find_resp(AccOut);
+ case run_find(Resp0, Db, Sel, Opts) of
+ {ok, AccOut} ->
+ end_find_resp(AccOut);
+ {error, Error} ->
+ chttpd:send_error(Req, Error)
+ end;
+
handle_find_req(Req, _Db) ->
chttpd:send_method_not_allowed(Req, "POST").