Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id F0B901862E for ; Wed, 12 Aug 2015 15:54:47 +0000 (UTC) Received: (qmail 64609 invoked by uid 500); 12 Aug 2015 15:54:25 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 64424 invoked by uid 500); 12 Aug 2015 15:54:25 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 63775 invoked by uid 99); 12 Aug 2015 15:54:25 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 12 Aug 2015 15:54:25 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 29482E3623; Wed, 12 Aug 2015 15:54:25 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: rnewson@apache.org To: commits@couchdb.apache.org Date: Wed, 12 Aug 2015 15:54:30 -0000 Message-Id: <7c0690e4d95240bb90b0be9fac58b3b4@git.apache.org> In-Reply-To: <4f5debe8615249bda39bc823d0718dfd@git.apache.org> References: <4f5debe8615249bda39bc823d0718dfd@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [06/11] chttpd commit: updated refs/heads/master to 238b8c4 Refactor handle_request/1 to use #httpd_resp{} Pass more info into #httpd{} and introduce #httpd_resp{} so we can abstract updating stats and logging of request into separate functions. We also prepare for introduction of before_request/after_request hooks. Project: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/commit/8d8cf91a Tree: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/tree/8d8cf91a Diff: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/diff/8d8cf91a Branch: refs/heads/master Commit: 8d8cf91a9995a874734873ab767cde46c9c66637 Parents: cf58b04 Author: ILYA Khlopotov Authored: Mon Jun 22 05:32:39 2015 -0700 Committer: ILYA Khlopotov Committed: Tue Aug 11 09:14:29 2015 -0700 ---------------------------------------------------------------------- include/chttpd.hrl | 22 +++++++++++ src/chttpd.erl | 97 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 97 insertions(+), 22 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/8d8cf91a/include/chttpd.hrl ---------------------------------------------------------------------- diff --git a/include/chttpd.hrl b/include/chttpd.hrl new file mode 100644 index 0000000..9d3bd97 --- /dev/null +++ b/include/chttpd.hrl @@ -0,0 +1,22 @@ +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + + +-record(httpd_resp, { + end_ts, + code, + response, + status, + nonce, + should_log = true, + reason +}). http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/8d8cf91a/src/chttpd.erl ---------------------------------------------------------------------- diff --git a/src/chttpd.erl b/src/chttpd.erl index 215f509..7a7bad9 100644 --- a/src/chttpd.erl +++ b/src/chttpd.erl @@ -12,6 +12,7 @@ -module(chttpd). -include_lib("couch/include/couch_db.hrl"). +-include_lib("chttpd/include/chttpd.hrl"). -export([start_link/0, start_link/1, start_link/2, stop/0, handle_request/1, handle_request_int/1, @@ -190,8 +191,14 @@ handle_request_int(MochiReq) -> Other -> Other end, + Nonce = couch_util:to_hex(crypto:rand_bytes(5)), + HttpReq = #httpd{ mochi_req = MochiReq, + begin_ts = Begin, + peer = Peer, + original_method = Method1, + nonce = Nonce, method = Method, path_parts = [list_to_binary(chttpd:unquote(Part)) || Part <- string:tokens(Path, "/")] @@ -204,12 +211,12 @@ handle_request_int(MochiReq) -> end, % put small token on heap to keep requests synced to backend calls - erlang:put(nonce, couch_util:to_hex(crypto:rand_bytes(5))), + erlang:put(nonce, Nonce), % suppress duplicate log erlang:put(dont_log_request, true), - Result = + Result0 = try couch_httpd:validate_host(HttpReq), chttpd_csrf:validate(HttpReq), @@ -260,28 +267,74 @@ handle_request_int(MochiReq) -> end end, - RequestTime = timer:now_diff(os:timestamp(), Begin)/1000, - {Status, Code} = case Result of - {ok, #delayed_resp{resp=Resp}} -> - {ok, Resp:get(code)}; - {ok, Resp} -> - {ok, Resp:get(code)}; - {aborted, Resp, _} -> - {aborted, Resp:get(code)} + {HttpReq1, HttpResp0} = result(Result0, HttpReq), + + HttpResp1 = update_stats(HttpReq1, HttpResp0), + maybe_log(HttpReq1, HttpResp1), + + case HttpResp1 of + #httpd_resp{status = ok, response = Resp} -> + {ok, Resp}; + #httpd_resp{status = aborted, reason = Reason} -> + couch_log:error("Response abnormally terminated: ~p", [Reason]), + exit(normal) + end. + +result(Result, #httpd{nonce = Nonce} = Req) -> + {Status, Code, Reason} = case Result of + {ok, #delayed_resp{resp=Resp}} -> + {ok, Resp:get(code), undefined}; + {ok, Resp} -> + {ok, Resp:get(code), undefined}; + {aborted, Resp, AbortReason} -> + {aborted, Resp:get(code), AbortReason} + end, + + HttpResp = #httpd_resp{ + code = Code, + status = Status, + response = Resp, + nonce = Nonce, + reason = Reason + }, + {Req, HttpResp}. + + +update_stats(HttpReq, #httpd_resp{end_ts = undefined} = Res) -> + update_stats(HttpReq, Res#httpd_resp{end_ts = os:timestamp()}); +update_stats(#httpd{begin_ts = BeginTime}, #httpd_resp{} = Res) -> + #httpd_resp{status = Status, end_ts = EndTime} = Res, + RequestTime = timer:now_diff(EndTime, BeginTime) / 1000, + couch_stats:update_histogram([couchdb, request_time], RequestTime), + case Status of + ok -> + couch_stats:increment_counter([couchdb, httpd, requests]); + aborted -> + couch_stats:increment_counter([couchdb, httpd, aborted_requests]) end, + Res. + +maybe_log(#httpd{} = HttpReq, #httpd_resp{should_log = true} = HttpResp) -> + #httpd{ + mochi_req = MochiReq, + begin_ts = BeginTime, + original_method = Method, + peer = Peer, + nonce = Nonce + } = HttpReq, + #httpd_resp{ + end_ts = EndTime, + code = Code, + status = Status + } = HttpResp, Host = MochiReq:get_header_value("Host"), - couch_log:notice("~s ~s ~s ~s ~s ~B ~p ~B", [get(nonce), Peer, Host, - atom_to_list(Method1), RawUri, Code, Status, round(RequestTime)]), - couch_stats:update_histogram([couchdb, request_time], RequestTime), - case Result of - {ok, _} -> - couch_stats:increment_counter([couchdb, httpd, requests]), - {ok, Resp}; - {aborted, _, Reason} -> - couch_stats:increment_counter([couchdb, httpd, aborted_requests]), - couch_log:error("Response abnormally terminated: ~p", [Reason]), - exit(normal) - end. + RawUri = MochiReq:get(raw_path), + RequestTime = timer:now_diff(EndTime, BeginTime) / 1000, + couch_log:notice("~s ~s ~s ~s ~s ~B ~p ~B", [Nonce, Peer, Host, + atom_to_list(Method), RawUri, Code, Status, round(RequestTime)]); +maybe_log(_HttpReq, #httpd_resp{should_log = false}) -> + ok. + %% HACK: replication currently handles two forms of input, #db{} style %% and #http_db style. We need a third that makes use of fabric. #db{}