ZF-3464: setEventItem calls passed function immediately

Description

The ->setEventItem() method calls the passed function reference immediately and sets the value straight away. i.e. it binds the value before a log message is even sent. This may be the intended functionality or it may not but it makes it unuseable in a dynamic environment. Consider this scenario:

You want to set up logging for an application and want to log the user id of the logged on user. You can't do this if your authentication service is not yet running or if the user hasn't yet logged on. Binding the value this early on will not allow you to log the actual user id. Thus the following code fails:

self::$_logHandler[$tag]->setEventItem('uid',$this->getUid()); $format = '%uid%|%timestamp%|%priorityName%|%priority%|%message%' . PHP_EOL; $formatter = new Zend_Log_Formatter_Simple($format); $writer->setFormatter($formatter);

because getUid relies on a service (based on Zend_Auth) that, although instantiated hasn't be called yet to set up authentication and therefore fails.

It therefore makes more sense to implement the setEventItem function parameter as a call back function, that is called when the log message is created.

I amended setEventItem as follows to achieve the desired effect

public function setEventItem($name, $value) {
    if (isset($this->_extras[$name])) {
        $this->_extras[$name] = $value;
    } else {
        $this->_extras = array_merge($this->_extras, array($name => $value));
    }
}

This allows you to call the method after setting up the writer with a new new value i.e.

self::$_logHandler[ZWARE_LOG_APP]->setEventItem('uid',$this->getUid()); $this->log(ZWARE_LOG_APP,$message,$priority);

Comments

Honestly, I just confused with what the proposal is here. It seems like you're talking about deferred execution of getUid(), but neither the original code snippet nor your proposed change would do this. The reason is simple: for method invocations, the arguments are evaluated before the method is called. Please let me know if I'm missing something here, and, if so, reopen the bug.

Waiting for further information from reporter. Resolving issue for now as there is a simple workaround for what the reporter seems to be trying to do.

Will. It's been so long since I opened this one I've almost forgotten what it was about and have overwritten my patch to Zend with latre revisions of the framework.

What I am trying to achieve is late binding of the value that goes into the item.

As previously stated setEventItem needs to be rewritten to allow the value to be passed as the name of a callback function which will provide the value when the logger is actually invoked with a call to log() The workaround I have shown is exactly that, a workaround. It would be more elegant to have a callback facility and that will require rework to teh log() method as well as setEventItem().

If not, my workaround still needs to be incorporated into the Zend library. (Zend/Log.php line 219 public function setEventItem() declaration) else its a patch that has to be applied every time the ZF library gets updated.

Unless of course you have a better way :-)

So I think you either reopen this issue and get it incorporated into the build or state why it shouldn't be done.