logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gary Gregory <garydgreg...@gmail.com>
Subject Re: Enums and Custom Levels
Date Sun, 26 Jan 2014 04:43:54 GMT
My idea was _not_ to add byte codes to the Logger interface, it was to add code to a user's
class that wraps a logger. 


-------- Original message --------
From: Remko Popma <remko.popma@gmail.com> 
Date:01/25/2014  21:51  (GMT-05:00) 
To: Log4J Developers List <log4j-dev@logging.apache.org> 
Subject: Re: Enums and Custom Levels 

I've started to think about how to implement Gary's idea to use these custom levels to generate
code that would add methods to the Logger interface, but I think I'll wait a little to see
what form the custom levels take.

On Sun, Jan 26, 2014 at 11:45 AM, Remko Popma <remko.popma@gmail.com> wrote:
These are the switches I found:
* log4j-1.2-api: org.apache.log4j.Category - just FYI, it looks like this switch is missing
the FATAL level... is this a bug?
* log4j-api: org.apache.logging.log4j.status.StatusLogger
* log4j-core: org.apache.logging.log4j.core.net.Severity
* log4j-core: org.apache.logging.log4j.core.pattern.LevelPatternConverter - perhaps just return
"level " + level.toString(); ?
* log4j-to-slf4j: org.apache.logging.slf4j.SLF4JLogger

On Sun, Jan 26, 2014 at 11:41 AM, Ralph Goers <ralph.goers@dslextreme.com> wrote:
I am not sure what you mean by this.  I have already succeeded in adding custom level names
to the configuration and making them be valid.  I am just trying to clean it up a bit based
on what Nick is suggesting.


On Jan 25, 2014, at 6:30 PM, Scott Deboy <scott.deboy@gmail.com> wrote:

There's no way to add support for users to define level entries (name and value pairs as a
new element in the config) and have us do the work to make those valid? That would get get
rid of my request for additional levels, right?

On Jan 25, 2014 6:15 PM, "Ralph Goers" <ralph.goers@dslextreme.com> wrote:
The class is needed because it is a name and a value (two items) that has to be represented
as a single parameter to Logger methods.  Using raw int or String is not a good alternative.


On Jan 25, 2014, at 4:54 PM, Scott Deboy <scott.deboy@gmail.com> wrote:

If levels are just a name and a value why require a class at all? What about just having it
defined in the configuration.

On Jan 25, 2014 4:37 PM, "Ralph Goers" <ralph.goers@dslextreme.com> wrote:
Because we don’t know the class name that the Level belongs to.  It is referenced in the
configuration just as “DIAG”, not “org.apache.logging.test.ExtendedLevel.DIAG”.

In any case I fixed it.  I just annotated the new Level as a Plugin and then look up all
the Level plugins in BaseConfiguration. Simply calling the getEnumConstants method on each
of the classes does the trick.


On Jan 25, 2014, at 4:26 PM, Paul Benedict <pbenedict@apache.org> wrote:

If you made it a requirement for the constructor to register, why not just instantiate each
level as you encounter it in the config?

On Sat, Jan 25, 2014 at 6:06 PM, Ralph Goers <ralph.goers@dslextreme.com> wrote:
Hmm. It seems I am going to have to do something to force the registration as the custom level
class hasn’t been constructed before the levels are referenced in the configuration. 


On Jan 25, 2014, at 3:43 PM, Ralph Goers <ralph.goers@dslextreme.com> wrote:

In the constructor each of them calls Levels.addLevel(this).


On Jan 25, 2014, at 2:21 PM, Remko Popma <remko.popma@gmail.com> wrote:

Interesting! So, users would add custom levels by creating a new enum that implements the
Level interface? How does the new enum get registered? In config or in code?

Just trying to understand how it works...

(With Nick's class I understood how that would work: users would extend the Level class and
pass an instance of that class to the Logger.log() methods; in config they could specify the
new Level name, and the Level.toLevel(String, Level) method would find the custom instance
in a static HashMap in the Level superclass.)

