Stiffstream / restinio

Cross-platform, efficient, customizable, and robust asynchronous HTTP(S)/WebSocket server C++ library with the right balance between performance and ease of use
Other
1.15k stars 93 forks source link

How do to simple request logging? #51

Closed codewithpassion closed 5 years ago

codewithpassion commented 5 years ago

Hey,

Great work with Restinio, greatly simplifies my work :)

On question: I'd like to log all requests that come in, a little like the apache access log. I can set a logging trait, and I already have that. But that uses the trace function and is very verbose.

I'd just like to output a simple log, without having to call it in every handler. Is that possible?

Thanks Dom

eao197 commented 5 years ago

Hi!

If you don't use RESTinio's express router then you can log all requests manually at the beginning of your request_handler. Something like:

auto my_request_handler(MyLogger & logger, const restinio::request_handle_t & req) {
   log_incoming_request(logger, req); // It's your function, you have to write it.
   ...
   // There you start to analyze the incoming request.
   if( restinio::http_method_get() == req->header().method() &&
      req->header().request_target() == "/" )
   { ... }
   else if(...)
   ... // and so on.
}
...
MyLogger logger{...};
restinio::run(restinio::on_thread_pool(...)
    .request_handler([logger](const auto & req) { return my_request_handler(logger, req); }
    ...);

If you use RESTinio's express router you have to call your log_incoming_request in every handler you define for the router.

The current version of RESTinio has no feature to log only the facts of incoming requests (like Apache does for access.log file).

codewithpassion commented 5 years ago

Ok, Thanks. I'm using the express router and added a call to a logging function.

eao197 commented 5 years ago

@codewithpassion I think that there can be another way. You can define your own type of request_handler and use RESTinio's express router object inside it. Something like that:

class express_router_with_logging {
   my_logger & logger_;
   std::unique_ptr<restinio::router::express_router_t<>> router_;
   ...
public:
   express_router_with_logging(
      my_logger & logger,
      std::unique_ptr<restinio::router::express_router_t<>> router)
      : logger_{logger}, router_{std::move(router)}
   {}
   ...
   restinio::request_handling_status_t operator()(
      const restinio::request_handle_t & req) const
   {
      log_incoming_request(logger_, req);
      return (*router_)(req);
   }
};
...
struct my_traits : public restinio::default_traits {
   using request_handler_t = express_router_with_logger;
   ...
};

NOTE. I don't check that approach myself, but it seems that it should be working.