Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

Zend Framework: Zend_Log Component Proposal

Proposed Component Name Zend_Log
Developer Notes http://framework.zend.com/wiki/display/ZFDEV/Zend_Log
Proposers Art Hundiak
Revision 1.1 - 27 June 2006: Initial Proposal. (wiki revision: 5)

Table of Contents

1. Overview

It is proposed that the existing static Zend_Log class be changed into a fully dynamic logging class. This proposal is being submitted based on some of the traffic on the mailing list as well as some off line conversations.

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

For many applications the need for a logging class is self evident. The existing static Zend_Log class covers this need rather nicely but suffers from the usual static class limitations i.e. it is difficult to add functionality and can be difficult to use in a testing enviroment.

4. Dependencies on Other Framework Components

Pretty much the same as the existing Zend_Log class.

5. Theory of Operation

In most cases the log class would be accessed via the registry. I would suggest having static getInstance(),setInstance(),hasInstance() methods to allow low level code access to one instance of the logging class without the need to go through the registry.

6. Milestones / Tasks

zone: Missing {zone-data:milestones}

7. Class Index

  • Zend_Log
  • Zend_Log_Interface
  • Zend_Log_Exception
  • Zend_Log_Adapter (existing adapter classes)

8. Use Cases

9. Class Skeletons

I'm not going to propose skeleton details until I see how the proposal is received. I think the existing class covers most of the standard required functionality so it's basically a question of refactoring the code to remove the statics and maybe adding a params array to the constructor. If someone else has strong opinions on what the class needs then I'm more than willing to either work with them or to turn the entire proposal over to them.

]]></ac:plain-text-body></ac:macro>

]]></ac:plain-text-body></ac:macro>

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jun 27, 2006

    <p>I don't know that this is necessary. In what circumstance would you <em>really</em> need to inject a new log object in a unit test? Also, I don't see what's preventing Zend_Log from being extended. Can you give an example of something you are currently prevented from doing?</p>

    <p>Aside from that, what's the point of registering the logger in the use case? Better to do this:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    // Initializing
    $registry->log = new Zend_Log(new Zend_Log_Adapter_File("log.txt"));

    // In an action
    $registry->log->log("A message");
    ]]></ac:plain-text-body></ac:macro>

    <p>Although I want to reiterate that I think the current implementation is fine.</p>

    1. Jun 27, 2006

      <p>I suppose in theory that it's possible to extend Zend_Log but the fact that most of the methods are static means that you could not override any of them without changing your user code to reflect the extended class name i.e. instead of using Zend_Log::log() you would need to use Zend_Log_Extended::log(). Requiring your user code to be changed just because you use a different log class is not a good thing.</p>

      <p>Some folks on the email list have pointed out that you can create multiple Zend_Log instances which again is true but they all have to be stored inside of a master log instance. So I can't simply do <br />
      $log1->log();<br />
      $log2->log();</p>

      <p>I would need to name the different instances when creating them and then pass the name into the log method. Just don't see the point. I'm all in favor of having a single log object be able to write to multiple adapters but I also want to be able to have more than one log instance and I want to be able to extend it if I need to. Not unreasonable requests from my point of view.</p>

      1. Jun 28, 2006

        <p>Again, if you could cite specific things that you would like to do that you currently can't...</p>

      2. Jun 28, 2006

        <p>Edit: I mean, specific functionality, not a certain programming style or implementation.</p>

  2. Jun 27, 2006

    <p>Current implementation is very awkward to use if you wish to log to couple of adapters at once.</p>

  3. Jun 28, 2006

    <p>The 'static classes are bad' argument has been hashed to death on the mailing list. I don't think that turning Zend_Log into an instantiable class is really going to benefit most users.</p>

    <p>That said, if there are specific limitations in Zend_Log that are affecting you (such as logging to multiple adapters as Michael mentions above), let's talk about them instead. I bet that any behavior you would add in a subclass would be useful to the community at large anyway.</p>

    <p>I would much rather see Zend_Log evolve into a full-fledged log4j clone, which would bring a consistent and familiar API, plus offer a wider array of extension points that should address most, if not all, of the customization concerns: <a class="external-link" href="http://logging.apache.org/">http://logging.apache.org/</a></p>

    1. Jun 28, 2006

      <p>I also would like to see Zend_Log going towards log4j-like functionality.</p>

    2. Jun 30, 2006

      <p>To make Zend_Log a log4j-clone ( log4ZFW <ac:emoticon ac:name="smile" /> ) would be a great deal as log4x is todays standard for logging issues.</p>

      <p>When we do it this way, we would have a standard implemented which rocks.</p>

  4. Sep 22, 2006

    <p>I'm convinced that morphing Zend_Log into a log4j clone is the best solution. There is no need to be able to instantiate Zend_Log as long as there is an easy way to configure multiple individual loggers whose output can be directed to multiple locations. I believe this is part of what Art was asking for initially.</p>

    <p>Gavin's suggestion that this may be impractical for ZF 1.0 makes sense. To that end, I suggest we focus on resolving API conflicts that will make such a migration difficult or impossible in the future. I think it would be rather confusing to have two different logging modules in a 2.0 release (Zend_Log, Zend_Log4ZFW), especially if the APIs are dissimilar.</p>

    <p>Here is what I propose then for 0.2:</p>

    <ul>
    <li>Resolve ZF-32 by always having a default logger which uses the Null adapter. This is consistent with log4j, where you can always safely call the log() method.</li>
    <li>Mark ZF-270 as "Won't fix": The original problem report can be satisfied with a logger configured with multiple appenders, which is possible in log4j. Most every other time you'd want to log to multiple loggers will be solved by logger inheritance.</li>
    <li>Defer ZF-281 to 2.0, when the log4j-based implementation will allow you to define your own custom layouts.</li>
    <li>Implement the convenience methods debug(), info(), warning(), error(), and severe(), as well as isDebugEnabled() et al. as requested in ZF-282. We should not implement enableLogLevel() or disableLogLevel() though, since the log level is defined as a threshold, not a bitfield.</li>
    </ul>

    <p>I believe we should also take advantage of this prerelease to make one final backwards-incompatible API change by changing the parameter order of the logging methods from this:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    public static function log($message, $level = self::LEVEL_DEBUG, $logName_or_fields = null, $logName = null)
    ]]></ac:plain-text-body></ac:macro>

    <p>to this:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    public static function log($level, $message, $logName = null, $logName_or_fields = null)
    ]]></ac:plain-text-body></ac:macro>

    <p>log4j and most other logging components always require an explicit log level for the message. This forces the developer to think about the intended scope of the message. It also makes the log level parameters useful: if the log level is an optional parameter, and everything is always a debug message (as it is now), you might as well not have a configurable level as it is unlikely to get used consistently.</p>

    <p>This is the only really difficult API change on the path to log4j. I believe that from here, we could perform a forklift update on Zend_Log with little to no impact on end-user code. Even if we didn't and we added a second logging module, for consistency with other log4j clones, the parameter order would be level then message. This could lead to all kinds of confusion for end-users when the parameter order in the two logging modules is different.</p>

    <p>Finally, to ease a future transition, we should make sure that any other improvements we consider for 1.0 have an analog in log4j.</p>