On Sunday, January 26, 2014, Ralph Goers <ralph.goers@dslextreme.com> wrote:
Here is what I am implementing:

1. Level is now an Interface. This allows the vast amount of code to continue to work.
2. The current Level enum has been renamed to StdLevel. It implements the Level interface.
3. A new class named Levels is in the spi package of the API. It contains a ConcurrentMap
containing all the registered Levels as well as the static methods that were previously part
of the Level enum.

For the most part the conversion to this has been pretty easy. The most frustrating part was
that I had to move the toLevel methods from what was the Level enum to the Levels class as
static methods are not allowed in interfaces until Java 8. This meant I had to modify several
classes to use Levels.toLevel instead of Level.toLevel. In addition, a few classes were using
the valueOf enum method. Those were converted to use Levels.getLevel.

The few places were Level is actually used as an enum were also pretty easy to handle as in
those cases the custom levels need to be converted to a StdLevel and then that enum is used.

Unless anyone objects I plan on committing this later today once I finish it and create some
tests and documentation.


On Jan 25, 2014, at 12:49 PM, Nicholas Williams <nicholas@nicholaswilliams.net> wrote:

No, of course, everyone seems to agree that custom levels should be permitted. But I never
heard agreement on whether we were going the extensible enum route or the Level-as-interface
route. The camp still seemed to disagree on that.


Sent from my iPhone, so please forgive brief replies and frequent typos

On Jan 25, 2014, at 11:20, Ralph Goers <ralph.goers@dslextreme.com> wrote:

I have not heard anyone disagree with allowing custom Levels. The disagreement I am hearing
is over adding new pre-defined levels.


On Jan 25, 2014, at 7:29 AM, Nick Williams <nicholas@nicholaswilliams.net> wrote:

I may have missed something. Did we decide on an approach? Last I heard, the camp was still
split: Some wanted to go with my extensible enum, others wanted to change Level to an interface
and make a Levels enum.

So I'm a bit confused. Which implementation are you working on?


On Jan 25, 2014, at 7:08 AM, Ralph Goers wrote:

I am working on the implementation of custom levels now. I should have it done today.


On Jan 24, 2014, at 7:07 PM, Remko Popma <remko.popma@gmail.com> wrote:

What is the best way to make progress on the custom levels implementation?

Do we re-open LOG4J-41 or start a fresh Jira ticket? For implementation ideas, do we attach
files to Jira, or create a branch?


On Saturday, January 25, 2014, Gary Gregory <garydgregory@gmail.com> wrote:
On Fri, Jan 24, 2014 at 11:48 AM, Remko Popma <remko.popma@gmail.com> wrote:

The hard-coded levels were proposed because it seemed that the extensible enum idea raised
by Nick was not going to be accepted.
My original position was that Markers could fulfill the requirement but Nick and yourself
made it clear that this was not satisfactory.

With extensible enums and markers off the table it seemed that the hard-coded levels was the
only alternative, and discussion ensued about what these levels should be called and what
strength they should have.

During this discussion, several people, including me, repeatedly expressed strong reservations
about adding pre-defined levels, but by this time I think people were thinking there was no

It looked like we were getting stuck, with half the group moving in one direction ("add pre-defined
levels!") and the other half wanting to move in another direction ("don't add pre-defined
levels!"). I asked that we re-reviewed our assumptions and try to reach a solution that would
satisfy all users.

We then decided to explore the option of using extensible enums again. This is still ongoing,
but I haven't seen anyone arguing against this idea since we started this thread.

Hard-coded levels and the extensible enum are different solutions to the same problem.

Hello All:

Absolutely not. See my DEFCON example.
Talking about an "extensible enum" is mixing design and implementation, we are talking about
'custom' and/or 'extensible' levels.
Custom/Extensible levels can be designed to serve one or all of:

- Allow inserting custom levels between built-in levels.
- Allow for domain specific levels outside of the concept of built-in levels, the DEFCON example.
- Should the custom levels themselves be extensible?



View raw message