开发者

How do you keep debug code out of production?

It happens to the best of us.

How do you keep debug code out of production?

Particularly when dealing with languages without built in debugging capabilities such as breakpoints and watched variables, these bugs bite developers. Debugging code, alerts and Response.Writes, show up in production code.

How do you separate debugging concerns from functional code in javascr开发者_开发问答ipt, php, or vbscript? How do you ensure those debugging changes never enter production environments?


The most simple method

define("DEBUG", true);


if (DEBUG) {
    echo "Debug Method";
}

For js its similar.


Human error is hard to prevent

https://meta.stackexchange.com/questions/71780/lol-debugging-are-we-so-homepage-alerts-false


It may not be perfect but I have a macro in my editor that allows me to add debug and wraps it in appropriate flagging comments. I also have a script that I run later that rips that stuff back out. Granted, it took me a while to really trust this mechanism but over time I've become comfortable with it.

My preference is avoid ever checking in debug code. Obviously as with any other 'rule' there are exceptions to this, but because it's easy to miss things later, I don't like checking it in.


One method is with an environmental variable. In your server configuration, you could set an environmental variable to say debug or not. The production servers would be configured to false, and the development to true. That way all you do in the code is check the environmental variable:

In PHP:

if (getenv('DEBUG_MODE')) {
    var_dump($foo);
}

That way, there's no way to forget, since it'll automatically turn itself off. But if you REALLY need to turn it on in production, just flip the switch...

  • Docs for Apache
  • Docs for Lighttpd
  • Docs for NginX


There are several ways to hide debug code in production, but few to remove it (when a compiler cannot automatically remove it).

I hide debug code by:

  • Only displaying it when the logged in user is a developer or tester.
  • Outputting it to a log/database when server side.

I remove it by searching for special comments before deployment:

  • alert("false") //TODO:REMOVE DEBUG CODE

My coworkers also suggested:

  • Overriding alert to check for a debug variable. (Side effects?)
  • Writing a alertDebug method to check for a debug variable. (Will anyone remember it?)
  • Checking to see if firebug was running

    if(window.console && window.console.firebug) { alert("you are using firebug"); }


It tends to happen less if you utilize language features which are designated for debugging purposes:

 assert( is_string($param1) );

Does not hurt production code.


As the most poular answer has a security flaw, let me include a less risky version from php.net.

define ('DEBUG', 1);
if (DEBUG == 1) {
   // echo some sensitive data.
}

The basics are the same, but this one won't execute debug code if the constant DEBUG is undeclared.

The problem with if (DEBUG) is that if the constant is not defined it will assume the string "DEBUG" which evaluates to true.


If its only "avoid debugs in production" then use the built in assert() function.

This avoids your debug messages from being processed at all and prevents any calculations you might have in there from consuming memory or processing power.

assert is completely ignored in production.

function debug(...$stuff){
    var_dump($stuff);
    return true; //always return true so assert will always pass it.
}
assert(debug("This code will not even be processed on production server. "));

That's the safest way but not very flexible.

One method I have been using a lot is to check the host name or the client IP address.

So I have a function to check the host name like this:

function onTestServer(){
    $SERVER_NAME = $_SERVER["SERVER_NAME"];

    if(substr($SERVER_NAME,-5)==="te.st") return true;//all *.te.st domains are test servers
    if (strpos($SERVER_NAME, ".localhost")!==false) return true; //all *.localhost domains are test servers
    return false;
}

And then I have my own vardump, debug and die statements that wont execute in production similar to this:

function varDump($stuff){
    if (!onTestServer()) return;
    echo "<pre>";
    var_dump($stuff);
    echo "</pre>";
}

Then you just only ever use the custom varDump() function so only you can see it.

My debug functions are a lot more complicated and show expandable trees of information etc. But the basic principle is the same. if on localhost do the vardumps etc otherwise nothing is displayed.

Really handy if you always want to see extra info when testing but dont want to have to remove all the vardumps before deploying to the server.

I also do things like check the client IP address and display errors and info on the actual production server as well if the client ip address is my own.

