Jump to content

Recommended Posts

Whenever there's a PHP or MySQL error on my production site, I want the error to be logged in a file.

 

I have found a file called error_log in my site's root folder containing previous PHP and MySQL errors, so error logging is already working.  But I want to understand how and why it's working.

 

I checked my php.ini file:

error_reporting = E_ALL & ~E_NOTICE

display_errors = On

display_startup_errors = Off

; Log errors into a log file (server-specific log, stderr, or error_log (below))
; As stated above, you're strongly advised to use error logging in place of
; error displaying on production web sites.
log_errors = On;

; Set maximum length of log_errors. In error_log information about the source is
; added. The default is 1024 and 0 allows to not apply any maximum length at all.
log_errors = On;

; Log errors to specified file.
error_log = error_log;

; Log errors to syslog (Event Log on NT, not valid in Windows 95).
error_log = error_log;

Question 1

 

How can there be two each of log_errors = On and error_log = error_log?

 

 

Question 2

 

Will errors be logged in the error_log file no matter what, or do I have to use die()/trigger_error() in my code? 

 

In other words, if my database is down, will all of these lines log errors?

mysql_query("SELECT * FROM `table` WHERE date IS NULL");
mysql_query("SELECT * FROM `table` WHERE date IS NULL") or die(mysql_error());
mysql_query("SELECT * FROM `table` WHERE date IS NULL") or trigger_error(mysql_error());

Question 3

 

If I put E_USER_ERROR in trigger_error(), will only that type of errors be logged?
 

Link to comment
https://forums.phpfreaks.com/topic/283185-trying-to-understand-error-logging/
Share on other sites

Question1 For some reason your host has this directive defined twice. All errors is logged to the file named error_log

 

Question 2 If error reporting is off, then yes all errors will be logged. What types of errors are logged depends on the level you have set error_reporting to. Setting error reporting to    E_ALL & ~E_NOTICE   will log all errors except notices

 

Question 3 No

this should help you on the subject:

http://php.net/manual/en/book.errorfunc.php

 

Thanks, but I've already checked that stuff out. It's quite confusing for me.

 

Question 2 If error reporting is off, then yes all errors will be logged. What types of errors are logged depends on the level you have set error_reporting to. Setting error reporting to    E_ALL & ~E_NOTICE   will log all errors except notices

 

Do you mean if error_reporting is turned on?

 

Can you explain how to use the predefined constants (e.g., E_USER_ERROR), please?

 

Do you mean if error_reporting is turned on?

Sorry I meant to say display_errors is off. If error_reporting is off then no errors will be logged.

 

The E_USER_* error constants are used for reporting your own custom errors when using trigger_error. Again anything to do with errors and how to handle them is explained in the manual which gristoi linked to.

The E_USER_* error constants are used for reporting your own custom errors when using trigger_error. Again anything to do with errors and how to handle them is explained in the manual which gristoi linked to.

 

What I don't understand is which constant I am supposed to use, and when. It doesn't tell you in the manual.

 

I don't want my scripts to die and present half a page to users, so I know that I shouldn't use E_USER_ERROR.

 

What, then, should I use if mysql_connect(), mysql_select_db() or mysql_query() fail? Should I use E_USER_WARNING, or should I leave the default E_USER_NOTICE? Does it really matter?

 

For example, should I do this for MySQL queries?

$query = mysql_query("Some query");

if(!$query) {
     echo "Message to user.";
     trigger_error("Error!", E_USER_WARNING); // Message to be logged
}

Sorry I meant to say display_errors is off. If error_reporting is off then no errors will be logged.

Even when "display_errors" is on, errors will still be logged.

 

What I don't understand is which constant I am supposed to use, and when. It doesn't tell you in the manual.

It depends on the environment you're in Fluoresce. In a development or testing environment, you will want to log as much as possible to help with debugging. It's up to you if you have "display_errors" enabled or not, but personally I prefer to have them all logged into a file and tailf it so I can monitor them.

 

As for the constants, you don't generally want anything in the production logs except stuff you really need to know about. During dev/testing you should clear the less important notices out before even releasing, so you should be okay with:

 

// Report simple running errors
error_reporting(E_ERROR | E_WARNING | E_PARSE);
As for development, you want absolutely everything reported, so you want:

 

// Report all PHP errors
error_reporting(-1);
You shouldn't really ever be getting E_USER_* errors in production. Edited by Adam

What I don't understand is which constant I am supposed to use, and when. It doesn't tell you in the manual.

You use whichever one you feel is appropriate for the situation. For example if the error is minor and doesn't cause any real problems (or not really an error, but inefficient or something) then E_USER_NOTICE would be appropriate.

 

E_USER_WARNING would be for more serious errors that will prevent something from working properly, but is not bad enough to necessitate killing the script. For example if the DB connect fails, then you can't run any queries. The script itself could continue and handle the error by skipping the DB queries or generating an error page.

 

E_USER_ERROR would be for something that is a legit show stopper and the script cannot possibly continue. Something on this level would probably be rare in the user context. I can't think of any particular example where one might use E_USER_ERROR.

 

Note that trigger_error is not a replacement for proper checking of return values. It's just a convenient way to log a message when an error occurs. If you're trying to call mysqli_connect and it fails for instance, you'd still check the return value such as:

$conn = mysqli_connect(...) or trigger_error('Failed to connect to MySQL', E_USER_WARNING);
if (!$conn){
   //abort or return or whatever to handle it
}
Edited by kicken

Here are the php.ini settings for my production site:

error_reporting = E_ALL
display_errors = Off
log_errors = On
error_log = error_log

I've just done a bit of newbie experimentation.  An error is logged if mysql_connect() fails even without trigger_error().

 

In other words, for logging, the trigger_error() part of the following code is not necessary.

$conn = mysqli_connect(...) or trigger_error('Failed to connect to MySQL', E_USER_WARNING);

If you use the code above, two warnings will be logged, one by the system and one by your use of trigger_error(). 

 

Am I mistaken?

 

I guess this means that trigger_error() is to be used when errors aren't automatically thrown, and whatever error constant you use depends on what you think is appropriate.

 

Is that correct?

I guess this means that trigger_error() is to be used when errors aren't automatically thrown, and whatever error constant you use depends on what you think is appropriate.

 

Is that correct?

Correct. I wouldn't ever trigger another error in that situation because you know one has already been triggered. I don't really agree with the PHP docs for having that example. As I edited my last post to say, you shouldn't ever really be encountering user triggered errors in your production environment, because they imply bad configuration, bad connection or something dev wise has not gone right. PHP will automatically trigger warnings appropriately and bomb out in most situations though. Nothing should make it to a production environment if it's triggering user errors.

Okay, I'm confused now. I don't know how I should be handling possible future mysql_connect() errors.

 

Here's what I've just discovered ...

 

If I use the following code and the connection fails, the user is presented with a MySQL error message (even though display_errors is turned off), the script dies (so the user only gets half a page), and 4 warnings are logged (1 for the failure to connect, 2 for the failure to select the database, and 1 for the failure of the MySQL query).

$con = mysql_connect("localhost", "", "");
// Rest of code

On the other hand, if I use the following code and the connection fails, the user is presented with a custom message, the script doesn't die (so the user gets a full page), and 1 warning is logged (for the failure to connect).

$conn = mysql_connect("localhost", "", "");
if(!$conn) {
     echo "<p>Custom error message for user.</p>";
}
else {
     // Rest of code
}

I haven't had to use trigger_error() at all.

 

Is that the best way to deal with possible future connection failures? I ask because even the PHPFreaks website says to use this:

mysql_connect("localhost", "", "") or trigger_error("Connection failed! " . mysql_error());
// Rest of code

If the second bit of code is the best way to deal with future connection problems, my question is, should I use the same if/else logic for mysql_select_db() and mysql_query() as well?  Wouldn't my scripts then be packed with if/else conditionals?

 

And is it all even necessary? What's the chance that the connection, database selection or query will fail?

Edited by Fluoresce

trigger_error is just use to help log errors. It has nothing to do with handling them. Also, as mentioned for things where PHP already provides error messages like on failure of mysql_connect, it is entirely unnecessary. Where you might use it is in your own classes or functions to provide error reporting when necessary. For example, I've made a few classes before that use cURL to download a file then parse the contents. I used trigger_error to report things like the cURL download failing or the reason why parsing the file contents failed.

 

Whether you use trigger_error at all or not though, you still need to make sure your code can handle such errors by checking the functions return value and acting accordingly. As for the chances of something like mysql_connect or mysql_query failing, it's > 0% so you need to handle it. In an ideal world these operations would never fail, but the world is far from perfect. Network problems, file corruption, hardware failures, etc all can cause these to fail at any time.

Good stuff!

 

Okay, here's what I want to do.

 

If a MySQL connection or query fails in the future, I want a user-friendly message to be presented to the user, a log to be made of the error, and an e-mail to be sent to me.

 

Here are my php.ini settings:

error_reporting = E_ALL
display_errors = Off
log_errors = On
error_log = [nameoffile]

Here's what I've got so far:

// Prepare headers for e-mail
$headers = "From: help@mysite.com\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
// Connect to MySQL
$con = mysql_connect("", "", "");
if(!$con) {
     echo "<p>User-friendly message for user.</p>";
     error_log("MySQL connection failed! Date: " . date("l jS \of F, Y, h:i:s A") . ". File: " . $_SERVER['REQUEST_URI'], 1, "personaladdress@whatever.com", $headers);
}
else {
    // Rest of code
}

The code works. The user-friendly message is presented to the user, a log is made of the error, and an e-mail is sent to me specifying the data and time of the error and the file in which the error occurred.

 

Does it look okay to you guys?  How would you do it?

  • Solution

Make a function, that calls error_log so you don't have to define the email headers each time you want to log an error.

// define custom error logging function
function my_error_log($error_txt) 
{
	// Prepare headers for e-mail
	$headers = "From: help@mysite.com\r\n";
	$headers .= "MIME-Version: 1.0\r\n";
	$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";

	// append error information to error message
	$error_text .= " Date: " . date("l jS \of F, Y, h:i:s A") . ". File: " . $_SERVER['REQUEST_URI'];

	// call error_log function
	error_log($error_text, 1, "personaladdress@whatever.com", $headers);	
}

// Connect to MySQL
$con = mysql_connect("", "", "");
if(!$con) {
     echo "<p>User-friendly message for user.</p>";
     // call custom error log function
     my_error_log("MySQL connection failed!"); // jsut pass in the error message
}
else {
    // Rest of code
}
Edited by Ch0cu3r

 

Make a function, that calls error_log so you don't have to define the email headers each time you want to log an error.

// define custom error logging function
function my_error_log($error_txt) 
{
	// Prepare headers for e-mail
	$headers = "From: help@mysite.com\r\n";
	$headers .= "MIME-Version: 1.0\r\n";
	$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";

	// append error information to error message
	$error_text .= " Date: " . date("l jS \of F, Y, h:i:s A") . ". File: " . $_SERVER['REQUEST_URI'];

	// call error_log function
	error_log($error_text, 1, "personaladdress@whatever.com", $headers);	
}

// Connect to MySQL
$con = mysql_connect("", "", "");
if(!$con) {
     echo "<p>User-friendly message for user.</p>";
     // call custom error log function
     my_error_log("MySQL connection failed!"); // jsut pass in the error message
}
else {
    // Rest of code
}

 

 

Thanks, but it's not working:

PHP Notice:  Undefined variable: error_text in ...

The email is sent, but the string (error message) that I enter into my_error_log() doesn't appear in the email.

 

I tried putting $error_text = ''; both inside and outside the function. Although the notice goes away when I try it inside the function, the error message that I enter into my_error_log() still doesn't appear in the email.

Edited by Fluoresce
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.