Jump to content


Photo

Trying to Understand Error Logging

error log log errors display errors trigger error

Best Answer Ch0cu3r, 23 October 2013 - 09:24 AM

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
}
Go to the full post


  • Please log in to reply
16 replies to this topic

#1 Fluoresce

Fluoresce

    Advanced Member

  • Members
  • PipPipPip
  • 261 posts
  • LocationLondinium

Posted 22 October 2013 - 06:46 AM

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?
 



#2 gristoi

gristoi

    Advanced Member

  • Members
  • PipPipPip
  • 837 posts

Posted 22 October 2013 - 06:59 AM

this should help you on the subject:

http://php.net/manua...k.errorfunc.php


To err is human... to really foul up requires the root password

#3 Ch0cu3r

Ch0cu3r

    Advanced Member

  • Moderators
  • 2,247 posts

Posted 22 October 2013 - 07:11 AM

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



#4 Fluoresce

Fluoresce

    Advanced Member

  • Members
  • PipPipPip
  • 261 posts
  • LocationLondinium

Posted 22 October 2013 - 08:29 AM

this should help you on the subject:

http://php.net/manua...k.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?



#5 Ch0cu3r

Ch0cu3r

    Advanced Member

  • Moderators
  • 2,247 posts

Posted 22 October 2013 - 10:29 AM

 

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.



#6 Fluoresce

Fluoresce

    Advanced Member

  • Members
  • PipPipPip
  • 261 posts
  • LocationLondinium

Posted 22 October 2013 - 05:37 PM

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
}


#7 Adam

Adam

    Advanced Member

  • Gurus
  • 5,686 posts
  • LocationSheffield / UK

Posted 22 October 2013 - 06:25 PM

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, 22 October 2013 - 06:27 PM.


#8 kicken

kicken

    Wiser? Not exactly.

  • Gurus
  • 2,707 posts
  • LocationBonita, FL

Posted 22 October 2013 - 06:34 PM

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, 22 October 2013 - 06:39 PM.

Recycle your old CD's, don't trash them!
Did I help you out?  Feeling generous? I accept tips via Paypal or Bitcoin @ 14mDxaob8Jgdg52scDbvf3uaeR61tB2yC7

#9 Fluoresce

Fluoresce

    Advanced Member

  • Members
  • PipPipPip
  • 261 posts
  • LocationLondinium

Posted 22 October 2013 - 07:03 PM

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?



#10 Adam

Adam

    Advanced Member

  • Gurus
  • 5,686 posts
  • LocationSheffield / UK

Posted 22 October 2013 - 07:15 PM

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.

#11 Fluoresce

Fluoresce

    Advanced Member

  • Members
  • PipPipPip
  • 261 posts
  • LocationLondinium

Posted 22 October 2013 - 09:11 PM

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, 22 October 2013 - 09:16 PM.


#12 kicken

kicken

    Wiser? Not exactly.

  • Gurus
  • 2,707 posts
  • LocationBonita, FL

Posted 22 October 2013 - 10:18 PM

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.
Recycle your old CD's, don't trash them!
Did I help you out?  Feeling generous? I accept tips via Paypal or Bitcoin @ 14mDxaob8Jgdg52scDbvf3uaeR61tB2yC7

#13 Fluoresce

Fluoresce

    Advanced Member

  • Members
  • PipPipPip
  • 261 posts
  • LocationLondinium

Posted 23 October 2013 - 08:05 AM

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?



#14 Ch0cu3r

Ch0cu3r

    Advanced Member

  • Moderators
  • 2,247 posts

Posted 23 October 2013 - 09:24 AM   Best Answer

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, 23 October 2013 - 09:25 AM.


#15 Fluoresce

Fluoresce

    Advanced Member

  • Members
  • PipPipPip
  • 261 posts
  • LocationLondinium

Posted 23 October 2013 - 10:26 AM

 

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, 23 October 2013 - 10:34 AM.


#16 Ch0cu3r

Ch0cu3r

    Advanced Member

  • Moderators
  • 2,247 posts

Posted 23 October 2013 - 10:41 AM

Sorry, I left the letter e out of error_text, the  line below

 

function my_error_log($error_txt)

 

should be 

 

function my_error_log($error_text)


Edited by Ch0cu3r, 23 October 2013 - 10:42 AM.


#17 Fluoresce

Fluoresce

    Advanced Member

  • Members
  • PipPipPip
  • 261 posts
  • LocationLondinium

Posted 23 October 2013 - 10:49 AM

Sorry, I left the letter e out of error_text, the  line below

 

function my_error_log($error_txt)

 

should be 

 

function my_error_log($error_text)

 

Nice eyes, man!

 

Working perfectly now. :happy-04:






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Cheap Linux VPS from $5
SSD Storage, 30 day Guarantee
1 TB of BW, 100% Network Uptime

AlphaBit.com