Best way to log access to web pages

1.3k views Asked by At

One of my website is using Nitrogen with a Cowboy server. I would like to log every access to web pages just like Apache does with access.log. What would be the best way to do that ?

3

There are 3 answers

0
P_A On BEST ANSWER

You can use cowboy middlewares https://ninenines.eu/docs/en/cowboy/1.0/guide/middlewares/

Just create a simple log module:

-module(app_web_log).
-behaviour(cowboy_middleware).

-export([execute/2]).

execute(Req, Env) ->
    {{Peer, _}, Req2} = cowboy_req:peer(Req),
    {Method, Req3} = cowboy_req:method(Req2),
    {Path, Req4} = cowboy_req:path(Req3),
    error_logger:info_msg("~p: [~p]: ~p ~p", [calendar:universal_time(), Peer, Method, Path]),
    {ok, Req4, Env}.

and add it in list of middlwares:

    {ok, _} = cowboy:start_http(http, 100, [{port, 8080}], [
            {env, [{dispatch, Dispatch}]},
            {middlewares, [cowboy_router, app_web_log, cowboy_handler]}]).
3
Steve Vinoski On

Try using Nitrogen on top of the Yaws web server instead, since it performs access logging by default.

0
chops On

Each underlying webserver does it differently (or not at all) - this is something simple_bridge does not yet have abstracted.

So in the case of cowboy, you'll likely have to rig it up yourself.

If you're using a newer build of Nitrogen (if you have the file site/src/nitrogen_main_handler.erl), then you can edit that file to manually log yourself. For example, using erlang's error handler, you could add something simple like:

log_request() ->
    error_logger:info_msg("~p: [~p]: ~p", [{date(), time()}, wf:peer_ip(), wf:url()]).

run() ->
    handlers(),
    log_request(), %% <--- insert before wf_core:run()
    wf_core:run().

Then whatever happens with the log can be handled by configuring error_logger to write to disk (http://erldocs.com/17.0/kernel/error_logger.html?i=13&search=error_logger#logfile/1)

If you use an older Nitrogen (which would have site/src/nitrogen_cowboy.erl), then you would similarly edit that file, once again before the wf_core:run() call.

Alternatively, your hooks option with cowboy could work as well. I've not worked with them, so you're on your own there :)