Last active
December 9, 2015 21:48
-
-
Save jcomellas/adbad0b34c710f6ab642 to your computer and use it in GitHub Desktop.
Cowboy onresponse callback for common access log
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% Use the following function as onresponse callback when creating the | |
%% cowboy listener environment to log HTTP requests in common log format. | |
-define(HDR_X_FORWARDED_FOR, "x-forwarded-for"). | |
-spec common_http_log(cowboy:status(), cowboy:headers(), iodata(), cowboy_req:req()) -> cowboy_req:req(). | |
common_http_log(Status, _Headers, Body, Req0) -> | |
%% 127.0.0.1 - - [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 | |
[Method, Version, Path, Qs0] = cowboy_req:get([method, version, path, qs], Req0), | |
{{IpAddr, _Port}, Req1} = cowboy_req:peer(Req0), | |
Addr = inet:ntoa(IpAddr), | |
Datetime = calendar:now_to_universal_time(os:timestamp()), | |
Iso8601Date = datetime_to_iso8601(Datetime), | |
Qs = case Qs0 of | |
<<>> -> Qs0; | |
_ -> [$?, Qs0] | |
end, | |
Size = iolist_size(Body), | |
case cowboy_req:header(<<?HDR_X_FORWARDED_FOR>>, Req1) of | |
{undefined, Req} -> | |
lager:info("~s - - [~s] \"~s ~s~s ~s\" ~b ~b", | |
[Addr, Iso8601Date, Method, Path, Qs, Version, Status, Size]), | |
Req; | |
{ForwardedAddrs0, Req} -> | |
%% The X-Forwarded-For header value looks like this: "client, proxy1, proxy2". | |
ForwardedAddrs = [[bstr:lstrip(ForwardedAddr, $\s), <<"->">>] || | |
ForwardedAddr <- binary:split(ForwardedAddrs0, <<",">>, [global, trim])], | |
lager:info("~s~s - - [~s] \"~s ~s~s ~s\" ~b ~b", | |
[iolist_to_binary(ForwardedAddrs), Addr, Iso8601Date, | |
Method, Path, Qs, Version, Status, Size]), | |
Req | |
end. | |
-spec datetime_to_iso8601(calendar:datetime()) -> binary(). | |
datetime_to_iso8601({{_, _, _}, {_, _, _}} = Datetime) -> | |
datetime_to_iso8601(Datetime, <<$Z>>). | |
-spec datetime_to_iso8601(calendar:datetime(), Suffix :: binary()) -> binary(). | |
datetime_to_iso8601({{Year, Month, Day}, {Hour, Min, Sec}}, Suffix) -> | |
ToBin = fun (I, Width) -> bstr:lpad(integer_to_binary(I), Width, $0) end, | |
YYYY = ToBin(Year, 4), | |
MM = ToBin(Month, 2), | |
DD = ToBin(Day, 2), | |
Hh = ToBin(Hour, 2), | |
Mm = ToBin(Min, 2), | |
Ss = ToBin(Sec, 2), | |
<<YYYY/binary, $-, MM/binary, $-, DD/binary, $T, | |
Hh/binary, $:, Mm/binary, $:, Ss/binary, Suffix/binary>>. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment