0

I have a PHP application built in Symfony. All the infrastructure is on AWS. I also have multiple APIs which are hosted on a ec2 instance connected to a READ-ONLY replica of MySQL Aurora.

My question is how can I log(store in the DB) every API call (user info, call timestamp, which parameters they are passing etc.).

I cannot insert the logging (storing in the DB) into the api endpoint because insert is a time consuming and will degrade our API performance.

Thanks

Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79
rashidkhan
  • 462
  • 8
  • 24
  • "and will degrade our API performance" you can't have it both ways. Sine you're already in AWS, maybe check out https://aws.amazon.com/blogs/developer/php-application-logging-with-amazon-cloudwatch-logs-and-monolog/ – Scuzzy Sep 08 '21 at 21:14
  • 1
    Sure, the second question conflicts with the guidelines to not ask for recommendations. However the core question obviously is "How to log the complete request". Would have been enough to edit the question instead of closing it completly, wouldn't it? About the logging: Create an EventSubscriber for `KernelEvents::TERMINAT`. This is triggered after the response is send to the user and will thus not influence the (response creation) performance. You can access the request in the event and store what ever information you like. – Andrei Herford Sep 09 '21 at 05:57
  • @Scuzzy Thanks for the link but why can't we have both ways. I think I'm not the first one who wants to do this. Everyone wants to log the information they are looking for. I had also asked about Database choice but you didn't comment on that. – rashidkhan Sep 09 '21 at 07:14
  • @AndreiHerford thanks for the hint. I was looking at the KernelEvents yesterday but was thinking if that would slow down the API response as I will have to insert the record in the Database upon each api call. Do you think it will affect api performance? – rashidkhan Sep 09 '21 at 11:19
  • 1
    @rashidkhan Of course it will effect the overall server performance since it adds extra work (as every new line of code does). By using the `Terminate` event this work is done **after** the response is send to the user. So the user will not notice any difference since his request is answered as fast as before. It would only have an effect if there is so much work to do that the server does not have the capacity to handle the next request. While this is possible in theory, I doubt that this will be the case here. – Andrei Herford Sep 09 '21 at 11:37
  • @AndreiHerford I have implented some logging using the `Terminate` and so far it looks good. Will test it further and also will try the monolog solution. Thanks for the hint though. – rashidkhan Sep 10 '21 at 10:58
  • You're welcome. I think if you would remove the "2nd question" from the question, it could be re-opend and accept answers. – Andrei Herford Sep 10 '21 at 11:01
  • I have already removed the second part and submitted for review. – rashidkhan Sep 11 '21 at 09:05

1 Answers1

1

As I understand the question the main goal is to log all requests (e.g. in the database) without a negative impact on serving the response to the user.

Symfony offers multiple KernelEvents which are are triggered at different points in time while serving a request.

The kernel.terminate event is triggerd after the response was send to the user, when the kernel is about to shout down. This is the perfect time to do clean up work and perform other stuff which should have no influces on the necessary time to create the response.

So, simply create a event subscriber or event listener to handle kernel.terminate and perform your logging here without influencing performance.

Andrei Herford
  • 17,570
  • 19
  • 91
  • 225