function getIp()
{
    if (!empty($_SERVER['HTTP_CLIENT_IP']))   //check ip from share internet
    {
        $ip=$_SERVER['HTTP_CLIENT_IP'];
    }
    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))   //to check ip is pass from proxy
    {
        $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    else
    {
        $ip=$_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}

function onTestClient(){
    $office_ip = "xxxx.xxxx.xxxx.xxxx";
    $test_client_ips = array($office_ip,"any other ip you want");
    $client_ip = getIp();
    if (in_array($client_ip,$test_client_ips)) return true;
    return false;
}

Can be extremely handy if you need to test some quick updates on a live site from a handy computer without local testing environment to use. Can just add your current IP to the list and use functions like this one:

function die_dev($message){
    if (onTestServer() || onTestClient()) die($message);
}

Or even:

if (onTestClient()){
    //show a completely different interface/webpage html js etc
} else {
    //show the original content that is currently live
}


Code reviews. Generally when someone looks over the code this sort of thing really sticks out.


Here we have multiple stages of testing before code ever reaches production. Different groups of testers at each stage with different goals. Seems to work so far (we've never had debug code like this get out to production).

I was going to say "code reviews" but everyone else already said that, and I'm not sure it would have caught something like this...


what i do is in php

define ("DEBUG", true);


function op (){
    if ( !DEBUG ) return true;

    $args = func_get_args();

    foreach ( $args as $var ){
        if ( is_object ( $var ) or is_array ( $var ) ){
            print "<br /><pre>";
            print_r ( $var );
            print "</pre>";

        }
        else{
            print "<br />" . $var;
        }
    }

        return true;
}

// On places to check 
op ($array, $var);

In js also i will do the same like

function calert(message){
    if (!debug) return;
    alert (message);
}


Are you working on production server directly? Do you ever heard of staging server or test server? You can use your own computer to became your stage server-- use microsoft web matrix! Make your code clean and working perfectly there and then move to production.

There is no other good way to make sure that debugging code pop up on production server--QA before production


I follow three rules for debug code

Make the source code look awful, by...

 not indenting it from the left margin

 egregiously violating the coding standard

 putting in extra whitespace above and below

Set up a global debug switch, and

 have it alter an obvious output if it is ON, and

 make the debug code compilation depend on that switch being ON (i.e., so the code won't compile if the global switch is OFF)

Sabotage an obvious output, such as by:

 delete something really important

 put up 99/99/99, for the date

 comment out the "File Load" function

 delaying the splash-screen

 etc.

These three rules have worked well for me.


I am only going to mention this, since nobody has gone there.

If you don't write any debug code, then debug code won't make it to production.

If you are writing "debug code", it suggests that you don't actually understand your code well. Maybe it is too complex.

Write your unit tests first. That practice will lead to better design. Make sure you have complete code coverage. Test the cases that are hard to make happen - can't get a socket connection, database is not available, etc. Write regression tests. Do not deploy anything that can't pass them. Any bug report should be turned into a regression test before the code is changed. The regression test should fail - and be the only test that fails. Fix the bug.

Automate the compilation and testing. If you actually write debug code, it should be removed immediately after testing is successful. When your organization is really mature, perhaps you will even automate deployment.


My recommended way of debugging PHP code even in production mode.

  1. Sign up for free and create an app at http://todell.com/debug

  2. Debug your php code like this

    define("DEBUG_LVL",1); /*place this anywhere convenient to edit or on a single file that was included in your entire web application. */

    if(DEBUG_LVL > 0) file_get_contents("http://todell.com/w/y///".urlencode(json_encode($object))."/".LINE."/".urlencode(FILE)."/".$_SERVER["REMOTE_ADDR"]);

Where $object is the object you want to send to your debug app. it can be anything from exception thrown from your code or a benchmarking data. The $object size limit is 64KB This is not limited for PHP language only.


Developer diligence and good testers are all that stands in the way, really. There's no single tool or process that can prevent such things from happening.

If anything, it's a prime example of why it's critical to have a non-painful build/deploy process. Bad things will make it to Production. Guaranteed. The real question isn't how to prevent it, but how to respond to it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