-1

I am trying to log all of the errors from PHP to an external log file.

Is it possible to get the error messages displayed from

error_reporting(E_ALL);
ini_set('display_errors', 1);

as variables.

I do not want to throw any exceptions on the page I want to send them as variables.

The reason for this is I'm setting up notifications for when an error happens in AWS cloud watch as per https://aws.amazon.com/blogs/developer/php-application-logging-with-amazon-cloudwatch-logs-and-monolog/.

I can of course just change where its logging to, but I want to be notified if there is an error so I can then go check the actual log file.

Paddy Hallihan
  • 1,624
  • 3
  • 27
  • 76
  • 3
    Aren't all these errors already in the server logs? – B001ᛦ Jul 07 '21 at 13:19
  • if i am not wrong you can set a custom log file directly in php.ini – Lelio Faieta Jul 07 '21 at 13:20
  • I've added the reason for this, I don't just want to change where the logs are – Paddy Hallihan Jul 07 '21 at 13:25
  • If you're logging to CloudWatch, then set up a CloudWatch alarm with an email notification. Your application code shouldn't be bothered with this. Moreover, if an error exists in your error-handling-and-email-sending code or PHP *dies* without being able to send the email, you won't get those notifications. – deceze Jul 07 '21 at 13:26
  • For what you want, you need to write a error handler that will write specific errors to the log and trigger a mail event. – Grumpy Jul 07 '21 at 13:28
  • @deceze that article explains how to log your own messages to cloud watch which is fine. what i want to do here is get any uncaught errors that would otherwise only appear in the apache log file and also send these to cloud watch – Paddy Hallihan Jul 07 '21 at 13:28
  • You should still leave that to external, non-PHP systems, like the CloudWatch agent: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html#CloudWatch-Agent-Configuration-File-Logssection. Your PHP code should simply produce *log output.* That log output should be post-processed by external systems specialised for that. Simply log to stdout/specific log files from PHP. Let the CloudWatch agent ingest that to CloudWatch. Set up a CloudWatch alarm for specific keywords like "error" to get notified about problems. – deceze Jul 07 '21 at 13:35
  • If you bake all that into your PHP code, *which is the system which is failing*, you're introducing even more things that can go wrong into your PHP code and bloat it, and since it's the system under observation, it's not even guaranteed it'll be able to always send its own error reports. – deceze Jul 07 '21 at 13:36

1 Answers1

1

I use a combined approach:

  1. make use of set_error_handler() to install your own error handler

  2. check for fatal errors with error_get_last() in a custom function, via register_shutdown_function().

    $aError = error_get_last();
    if (NULL !== $aError {  // report fatal errors
      // anything to print or log the error
      print E_ERROR . $aError['file'] . $aError['line'] .  $aError['message'];
    }
    
  3. (Optionally) make use of set_exception_handler(), when you're dealing with ErrorExceptions.

Code4R7
  • 2,600
  • 1
  • 19
  • 42
  • `if (NULL !== $aError {` should be `if (!empty($errors)) {`. Nobody is using hungarian notation in PHP. The constant `null` is written in lowercase and swapping subject and object is not an advantage opposed to some people's thinking. – Daniel W. Jul 07 '21 at 13:40
  • Well, as you can clearly see at least somebody is using Hungarian Notation in PHP. Also, the null constant is a [special case](https://wiki.php.net/rfc/case_insensitive_constant_deprecation), and it is case insensitive by design. In this case, [`empty()`](https://www.php.net/manual/en/function.empty.php) equals [`isset()`](https://www.php.net/manual/en/function.isset.php), which 'Determine if a variable is declared and is different than null'. Which is the same here as !== NULL. – Code4R7 Jul 07 '21 at 17:55
  • The advantage of writing `NULL !== $aError` is that you can catch syntax errors earlier on. But on this I agree with you for a different reason, since it is less portable to C. I really don't care about others people's minds on the order of semantics, this code has run in a mature production environment for years. And there is no need to get religious on little details that do not matter. – Code4R7 Jul 07 '21 at 18:06
  • I'm not saying your code is wrong, it's just my opinion that when posting an answer in 2021, it should have baked in the best practices of 2021, not the conventions from 1999. – Daniel W. Jul 12 '21 at 14:42
  • That's just your preference, which is fine with me. If you feel my answer should be updated to your best practices of 2021, please edit the question and rename the variables. Then we can quit arguing about nothing and you will have more time to fix the bad certificate on your website. – Code4R7 Jul 13 '21 at 10:54