Re: Enums and Custom Levels - completed.
I'm very curious! Can't wait to see it. Go for it! On Sunday, January 26, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name=“” category=“Level”) for them to be usable during configuration. Are their any objections to me checking this in? I’ll be doing the commit at around noon Pacific Daylight Time if I don’t hear any. Ralph On Jan 25, 2014, at 7:08 AM, Ralph Goers ralph.go...@dslextreme.comjavascript:_e({}, 'cvml', 'ralph.go...@dslextreme.com'); wrote: I am working on the implementation of custom levels now. I should have it done today. Ralph On Jan 24, 2014, at 7:07 PM, Remko Popma remko.po...@gmail.comjavascript:_e({}, 'cvml', 'remko.po...@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? Remko On Saturday, January 25, 2014, Gary Gregory garydgreg...@gmail.com wrote: On Fri, Jan 24, 2014 at 11:48 AM, Remko Popma remko.po...@gmail.comwrote: Gary, 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 alternative. 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? Gary The extensible enum solution satisfies all of us who are opposed to adding pre-defined levels, while also satisfying the original requirement raised by Nick and yourself. Frankly I don't understand why you would still want the pre-defined levels. Remko On Sat, Jan 25, 2014 at 12:53 AM, Gary Gregory garydgreg...@gmail.comwrote: On Thu, Jan 23, 2014 at 10:45 PM, Remko Popma remko.po...@gmail.comwrote: Gary, I think that's a very cool idea! Much more flexible, powerful and elegant than pre-defined levels could ever be. As I wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. I'm not sure why you want to make the features mutually exclusive. (Some) others agree that these are different features. I see two topics: - What are the default levels for a 21st century logging framework. Do we simply blindly copy Log4j 1? Or do we look at frameworks from different languages and platforms for inspiration? - How (not if, I think we all agree) should we allow for custom levels. Gary It definitely makes sense to design the extensible enum with this potential usage in mind. Remko On Friday, January 24, 2014, Gary Gregory garydgreg...@gmail.com wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. Here is how I convinced myself that custom levels are a “good thing”. No matter which built-in levels exits, I may want custom levels. For example, I want my app to use the following levels DEFCON1, DEFCON2, DEFCON3, DEFCON4, and DEFCON5. This might be for one part of my app or a whole subsystem, no matter, I want to use the built-in levels in addition to the DEFCON levels. It is worth mentioning that if I want that feature only as a user, I can “skin” levels in a layout and assign any label to the built-in levels. If I am also a
Re: Enums and Custom Levels
I completely agree. On Sunday, January 26, 2014, Gary Gregory garydgreg...@gmail.com wrote: It does not matter how rare you think a condition will be, with concurrency issues, it's will happen, so we should only consider bug free solutions. Gary Original message From: Remko Popma Date:01/26/2014 00:13 (GMT-05:00) To: Log4J Developers List Subject: Re: Enums and Custom Levels Ralph, I copied Nick's code _as is_ and had no compile errors. The class is abstract, but instances are defined in the static block as: OFF = new Level(OFF, 0) {}; // note the {}: this creates an anonymous concrete subclass I agree that read access needs to be synchronized as well, not just write access (the constructor). I experimented with several options: * synchronizing on plain Object in both constructor and when accessing the static Map(s) * a ReentrantReadWriteLock * a lock-free implementation I decided against ReentrantReadWriteLock as it has more overhead than plain synchronized access and the write access (in the constructors) is going to be extremely rare: not worth paying the overhead in the more common reads. It is also cumbersome to code. The lock-free implementation uses an AtomicInteger for the ordinals, and an AtomicReference for the MapString, Level. In the constructor, create a new MapString, Level instance based on the old copy, add the new instance, and try to call compareAndSet to replace the old instance with the new instance. Retry on failure. Finally, simply synchronizing on the constructorLock object in the Level.toLevel() and Level.values() methods may be simplest. Which of the last two is best depends on how often the toLevel() and values() levels are called. It turns out they are only called during reconfiguration, so no real need to optimize these methods. I would argue that simple synchronization may be best in this case. Remko On Sun, Jan 26, 2014 at 1:49 PM, Ralph Goers ralph.go...@dslextreme.comjavascript:_e({}, 'cvml', 'ralph.go...@dslextreme.com'); wrote: As I am working on this I just want to point out a number of issues with the code below: 1. The class is abstract. The static block is doing a bunch of new Level() invocations which obviously generate compile errors on an abstract class. I had to make it be a non-abstract class. 2. As I pointed out before there is no way to access the “standard” levels as an enum. I have addressed that. 3. Although the constructor is synchronized access to the Map is not. Trying to get from the map while a Level is being added will result in a ConcurrentModificationException. I am using a ConcurrentMap instead. 3. The constructor requires synchronization because it is modifying both the map and the ordinal. However, since this isn’t an enum the ordinal value is of dubious value. Removing that would allow the removal of the synchronization in the constructor. I am considering that but I haven’t done it yet. 4. Your example of creating the extension shows doing a new Level(). This doesn’t work because a) the class is abstract and b) the constructor is protected. I am leaving the constructor protected so extension will require doing new ExtendedLevel(name, value) and creating a constructor. Not requiring that means applications can do a new Level() anywhere and I am opposed to allowing that. Ralph On Jan 23, 2014, at 12:42 AM, Nick Williams nicho...@nicholaswilliams.net javascript:_e({}, 'cvml', 'nicho...@nicholaswilliams.net'); wrote: Okay, I finally got a minute to read all of these emails, and... EVERYBODY FREEZE! What if I could get you an extensible enum that required no interface changes and no binary-incompatible changes at all? Sound too good to be true? I proposed this months ago (LOG4J2-41) and it got shot down multiple times, but as of now I've heard THREE people say extensible enum in this thread, so here it is, an extensible enum: public abstract class Level implements ComparableLevel, Serializable { public static final Level OFF; public static final Level FATAL; public static final Level ERROR; public static final Level WARN; public static final Level INFO; public static final Level DEBUG; public static final Level TRACE; public static final Level ALL; private static final long serialVersionUID = 0L; private static final HashtableString, Level map; private static final TreeMapInteger, Level values; private static final Object constructorLock; static { // static variables must be constructed in certain order constructorLock = new Object(); map = new HashtableString, Level(); values = new TreeMapInteger, Level(); OFF = new Level(OFF, 0) {}; FATAL = new Level(FATAL, 100) {}; ERROR = new Level(ERROR, 200) {}; WARN = new Level(WARN, 300) {}; INFO = new Level(INFO, 400) {};
[jira] [Updated] (LOG4J2-316) Logo Contest Submissions
[ https://issues.apache.org/jira/browse/LOG4J2-316?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] James Devenish updated LOG4J2-316: -- Attachment: Log4j-circular-more.svg Log4j-circular-more.png Logo Contest Submissions Key: LOG4J2-316 URL: https://issues.apache.org/jira/browse/LOG4J2-316 Project: Log4j 2 Issue Type: Task Reporter: Christian Grobmeier Assignee: Christian Grobmeier Attachments: CarloMatti-Concept.jpg, Log4J2-Attitude.png, Log4J2-Selected.png, Log4j-circular-more.png, Log4j-circular-more.svg, Log4j-circular.png, Log4j-circular.svg, Log4j-combined.png, Log4j-galactica.png, Log4j-textured.png, Log4j_logo.png, Micah_log4j_icon.png, a_new_log4j2-logo.png, apache-log4j-2.png, apache_log4j2_logo.png, l4j.png, l4j.svg, log4-SE.png, log4.png, log4J2-logo-B.png, log4J2-logo.png, log4J2_Lila.png, log4J2_Orange_Grün.png, log4J2_Schwartz.png, log4J_bunt.png, log4j-2-rnm.png, log4j-2.png, log4j-apache.png, log4j-asap.png, log4j-designmantic.com-1.PNG, log4j-designmantic.com-2.PNG, log4j-designmantic.com-3.PNG, log4j-designmantic.com-4.PNG, log4j-designmantic.com-5.PNG, log4j-designmantic.com-6.PNG, log4j-designmantic.com-7.PNG, log4j-designmantic.com-8.PNG, log4j-stepuk.png, log4j.png, log4j.png, log4j.svg, log4j2(Pasha_G).png, log4j2(logo).png, log4j2(logo)_1.png, log4j2-b.svg, log4j2_e-id.nl.jpg, log4j2_e-id.nl.svg, log4j_2.svg, log4j_idea.jpg, log4j_logo.png, log4j_murdy_1.png, log4j_murdy_10.png, log4j_murdy_11.png, log4j_murdy_11_types.png, log4j_murdy_2.png, log4j_murdy_3.png, log4j_murdy_4.png, log4j_murdy_6.png, log4j_murdy_7.png, log4j_murdy_8.png, log4j_murdy_9.png, logo-log4j-circle.png, logo-log4j-eruption.png, logo-m-nostrokes-condensed.png, logo-m-nostrokes-condensed.svg, logo-m-nostrokes.png, logo-m-nostrokes.svg, logo-m.png, logo-m.svg, logoprop_coffeesteam_131022NS.png, logoprop_monogram_131022NS.png, logoprop_stacked-lj_131022NS.png, tmp_140123_0205221834269922.png h4. Log4J logo contest Log4j 2.0 is looking for a new logo! After 12 years, the Log4j project is getting ready for a brand new major release: version 2.0. This new major version is a reboot of this project in many ways: it is not only time to change the version number to 2.0 but also time to refresh the Log4j logo. Log4j 2 is very different from Log4j 1. Log4j 2 is more reliable and faster than its predecessor and comparable frameworks. The team has grown after years of stagnation and there is now a lot of activity on our lists. We are now approaching the 2.0 release after eight beta releases. With our new logo, we want to show the Java community that Log4j is back. We would like to open participation to the community to create this new logo. h4. HOW TO PARTICIPATE Attach your entries to the Jira: https://issues.apache.org/jira/browse/LOG4J2-316 You can submit as many entries as you like. You must license your Logo under the Apache License 2.0. -The contest will last one month from the date of the announcement.- *UPDATE: The contest ends on 31.01.2014.* If your Logo is accepted, you must sign an ICLA: http://www.apache.org/licenses/icla.txt While we will accept PNG image formats for the contest, we prefer vector based formats (SVG). You can convert pixel-based formats produced with Gimp or Photoshop to SVG with free tools like Inkscape (http://inkscape.org) Please note that a logo should not contain too many details. h4. HOW THE WINNING LOGO IS CHOSEN We invite everyone to vote on the mailing lists. The votes of Apache Logging Committers are binding. If the community submits more than 10 Logos, voting will proceed in two rounds. In the first round, the 10 logos with the most +1 votes graduate to round two. In the second round, the logo with the most +1 will win the contest. The majority of the Apache Logging PMC can veto a logo. We will accept the logo when all votes are successful and the ICLA of the logo contributor is on file. Please ask questions on the dev mailing list. The Log4j team -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Enums and Custom Levels - completed.
So I assume we could build on this by adding the ability to generate these custom levels from the config, with no user provided class required? On Jan 26, 2014 12:58 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name=“” category=“Level”) for them to be usable during configuration. Are their any objections to me checking this in? I’ll be doing the commit at around noon Pacific Daylight Time if I don’t hear any. Ralph On Jan 25, 2014, at 7:08 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I am working on the implementation of custom levels now. I should have it done today. Ralph On Jan 24, 2014, at 7:07 PM, Remko Popma remko.po...@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? Remko On Saturday, January 25, 2014, Gary Gregory garydgreg...@gmail.com wrote: On Fri, Jan 24, 2014 at 11:48 AM, Remko Popma remko.po...@gmail.com wrote: Gary, 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 alternative. 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? Gary The extensible enum solution satisfies all of us who are opposed to adding pre-defined levels, while also satisfying the original requirement raised by Nick and yourself. Frankly I don't understand why you would still want the pre-defined levels. Remko On Sat, Jan 25, 2014 at 12:53 AM, Gary Gregory garydgreg...@gmail.com wrote: On Thu, Jan 23, 2014 at 10:45 PM, Remko Popma remko.po...@gmail.com wrote: Gary, I think that's a very cool idea! Much more flexible, powerful and elegant than pre-defined levels could ever be. As I wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. I'm not sure why you want to make the features mutually exclusive. (Some) others agree that these are different features. I see two topics: - What are the default levels for a 21st century logging framework. Do we simply blindly copy Log4j 1? Or do we look at frameworks from different languages and platforms for inspiration? - How (not if, I think we all agree) should we allow for custom levels. Gary It definitely makes sense to design the extensible enum with this potential usage in mind. Remko On Friday, January 24, 2014, Gary Gregory garydgreg...@gmail.com wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. Here is how I convinced myself that custom levels are a “good thing”. No matter which built-in levels exits, I may want custom levels. For example, I want my app to use the following levels DEFCON1, DEFCON2, DEFCON3, DEFCON4, and DEFCON5. This might be for one part of my app or a whole subsystem, no matter, I want to use the built-in levels in addition to the DEFCON levels. It is worth mentioning that if I want that feature only as a user, I can “skin” levels in a layout and assign any label to the built-in levels. If I am also a developer, I want to use DEFCON levels in the source code. At
Re: Enums and Custom Levels - completed.
Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the originating level class be included in the classpath. I'm thinking about socketreceiver and to a lesser extent logfilepatternreceiver. Scott On Jan 26, 2014 7:28 AM, Scott Deboy scott.de...@gmail.com wrote: So I assume we could build on this by adding the ability to generate these custom levels from the config, with no user provided class required? On Jan 26, 2014 12:58 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick's extensible enum class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name= category=Level) for them to be usable during configuration. Are their any objections to me checking this in? I'll be doing the commit at around noon Pacific Daylight Time if I don't hear any. Ralph On Jan 25, 2014, at 7:08 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I am working on the implementation of custom levels now. I should have it done today. Ralph On Jan 24, 2014, at 7:07 PM, Remko Popma remko.po...@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? Remko On Saturday, January 25, 2014, Gary Gregory garydgreg...@gmail.com wrote: On Fri, Jan 24, 2014 at 11:48 AM, Remko Popma remko.po...@gmail.com wrote: Gary, 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 alternative. 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? Gary The extensible enum solution satisfies all of us who are opposed to adding pre-defined levels, while also satisfying the original requirement raised by Nick and yourself. Frankly I don't understand why you would still want the pre-defined levels. Remko On Sat, Jan 25, 2014 at 12:53 AM, Gary Gregory garydgreg...@gmail.com wrote: On Thu, Jan 23, 2014 at 10:45 PM, Remko Popma remko.po...@gmail.com wrote: Gary, I think that's a very cool idea! Much more flexible, powerful and elegant than pre-defined levels could ever be. As I wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. I'm not sure why you want to make the features mutually exclusive. (Some) others agree that these are different features. I see two topics: - What are the default levels for a 21st century logging framework. Do we simply blindly copy Log4j 1? Or do we look at frameworks from different languages and platforms for inspiration? - How (not if, I think we all agree) should we allow for custom levels. Gary It definitely makes sense to design the extensible enum with this potential usage in mind. Remko On Friday, January 24, 2014, Gary Gregory garydgreg...@gmail.com wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. Here is how I convinced myself that custom levels are a good thing. No matter which built-in levels exits, I may want
[jira] [Created] (LOG4J2-514) ConsoleAppender closing System.out on Windows
Wolf480 Pl created LOG4J2-514: - Summary: ConsoleAppender closing System.out on Windows Key: LOG4J2-514 URL: https://issues.apache.org/jira/browse/LOG4J2-514 Project: Log4j 2 Issue Type: Bug Components: Appenders Affects Versions: 2.0-beta9 Environment: Windows 7 64-bit Oracle JDK 1.7.0_51 Reporter: Wolf480 Pl If the Console appender is not specified in the configuration file, after the configuration is read, the Console appender is being destroyed, which causes it to release its OutputStreamManager, When this manager is released and closed, it checks if the stream is System.out or System.err, and if it is, doesn't close it. But on Windows, ConsoleAppender wraps the System.out into a WindowsAnsiOutputStream. The OutputStreamManager closes the stream when it's released, and the stream closes the underlaying System.out. I think the easiest solution would be to use new FileOutputStream(FileDescriptor.out)) instead of System.out in ConsoleAppender implementation. -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
[jira] [Updated] (LOG4J2-514) ConsoleAppender closing System.out on Windows
[ https://issues.apache.org/jira/browse/LOG4J2-514?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Wolf480 Pl updated LOG4J2-514: -- Description: If the Console appender is not specified in the configuration file, after the configuration is read, the Console appender is being destroyed, which causes it to release its OutputStreamManager, When this manager is released and closed, it checks if the stream is System.out or System.err, and if it is, doesn't close it. But on Windows, ConsoleAppender wraps the System.out into a WindowsAnsiOutputStream. The OutputStreamManager closes the stream when it's released, and the stream closes the underlaying System.out. proof: http://imageshack.com/a/img31/8296/cg6b.png I think the easiest solution would be to use new FileOutputStream(FileDescriptor.out)) instead of System.out in ConsoleAppender implementation. was: If the Console appender is not specified in the configuration file, after the configuration is read, the Console appender is being destroyed, which causes it to release its OutputStreamManager, When this manager is released and closed, it checks if the stream is System.out or System.err, and if it is, doesn't close it. But on Windows, ConsoleAppender wraps the System.out into a WindowsAnsiOutputStream. The OutputStreamManager closes the stream when it's released, and the stream closes the underlaying System.out. I think the easiest solution would be to use new FileOutputStream(FileDescriptor.out)) instead of System.out in ConsoleAppender implementation. ConsoleAppender closing System.out on Windows - Key: LOG4J2-514 URL: https://issues.apache.org/jira/browse/LOG4J2-514 Project: Log4j 2 Issue Type: Bug Components: Appenders Affects Versions: 2.0-beta9 Environment: Windows 7 64-bit Oracle JDK 1.7.0_51 Reporter: Wolf480 Pl If the Console appender is not specified in the configuration file, after the configuration is read, the Console appender is being destroyed, which causes it to release its OutputStreamManager, When this manager is released and closed, it checks if the stream is System.out or System.err, and if it is, doesn't close it. But on Windows, ConsoleAppender wraps the System.out into a WindowsAnsiOutputStream. The OutputStreamManager closes the stream when it's released, and the stream closes the underlaying System.out. proof: http://imageshack.com/a/img31/8296/cg6b.png I think the easiest solution would be to use new FileOutputStream(FileDescriptor.out)) instead of System.out in ConsoleAppender implementation. -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
[jira] [Reopened] (LOG4J2-41) Extensible Log Level
[ https://issues.apache.org/jira/browse/LOG4J2-41?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Ralph Goers reopened LOG4J2-41: --- Assignee: Ralph Goers Reopening as we agreed to address this. Extensible Log Level Key: LOG4J2-41 URL: https://issues.apache.org/jira/browse/LOG4J2-41 Project: Log4j 2 Issue Type: Improvement Components: API Reporter: Ralph Goers Assignee: Ralph Goers It is desirable to have the Level be an enum. However, it is also desirable to let users add new log levels. These goals are in opposition to each other since enum classes are final. In addition, adding new levels implies adding new methods to the Logger interface (or some counterpart to it). This would be unworkable. -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
[jira] [Closed] (LOG4J2-41) Extensible Log Level
[ https://issues.apache.org/jira/browse/LOG4J2-41?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Ralph Goers closed LOG4J2-41. - Extensible Log Level Key: LOG4J2-41 URL: https://issues.apache.org/jira/browse/LOG4J2-41 Project: Log4j 2 Issue Type: Improvement Components: API Reporter: Ralph Goers Assignee: Ralph Goers Fix For: 2.0-rc1 It is desirable to have the Level be an enum. However, it is also desirable to let users add new log levels. These goals are in opposition to each other since enum classes are final. In addition, adding new levels implies adding new methods to the Logger interface (or some counterpart to it). This would be unworkable. -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
[jira] [Resolved] (LOG4J2-41) Extensible Log Level
[ https://issues.apache.org/jira/browse/LOG4J2-41?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Ralph Goers resolved LOG4J2-41. --- Resolution: Fixed Fix Version/s: 2.0-rc1 Support for custom levels was added in revision 1561537. Extensible Log Level Key: LOG4J2-41 URL: https://issues.apache.org/jira/browse/LOG4J2-41 Project: Log4j 2 Issue Type: Improvement Components: API Reporter: Ralph Goers Assignee: Ralph Goers Fix For: 2.0-rc1 It is desirable to have the Level be an enum. However, it is also desirable to let users add new log levels. These goals are in opposition to each other since enum classes are final. In addition, adding new levels implies adding new methods to the Logger interface (or some counterpart to it). This would be unworkable. -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Enums and Custom Levels - completed.
Can you post a diff or the related files somewhere? Obviously it can be tweaked after commit if necessary, but I'd like to see if there's anything major that sticks out to me before you commit. Thanks, Nick On Jan 26, 2014, at 2:57 AM, Ralph Goers wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name=“” category=“Level”) for them to be usable during configuration. Are their any objections to me checking this in? I’ll be doing the commit at around noon Pacific Daylight Time if I don’t hear any. Ralph On Jan 25, 2014, at 7:08 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I am working on the implementation of custom levels now. I should have it done today. Ralph On Jan 24, 2014, at 7:07 PM, Remko Popma remko.po...@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? Remko On Saturday, January 25, 2014, Gary Gregory garydgreg...@gmail.com wrote: On Fri, Jan 24, 2014 at 11:48 AM, Remko Popma remko.po...@gmail.com wrote: Gary, 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 alternative. 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? Gary The extensible enum solution satisfies all of us who are opposed to adding pre-defined levels, while also satisfying the original requirement raised by Nick and yourself. Frankly I don't understand why you would still want the pre-defined levels. Remko On Sat, Jan 25, 2014 at 12:53 AM, Gary Gregory garydgreg...@gmail.com wrote: On Thu, Jan 23, 2014 at 10:45 PM, Remko Popma remko.po...@gmail.com wrote: Gary, I think that's a very cool idea! Much more flexible, powerful and elegant than pre-defined levels could ever be. As I wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. I'm not sure why you want to make the features mutually exclusive. (Some) others agree that these are different features. I see two topics: - What are the default levels for a 21st century logging framework. Do we simply blindly copy Log4j 1? Or do we look at frameworks from different languages and platforms for inspiration? - How (not if, I think we all agree) should we allow for custom levels. Gary It definitely makes sense to design the extensible enum with this potential usage in mind. Remko On Friday, January 24, 2014, Gary Gregory garydgreg...@gmail.com wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. Here is how I convinced myself that custom levels are a “good thing”. No matter which built-in levels exits, I may want custom levels. For example, I want my app to use the following levels DEFCON1, DEFCON2, DEFCON3, DEFCON4, and DEFCON5. This might be for one part of my app or a whole subsystem, no matter, I want to use the built-in levels in addition to the DEFCON levels. It is worth mentioning that if I want that feature only as a user, I can
Re: Enums and Custom Levels - completed.
Never mind I see you just committed. :-) I'll review and provide feedback if necessary. N On Jan 26, 2014, at 1:36 PM, Nick Williams wrote: Can you post a diff or the related files somewhere? Obviously it can be tweaked after commit if necessary, but I'd like to see if there's anything major that sticks out to me before you commit. Thanks, Nick On Jan 26, 2014, at 2:57 AM, Ralph Goers wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name=“” category=“Level”) for them to be usable during configuration. Are their any objections to me checking this in? I’ll be doing the commit at around noon Pacific Daylight Time if I don’t hear any. Ralph On Jan 25, 2014, at 7:08 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I am working on the implementation of custom levels now. I should have it done today. Ralph On Jan 24, 2014, at 7:07 PM, Remko Popma remko.po...@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? Remko On Saturday, January 25, 2014, Gary Gregory garydgreg...@gmail.com wrote: On Fri, Jan 24, 2014 at 11:48 AM, Remko Popma remko.po...@gmail.com wrote: Gary, 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 alternative. 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? Gary The extensible enum solution satisfies all of us who are opposed to adding pre-defined levels, while also satisfying the original requirement raised by Nick and yourself. Frankly I don't understand why you would still want the pre-defined levels. Remko On Sat, Jan 25, 2014 at 12:53 AM, Gary Gregory garydgreg...@gmail.com wrote: On Thu, Jan 23, 2014 at 10:45 PM, Remko Popma remko.po...@gmail.com wrote: Gary, I think that's a very cool idea! Much more flexible, powerful and elegant than pre-defined levels could ever be. As I wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. I'm not sure why you want to make the features mutually exclusive. (Some) others agree that these are different features. I see two topics: - What are the default levels for a 21st century logging framework. Do we simply blindly copy Log4j 1? Or do we look at frameworks from different languages and platforms for inspiration? - How (not if, I think we all agree) should we allow for custom levels. Gary It definitely makes sense to design the extensible enum with this potential usage in mind. Remko On Friday, January 24, 2014, Gary Gregory garydgreg...@gmail.com wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. Here is how I convinced myself that custom levels are a “good thing”. No matter which built-in levels exits, I may want custom levels. For example, I want my app to use the following levels DEFCON1, DEFCON2, DEFCON3, DEFCON4, and DEFCON5. This might be for one part of my app or a whole
Re: Enums and Custom Levels - completed.
I’ve committed the changes. Take a look at ExtendedLevels.java, ExtendedLevelTest.java and log4j-customLevel.xml in the log4j-core test directories to see how it works. Ralph On Jan 26, 2014, at 1:19 AM, Remko Popma remko.po...@gmail.com wrote: I'm very curious! Can't wait to see it. Go for it! On Sunday, January 26, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name=“” category=“Level”) for them to be usable during configuration. Are their any objections to me checking this in? I’ll be doing the commit at around noon Pacific Daylight Time if I don’t hear any. Ralph On Jan 25, 2014, at 7:08 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I am working on the implementation of custom levels now. I should have it done today. Ralph On Jan 24, 2014, at 7:07 PM, Remko Popma remko.po...@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? Remko On Saturday, January 25, 2014, Gary Gregory garydgreg...@gmail.com wrote: On Fri, Jan 24, 2014 at 11:48 AM, Remko Popma remko.po...@gmail.com wrote: Gary, 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 alternative. 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? Gary The extensible enum solution satisfies all of us who are opposed to adding pre-defined levels, while also satisfying the original requirement raised by Nick and yourself. Frankly I don't understand why you would still want the pre-defined levels. Remko On Sat, Jan 25, 2014 at 12:53 AM, Gary Gregory garydgreg...@gmail.com wrote: On Thu, Jan 23, 2014 at 10:45 PM, Remko Popma remko.po...@gmail.com wrote: Gary, I think that's a very cool idea! Much more flexible, powerful and elegant than pre-defined levels could ever be. As I wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. I'm not sure why you want to make the features mutually exclusive. (Some) others agree that these are different features. I see two topics: - What are the default levels for a 21st century logging framework. Do we simply blindly copy Log4j 1? Or do we look at frameworks from different languages and platforms for inspiration? - How (not if, I think we all agree) should we allow for custom levels. Gary It definitely makes sense to design the extensible enum with this potential usage in mind. Remko On Friday, January 24, 2014, Gary Gregory garydgreg...@gmail.com wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. Here is how I convinced myself that custom levels are a “good thing”. No matter which built-in levels exits, I may want custom levels. For example, I want my app to use the following levels DEFCON1, DEFCON2, DEFCON3, DEFCON4, and DEFCON5. This might be for one part of my app or a whole subsystem, no matter, I want to use the
Re: Enums and Custom Levels - completed.
I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the originating level class be included in the classpath. I'm thinking about socketreceiver and to a lesser extent logfilepatternreceiver. Scott On Jan 26, 2014 7:28 AM, Scott Deboy scott.de...@gmail.com wrote: So I assume we could build on this by adding the ability to generate these custom levels from the config, with no user provided class required? On Jan 26, 2014 12:58 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name=“” category=“Level”) for them to be usable during configuration. Are their any objections to me checking this in? I’ll be doing the commit at around noon Pacific Daylight Time if I don’t hear any. Ralph On Jan 25, 2014, at 7:08 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I am working on the implementation of custom levels now. I should have it done today. Ralph On Jan 24, 2014, at 7:07 PM, Remko Popma remko.po...@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? Remko On Saturday, January 25, 2014, Gary Gregory garydgreg...@gmail.com wrote: On Fri, Jan 24, 2014 at 11:48 AM, Remko Popma remko.po...@gmail.com wrote: Gary, 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 alternative. 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? Gary The extensible enum solution satisfies all of us who are opposed to adding pre-defined levels, while also satisfying the original requirement raised by Nick and yourself. Frankly I don't understand why you would still want the pre-defined levels. Remko On Sat, Jan 25, 2014 at 12:53 AM, Gary Gregory garydgreg...@gmail.com wrote: On Thu, Jan 23, 2014 at 10:45 PM, Remko Popma remko.po...@gmail.com wrote: Gary, I think that's a very cool idea! Much more flexible, powerful and elegant than pre-defined levels could ever be. As I wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. I'm not sure why you want to make the features mutually exclusive. (Some) others agree that these are different features. I see two topics: - What are the default levels for a 21st century logging framework. Do we simply blindly copy Log4j 1? Or do we look at frameworks from different languages and platforms for inspiration? - How (not if, I think we all agree) should we allow for custom levels. Gary It
Re: Enums and Custom Levels - completed.
Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the originating level class be included in the classpath. I'm thinking about socketreceiver and to a lesser extent logfilepatternreceiver. Scott On Jan 26, 2014 7:28 AM, Scott Deboy scott.de...@gmail.com wrote: So I assume we could build on this by adding the ability to generate these custom levels from the config, with no user provided class required? On Jan 26, 2014 12:58 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name=“” category=“Level”) for them to be usable during configuration. Are their any objections to me checking this in? I’ll be doing the commit at around noon Pacific Daylight Time if I don’t hear any. Ralph On Jan 25, 2014, at 7:08 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I am working on the implementation of custom levels now. I should have it done today. Ralph On Jan 24, 2014, at 7:07 PM, Remko Popma remko.po...@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? Remko On Saturday, January 25, 2014, Gary Gregory garydgreg...@gmail.com wrote: On Fri, Jan 24, 2014 at 11:48 AM, Remko Popma remko.po...@gmail.com wrote: Gary, 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 alternative. 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? Gary The extensible enum solution satisfies all of us who are opposed to adding pre-defined levels, while also satisfying the original requirement raised by Nick and yourself. Frankly I don't understand why you would still want the pre-defined levels. Remko On Sat, Jan 25, 2014 at 12:53 AM, Gary Gregory garydgreg...@gmail.com wrote: On Thu, Jan 23, 2014 at 10:45 PM, Remko Popma remko.po...@gmail.com wrote: Gary, I think that's a very cool idea! Much more flexible, powerful and elegant than pre-defined levels could ever be. As I wrote: I am discussing custom levels here with the understanding that this is a separate topic from what the built-in levels are. I'm not sure why you want to make the features mutually exclusive. (Some) others agree that these are different features. I see two topics: - What are the default levels for a 21st century
[jira] [Commented] (LOG4J2-373) Classloader issue in OSGi-environment
[ https://issues.apache.org/jira/browse/LOG4J2-373?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13882421#comment-13882421 ] Matt Sicker commented on LOG4J2-373: I meant log4j-core, not osgi. Classloader issue in OSGi-environment - Key: LOG4J2-373 URL: https://issues.apache.org/jira/browse/LOG4J2-373 Project: Log4j 2 Issue Type: Bug Components: API, Core Affects Versions: 2.0-beta9 Environment: OSGi R5 / R4 (Apache Felix 4.x) Reporter: Roland Weiglhofer Priority: Critical Labels: ClassLoader, OSGI Attachments: log4j-api.patch Using Log4j2 in a bundle causes following error: ERROR StatusLogger org.apache.logging.log4j.core.impl.Log4jContextFactory does not implement org.apache.logging.log4j.spi.LoggerContextFactory ERROR StatusLogger Unable to locate a logging implementation, using SimpleLogger printing the ClassLoaders in LogManager gives me following output: org.apache.logging.log4j.spi.LoggerContextFactory loaded by org.apache.logging.log4j-api [13] org.apache.logging.log4j.core.impl.Log4jContextFactory loaded by sun.misc.Launcher$AppClassLoader@35a16869 We have two different ClassLoaders. That's why the implementation is not assignable. The core uses the bootstrap-classloader and the api uses the bundle-classloader. Workaround needed. Thx addendum: ProviderUtil.findClassLoader() returns the bootstrap-classloader but not the bundle-classloader of the log4j2-core. The log4j2-core is a fragment of the log4j2-api bundle. Thus, ProviderUtil.findClassLoader() must return the bundle-classloader of log4j2-api. This a bug for the case that log4j2-core is used as the implementation. There are other cases that will also cause problems. Further investigations are necessary. Workaround: 1. check if log4j2 runs in an OSGI container. Bundle mybundle = org.osgi.framework.FrameworkUtil.getBundle(MyClass.this); 2. if(mybundle != null), than get bundle-classloader of log4j2-impl. mybundle.adapt(BundleWiring.class).getClassLoader(); -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Enums and Custom Levels - completed.
Some (ok, a lot of) feedback: - `private static ConcurrentMapString, Level levels` should be final. - `private static Object constructorLock` should be final. In fact, code inspection flags this as a warning since code synchronizes on it. - The standard Level constants should be instantiated in a static initializer like in my original code. Otherwise the order they are instantiated in is unpredictable, and DEBUG (for example) may even have a different ordinal each time the JVM starts. - Level isn't abstract. However, you use `new Level(xxx, n) {}` (brackets) for Level.OFF, ExtendedLevels.NOTE, and ExtendedLevels.DETAIL, but you use `new Level(xxx, n)` (no brackets) for other levels. IMO, Level should be abstract (so that there's always exactly one instance of every class that extends Level, just like a real enum), and the levels should all use {} to construct. However, if we don't make Level abstract, then we should remove {} from OFF, NOTE, and DETAIL because it's unnecessary. - The way StdLevel appears in the middle of Level separates its static fields from its instance fields, constructor, and methods. It makes it difficult to read. I have to scroll pass StdLevel to see the rest of Level. Can we please move StdLevel to the bottom of Level? - This is more personal preference, but I don't like abbreviating things in class names. What is Std? We may know, but does everyone? To someone unfamiliar with English, Standard is easy to translate, but they have to first figure out that Std is short for Std. Can be please un-abbreviate this to StandardLevel? - I disagree with this approach: if (levels.containsKey(name)) { Level level = levels.get(name); if (level.intLevel() != intLevel) { throw new IllegalArgumentException(Level + name + has already been defined.); } ordinal = level.ordinal; } This allows multiple Levels with the same name/intLevel to be instantiated, which prevents equality testing (level == Level.OFF) from being 100% deterministic. It should really be this: if (levels.containsKey(name)) { throw new IllegalArgumentException(Level + name + has already been defined.); } - I think we should make all of the methods of Level final. Custom levels shouldn't be able to change their behavior, IMO. Alternatively, if we don't make Level abstract, we should make it final. - Level has no JavaDoc. The Level constants in Level have no JavaDoc. That needs to be fixed. - I'm still not convinced StdLevel/StandardLevel is necessary. It seems like an anti-pattern to me. From what I can tell (please let me know if I'm missing something), StdLevel's entire purpose is to allow us to still switch on the standard levels. I think that's a bad reason to create an enum whose constants mirror Level. The primary problem with the StdLevel is that the conversion from a Level to a StdLevel in many cases happens __on every logging event__. That's going to be hugely inefficient. Really, when a custom Level is created, it should be created with an equivalent standard Level (or StdLevel). There are several ways to accomplish this that are open to discussion, but I don't think the current StdLevel.getStdLevel is the right approach. One alternative: private final Level standardLevel; protected Level(String name, int level, Level mapToOtherFrameworksAs) { this(name, level); this.standardLevel = mapToOtherFrameworksAs; } private Level(String name, int level) { // same as now this.standardLevel = this; } public final Level getStandardLevel() { return this.standardLevel; } This does, admittedly, have some problems. Another alternative that I could also be happy with that keeps the StandardLevel enum: private final StandardLevel standardLevel; protected Level(String name, int level, StandardLevel mapToOtherFrameworksAs) { this(name, level); this.standardLevel = mapToOtherFrameworksAs; } private Level(String name, int level) { // same as now this.standardLevel = this; } public final StandardLevel getStandardLevel() { return this.standardLevel; } Nick On Jan 26, 2014, at 1:38 PM, Ralph Goers wrote: I’ve committed the changes. Take a look at ExtendedLevels.java, ExtendedLevelTest.java and log4j-customLevel.xml in the log4j-core test directories to see how it works. Ralph On Jan 26, 2014, at 1:19 AM, Remko Popma remko.po...@gmail.com wrote: I'm very curious! Can't wait to see it. Go for it! On Sunday, January 26, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with
Re: Enums and Custom Levels - completed.
I agree with most of this and will make the suggested changes. At least up to the point of getting rid of the StandardLevel enum. That is used in too many places to map to some other framework. I agree that doing the calculation every time is not the right way to go and will see what I can do, but I don’t like passing the standard level as a parameter - it should be based solely on the intValue. However, that would mean the StandardLevel enum has to be created before the Levels themselves are created. Ralph On Jan 26, 2014, at 12:41 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Some (ok, a lot of) feedback: - `private static ConcurrentMapString, Level levels` should be final. - `private static Object constructorLock` should be final. In fact, code inspection flags this as a warning since code synchronizes on it. - The standard Level constants should be instantiated in a static initializer like in my original code. Otherwise the order they are instantiated in is unpredictable, and DEBUG (for example) may even have a different ordinal each time the JVM starts. - Level isn't abstract. However, you use `new Level(xxx, n) {}` (brackets) for Level.OFF, ExtendedLevels.NOTE, and ExtendedLevels.DETAIL, but you use `new Level(xxx, n)` (no brackets) for other levels. IMO, Level should be abstract (so that there's always exactly one instance of every class that extends Level, just like a real enum), and the levels should all use {} to construct. However, if we don't make Level abstract, then we should remove {} from OFF, NOTE, and DETAIL because it's unnecessary. - The way StdLevel appears in the middle of Level separates its static fields from its instance fields, constructor, and methods. It makes it difficult to read. I have to scroll pass StdLevel to see the rest of Level. Can we please move StdLevel to the bottom of Level? - This is more personal preference, but I don't like abbreviating things in class names. What is Std? We may know, but does everyone? To someone unfamiliar with English, Standard is easy to translate, but they have to first figure out that Std is short for Std. Can be please un-abbreviate this to StandardLevel? - I disagree with this approach: if (levels.containsKey(name)) { Level level = levels.get(name); if (level.intLevel() != intLevel) { throw new IllegalArgumentException(Level + name + has already been defined.); } ordinal = level.ordinal; } This allows multiple Levels with the same name/intLevel to be instantiated, which prevents equality testing (level == Level.OFF) from being 100% deterministic. It should really be this: if (levels.containsKey(name)) { throw new IllegalArgumentException(Level + name + has already been defined.); } - I think we should make all of the methods of Level final. Custom levels shouldn't be able to change their behavior, IMO. Alternatively, if we don't make Level abstract, we should make it final. - Level has no JavaDoc. The Level constants in Level have no JavaDoc. That needs to be fixed. - I'm still not convinced StdLevel/StandardLevel is necessary. It seems like an anti-pattern to me. From what I can tell (please let me know if I'm missing something), StdLevel's entire purpose is to allow us to still switch on the standard levels. I think that's a bad reason to create an enum whose constants mirror Level. The primary problem with the StdLevel is that the conversion from a Level to a StdLevel in many cases happens __on every logging event__. That's going to be hugely inefficient. Really, when a custom Level is created, it should be created with an equivalent standard Level (or StdLevel). There are several ways to accomplish this that are open to discussion, but I don't think the current StdLevel.getStdLevel is the right approach. One alternative: private final Level standardLevel; protected Level(String name, int level, Level mapToOtherFrameworksAs) { this(name, level); this.standardLevel = mapToOtherFrameworksAs; } private Level(String name, int level) { // same as now this.standardLevel = this; } public final Level getStandardLevel() { return this.standardLevel; } This does, admittedly, have some problems. Another alternative that I could also be happy with that keeps the StandardLevel enum: private final StandardLevel standardLevel; protected Level(String name, int level, StandardLevel mapToOtherFrameworksAs) { this(name, level); this.standardLevel = mapToOtherFrameworksAs; } private Level(String name, int level) { // same as now this.standardLevel = this; } public final StandardLevel getStandardLevel() { return
Re: Question about Log4jServletFilter in core.
Nick, Are you working on this? Ralph On Jan 18, 2014, at 11:38 AM, Nicholas Williams nicho...@nicholaswilliams.net wrote: Yes. Next weekend I plan on adding a Servlet context parameter that allows the user to disable starting Log4j automatically. That should allow us to keep everything in one JAR while supporting both sides of the argument. Nick Sent from my iPhone, so please forgive brief replies and frequent typos On Jan 18, 2014, at 10:54, Gary Gregory garydgreg...@gmail.com wrote: On Sat, Jan 18, 2014 at 12:35 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I’ve always had reservations about the servlet 3.0 automatic configuration because if the log4j jar is present it can’t be disabled or be modified by the end user. We’ve had some issues with Spring initialization and now LOG4J2-452 reinforces that. I would propose that if we want to keep it that we move the minimum amount required into its own jar so that users have a choice as to whether it is automatically initialized. Am I the only one who feels this way? Frankly, this and one other issue I plan to work on this weekend are the only things I see as blockers for a GA release. For me, the fewer jars, the better. Can't this be configured somehow without having to do more jar juggling? Gary Ralph On Jan 17, 2014, at 8:25 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Filter initialization is one of the last things to happen in web app startup. The ServletContainerInitializer sets the threads logger context so that web app startup procedures can use it. The filter's init() method clears it near the end of startup so that it doesn't bleed into another web app. Then, on web apps shutdown, destruction of filters is one of the first things to happen. The filter's destroy() sets the logger context so that the web app shutdown procedures can use it. Nick On Jan 17, 2014, at 10:17 PM, Matt Sicker wrote: Now I'm not sure if I'm interpreting this correctly, but init() clears the current thread's logger context, and destroy() sets it. What's up with this? Especially since it just gets set and cleared in the doFilter() bit. -- Matt Sicker boa...@gmail.com -- E-Mail: garydgreg...@gmail.com | ggreg...@apache.org Java Persistence with Hibernate, Second Edition JUnit in Action, Second Edition Spring Batch in Action Blog: http://garygregory.wordpress.com Home: http://garygregory.com/ Tweet! http://twitter.com/GaryGregory
Re: Enums and Custom Levels - completed.
I do have one other comment. You mention that the ordinal value isn’t guaranteed because the levels might be instantiated in a different order each time. An alternative wold be to just get rid of the ordinal. It isn’t used anywhere by anything and when custom values are added they will be added after the standard levels, which is correct but might not be what you would expect. Eliminating that would allow the static initialization to stay as it is and get rid of the need for synchronization in the constructor. Ralph On Jan 26, 2014, at 12:41 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Some (ok, a lot of) feedback: - `private static ConcurrentMapString, Level levels` should be final. - `private static Object constructorLock` should be final. In fact, code inspection flags this as a warning since code synchronizes on it. - The standard Level constants should be instantiated in a static initializer like in my original code. Otherwise the order they are instantiated in is unpredictable, and DEBUG (for example) may even have a different ordinal each time the JVM starts. - Level isn't abstract. However, you use `new Level(xxx, n) {}` (brackets) for Level.OFF, ExtendedLevels.NOTE, and ExtendedLevels.DETAIL, but you use `new Level(xxx, n)` (no brackets) for other levels. IMO, Level should be abstract (so that there's always exactly one instance of every class that extends Level, just like a real enum), and the levels should all use {} to construct. However, if we don't make Level abstract, then we should remove {} from OFF, NOTE, and DETAIL because it's unnecessary. - The way StdLevel appears in the middle of Level separates its static fields from its instance fields, constructor, and methods. It makes it difficult to read. I have to scroll pass StdLevel to see the rest of Level. Can we please move StdLevel to the bottom of Level? - This is more personal preference, but I don't like abbreviating things in class names. What is Std? We may know, but does everyone? To someone unfamiliar with English, Standard is easy to translate, but they have to first figure out that Std is short for Std. Can be please un-abbreviate this to StandardLevel? - I disagree with this approach: if (levels.containsKey(name)) { Level level = levels.get(name); if (level.intLevel() != intLevel) { throw new IllegalArgumentException(Level + name + has already been defined.); } ordinal = level.ordinal; } This allows multiple Levels with the same name/intLevel to be instantiated, which prevents equality testing (level == Level.OFF) from being 100% deterministic. It should really be this: if (levels.containsKey(name)) { throw new IllegalArgumentException(Level + name + has already been defined.); } - I think we should make all of the methods of Level final. Custom levels shouldn't be able to change their behavior, IMO. Alternatively, if we don't make Level abstract, we should make it final. - Level has no JavaDoc. The Level constants in Level have no JavaDoc. That needs to be fixed. - I'm still not convinced StdLevel/StandardLevel is necessary. It seems like an anti-pattern to me. From what I can tell (please let me know if I'm missing something), StdLevel's entire purpose is to allow us to still switch on the standard levels. I think that's a bad reason to create an enum whose constants mirror Level. The primary problem with the StdLevel is that the conversion from a Level to a StdLevel in many cases happens __on every logging event__. That's going to be hugely inefficient. Really, when a custom Level is created, it should be created with an equivalent standard Level (or StdLevel). There are several ways to accomplish this that are open to discussion, but I don't think the current StdLevel.getStdLevel is the right approach. One alternative: private final Level standardLevel; protected Level(String name, int level, Level mapToOtherFrameworksAs) { this(name, level); this.standardLevel = mapToOtherFrameworksAs; } private Level(String name, int level) { // same as now this.standardLevel = this; } public final Level getStandardLevel() { return this.standardLevel; } This does, admittedly, have some problems. Another alternative that I could also be happy with that keeps the StandardLevel enum: private final StandardLevel standardLevel; protected Level(String name, int level, StandardLevel mapToOtherFrameworksAs) { this(name, level); this.standardLevel = mapToOtherFrameworksAs; } private Level(String name, int level) { // same as now this.standardLevel = this; } public final StandardLevel getStandardLevel() { return
logging to solr/elasticsearch
Hello everyone, last thursday i had a small chat with christian grobmeier on a java user group meeting i am doing a lot of search and analytics in my daily business and i am very interessted in developing a component that directly logs into a solr/elasticsearch index Over a year ago i allready did some development on a solr appender if you are interesetedyou can have a look at :http://sourceforge.net/projects/log4jsolr.slugdev.p/ I like to develop a new component for log4j 2 My questions to you - is there allready done or planned in that direction? - where would such a component would fits best to log2j? (appender? plugin?) - whats the best way to configure an appender? in my first versionof the solr appender i had a lot of optional field mapping whicht made the configuration within the log4j.xml quite big would be great to get some feedback. this could be a good way to connect log events directly to a tool like kibana regards Markus Klose
Re: Question about Log4jServletFilter in core.
I am. Today, in fact. N On Jan 26, 2014, at 3:43 PM, Ralph Goers wrote: Nick, Are you working on this? Ralph On Jan 18, 2014, at 11:38 AM, Nicholas Williams nicho...@nicholaswilliams.net wrote: Yes. Next weekend I plan on adding a Servlet context parameter that allows the user to disable starting Log4j automatically. That should allow us to keep everything in one JAR while supporting both sides of the argument. Nick Sent from my iPhone, so please forgive brief replies and frequent typos On Jan 18, 2014, at 10:54, Gary Gregory garydgreg...@gmail.com wrote: On Sat, Jan 18, 2014 at 12:35 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I’ve always had reservations about the servlet 3.0 automatic configuration because if the log4j jar is present it can’t be disabled or be modified by the end user. We’ve had some issues with Spring initialization and now LOG4J2-452 reinforces that. I would propose that if we want to keep it that we move the minimum amount required into its own jar so that users have a choice as to whether it is automatically initialized. Am I the only one who feels this way? Frankly, this and one other issue I plan to work on this weekend are the only things I see as blockers for a GA release. For me, the fewer jars, the better. Can't this be configured somehow without having to do more jar juggling? Gary Ralph On Jan 17, 2014, at 8:25 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Filter initialization is one of the last things to happen in web app startup. The ServletContainerInitializer sets the threads logger context so that web app startup procedures can use it. The filter's init() method clears it near the end of startup so that it doesn't bleed into another web app. Then, on web apps shutdown, destruction of filters is one of the first things to happen. The filter's destroy() sets the logger context so that the web app shutdown procedures can use it. Nick On Jan 17, 2014, at 10:17 PM, Matt Sicker wrote: Now I'm not sure if I'm interpreting this correctly, but init() clears the current thread's logger context, and destroy() sets it. What's up with this? Especially since it just gets set and cleared in the doFilter() bit. -- Matt Sicker boa...@gmail.com -- E-Mail: garydgreg...@gmail.com | ggreg...@apache.org Java Persistence with Hibernate, Second Edition JUnit in Action, Second Edition Spring Batch in Action Blog: http://garygregory.wordpress.com Home: http://garygregory.com/ Tweet! http://twitter.com/GaryGregory
[jira] [Commented] (LOG4J2-513) Use more OSGi-friendly class loading mechanisms.
[ https://issues.apache.org/jira/browse/LOG4J2-513?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13882458#comment-13882458 ] Matt Sicker commented on LOG4J2-513: So far, one major refactoring that was required is separating out the class that holds the LoggerContextFactory. For lack of a better class name, I've gone with LoggerContextFactoryContext. This becomes an overridable anchor to the system, where LogManager delegates out to the context class. Included in the context class is the code from LogManager.static, and LogManager.static simply calls that method with override=false. Anyway, I've also added another bundle that includes a BundleActivator that will load/reload the logger context factory using the proper class loader. Needs more testing as I'm still learning how to use OSGi, but it seems simple enough. Use more OSGi-friendly class loading mechanisms. Key: LOG4J2-513 URL: https://issues.apache.org/jira/browse/LOG4J2-513 Project: Log4j 2 Issue Type: Sub-task Components: API Affects Versions: 2.0-rc1 Environment: OSGi Reporter: Matt Sicker Labels: api, bundle, classloader, osgi See for instance [here|http://njbartlett.name/2012/10/23/dreaded-thread-context-classloader.html]. Currently, o.a.l.l.util.ProviderUtil has a findClassLoader() method that depends on using the thread context class loader (TCCL). Now this method may work in certain environments, but once you're in an OSGi environment, class loaders are far more modular thanks to each bundle getting its own class loader. The thread context class loader is oftentimes not the correct one in such an environment. I'll do more research on being compatible with OSGi without depending on OSGi. In the meantime, this ticket will have to do. -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Enums and Custom Levels - completed.
I made most of the changes. I moved StandardLevel to a separate file in the spi sub-package. The actual level values are defined there and then referenced in Level. This way each Level can be associated with a StandardLevel in its constructor. Ralph On Jan 26, 2014, at 1:40 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I agree with most of this and will make the suggested changes. At least up to the point of getting rid of the StandardLevel enum. That is used in too many places to map to some other framework. I agree that doing the calculation every time is not the right way to go and will see what I can do, but I don’t like passing the standard level as a parameter - it should be based solely on the intValue. However, that would mean the StandardLevel enum has to be created before the Levels themselves are created. Ralph On Jan 26, 2014, at 12:41 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Some (ok, a lot of) feedback: - `private static ConcurrentMapString, Level levels` should be final. - `private static Object constructorLock` should be final. In fact, code inspection flags this as a warning since code synchronizes on it. - The standard Level constants should be instantiated in a static initializer like in my original code. Otherwise the order they are instantiated in is unpredictable, and DEBUG (for example) may even have a different ordinal each time the JVM starts. - Level isn't abstract. However, you use `new Level(xxx, n) {}` (brackets) for Level.OFF, ExtendedLevels.NOTE, and ExtendedLevels.DETAIL, but you use `new Level(xxx, n)` (no brackets) for other levels. IMO, Level should be abstract (so that there's always exactly one instance of every class that extends Level, just like a real enum), and the levels should all use {} to construct. However, if we don't make Level abstract, then we should remove {} from OFF, NOTE, and DETAIL because it's unnecessary. - The way StdLevel appears in the middle of Level separates its static fields from its instance fields, constructor, and methods. It makes it difficult to read. I have to scroll pass StdLevel to see the rest of Level. Can we please move StdLevel to the bottom of Level? - This is more personal preference, but I don't like abbreviating things in class names. What is Std? We may know, but does everyone? To someone unfamiliar with English, Standard is easy to translate, but they have to first figure out that Std is short for Std. Can be please un-abbreviate this to StandardLevel? - I disagree with this approach: if (levels.containsKey(name)) { Level level = levels.get(name); if (level.intLevel() != intLevel) { throw new IllegalArgumentException(Level + name + has already been defined.); } ordinal = level.ordinal; } This allows multiple Levels with the same name/intLevel to be instantiated, which prevents equality testing (level == Level.OFF) from being 100% deterministic. It should really be this: if (levels.containsKey(name)) { throw new IllegalArgumentException(Level + name + has already been defined.); } - I think we should make all of the methods of Level final. Custom levels shouldn't be able to change their behavior, IMO. Alternatively, if we don't make Level abstract, we should make it final. - Level has no JavaDoc. The Level constants in Level have no JavaDoc. That needs to be fixed. - I'm still not convinced StdLevel/StandardLevel is necessary. It seems like an anti-pattern to me. From what I can tell (please let me know if I'm missing something), StdLevel's entire purpose is to allow us to still switch on the standard levels. I think that's a bad reason to create an enum whose constants mirror Level. The primary problem with the StdLevel is that the conversion from a Level to a StdLevel in many cases happens __on every logging event__. That's going to be hugely inefficient. Really, when a custom Level is created, it should be created with an equivalent standard Level (or StdLevel). There are several ways to accomplish this that are open to discussion, but I don't think the current StdLevel.getStdLevel is the right approach. One alternative: private final Level standardLevel; protected Level(String name, int level, Level mapToOtherFrameworksAs) { this(name, level); this.standardLevel = mapToOtherFrameworksAs; } private Level(String name, int level) { // same as now this.standardLevel = this; } public final Level getStandardLevel() { return this.standardLevel; } This does, admittedly, have some problems. Another alternative that I could also be happy with that keeps the StandardLevel enum: private final StandardLevel standardLevel; protected Level(String name, int level,
Re: logging to solr/elasticsearch
The closest existing components that are vaguely related to what you're requesting are Mongo and CouchDB appenders. In log4j-core, the NoSQL appenders might be a good place to put this, but I'm not too sure. I mean, solr is kind of like a database, so it might belong in db at least. On 26 January 2014 16:10, Markus Klose lo...@markus-klose.de wrote: Hello everyone, last thursday i had a small chat with christian grobmeier on a java user group meeting i am doing a lot of search and analytics in my daily business and i am very interessted in developing a component that directly logs into a solr/elasticsearch index Over a year ago i allready did some development on a solr appender if you are interesetedyou can have a look at : http://sourceforge.net/projects/log4jsolr.slugdev.p/ I like to develop a new component for log4j 2 My questions to you - is there allready done or planned in that direction? - where would such a component would fits best to log2j? (appender? plugin?) - whats the best way to configure an appender? in my first versionof the solr appender i had a lot of optional field mapping whicht made the configuration within the log4j.xml quite big would be great to get some feedback. this could be a good way to connect log events directly to a tool like kibana regards Markus Klose -- Matt Sicker boa...@gmail.com
Re: Enums and Custom Levels - completed.
I would be OK with getting rid of the ordinal. It makes it less enum-like, but I agree that the ordinal really has little purpose now. The intLevel is more important. Here may be the best approach I can think of for calculating the StandardLevel-equivalent on instantiation: public static Level OFF = new Level(OFF, 0, StandardLevel.OFF) {}; ... public static Level ALL = new Level(ALL, Integer.MAX_VALUE, StandardLevel.ALL); ... private Level(String name, int intLevel, StandardLevel standardLevel) { // this is the only c-tor standard levels use // same logic as current constructor this.standardLevel = standardLevel; } protected Level(String name, int intLevel) { // this is the only c-tor custom levels use this(name, intLevel, Level.calculateStandardLevel(intLevel)); } public enum StandardLevel { OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL } Thoughts? N On Jan 26, 2014, at 4:02 PM, Ralph Goers wrote: I do have one other comment. You mention that the ordinal value isn’t guaranteed because the levels might be instantiated in a different order each time. An alternative wold be to just get rid of the ordinal. It isn’t used anywhere by anything and when custom values are added they will be added after the standard levels, which is correct but might not be what you would expect. Eliminating that would allow the static initialization to stay as it is and get rid of the need for synchronization in the constructor. Ralph On Jan 26, 2014, at 12:41 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Some (ok, a lot of) feedback: - `private static ConcurrentMapString, Level levels` should be final. - `private static Object constructorLock` should be final. In fact, code inspection flags this as a warning since code synchronizes on it. - The standard Level constants should be instantiated in a static initializer like in my original code. Otherwise the order they are instantiated in is unpredictable, and DEBUG (for example) may even have a different ordinal each time the JVM starts. - Level isn't abstract. However, you use `new Level(xxx, n) {}` (brackets) for Level.OFF, ExtendedLevels.NOTE, and ExtendedLevels.DETAIL, but you use `new Level(xxx, n)` (no brackets) for other levels. IMO, Level should be abstract (so that there's always exactly one instance of every class that extends Level, just like a real enum), and the levels should all use {} to construct. However, if we don't make Level abstract, then we should remove {} from OFF, NOTE, and DETAIL because it's unnecessary. - The way StdLevel appears in the middle of Level separates its static fields from its instance fields, constructor, and methods. It makes it difficult to read. I have to scroll pass StdLevel to see the rest of Level. Can we please move StdLevel to the bottom of Level? - This is more personal preference, but I don't like abbreviating things in class names. What is Std? We may know, but does everyone? To someone unfamiliar with English, Standard is easy to translate, but they have to first figure out that Std is short for Std. Can be please un-abbreviate this to StandardLevel? - I disagree with this approach: if (levels.containsKey(name)) { Level level = levels.get(name); if (level.intLevel() != intLevel) { throw new IllegalArgumentException(Level + name + has already been defined.); } ordinal = level.ordinal; } This allows multiple Levels with the same name/intLevel to be instantiated, which prevents equality testing (level == Level.OFF) from being 100% deterministic. It should really be this: if (levels.containsKey(name)) { throw new IllegalArgumentException(Level + name + has already been defined.); } - I think we should make all of the methods of Level final. Custom levels shouldn't be able to change their behavior, IMO. Alternatively, if we don't make Level abstract, we should make it final. - Level has no JavaDoc. The Level constants in Level have no JavaDoc. That needs to be fixed. - I'm still not convinced StdLevel/StandardLevel is necessary. It seems like an anti-pattern to me. From what I can tell (please let me know if I'm missing something), StdLevel's entire purpose is to allow us to still switch on the standard levels. I think that's a bad reason to create an enum whose constants mirror Level. The primary problem with the StdLevel is that the conversion from a Level to a StdLevel in many cases happens __on every logging event__. That's going to be hugely inefficient. Really, when a custom Level is created, it should be created with an equivalent standard Level (or StdLevel). There are several ways to accomplish this that are open to discussion, but I don't think the current
Re: Enums and Custom Levels - completed.
+1 to everything Nick said. On 26 January 2014 16:40, Nick Williams nicho...@nicholaswilliams.netwrote: I would be OK with getting rid of the ordinal. It makes it less enum-like, but I agree that the ordinal really has little purpose now. The intLevel is more important. Here may be the best approach I can think of for calculating the StandardLevel-equivalent on instantiation: public static Level OFF = new Level(OFF, 0, StandardLevel.OFF) {}; ... public static Level ALL = new Level(ALL, Integer.MAX_VALUE, StandardLevel.ALL); ... private Level(String name, int intLevel, StandardLevel standardLevel) { // this is the only c-tor standard levels use // same logic as current constructor this.standardLevel = standardLevel; } protected Level(String name, int intLevel) { // this is the only c-tor custom levels use this(name, intLevel, Level.calculateStandardLevel(intLevel)); } public enum StandardLevel { OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL } Thoughts? N On Jan 26, 2014, at 4:02 PM, Ralph Goers wrote: I do have one other comment. You mention that the ordinal value isn’t guaranteed because the levels might be instantiated in a different order each time. An alternative wold be to just get rid of the ordinal. It isn’t used anywhere by anything and when custom values are added they will be added after the standard levels, which is correct but might not be what you would expect. Eliminating that would allow the static initialization to stay as it is and get rid of the need for synchronization in the constructor. Ralph On Jan 26, 2014, at 12:41 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Some (ok, a lot of) feedback: - `private static ConcurrentMapString, Level levels` should be final. - `private static Object constructorLock` should be final. In fact, code inspection flags this as a warning since code synchronizes on it. - The standard Level constants should be instantiated in a static initializer like in my original code. Otherwise the order they are instantiated in is unpredictable, and DEBUG (for example) may even have a different ordinal each time the JVM starts. - Level isn't abstract. However, you use `new Level(xxx, n) {}` (brackets) for Level.OFF, ExtendedLevels.NOTE, and ExtendedLevels.DETAIL, but you use `new Level(xxx, n)` (no brackets) for other levels. IMO, Level should be abstract (so that there's always exactly one instance of every class that extends Level, just like a real enum), and the levels should all use {} to construct. However, if we don't make Level abstract, then we should remove {} from OFF, NOTE, and DETAIL because it's unnecessary. - The way StdLevel appears in the middle of Level separates its static fields from its instance fields, constructor, and methods. It makes it difficult to read. I have to scroll pass StdLevel to see the rest of Level. Can we please move StdLevel to the bottom of Level? - This is more personal preference, but I don't like abbreviating things in class names. What is Std? We may know, but does everyone? To someone unfamiliar with English, Standard is easy to translate, but they have to first figure out that Std is short for Std. Can be please un-abbreviate this to StandardLevel? - I disagree with this approach: if (levels.containsKey(name)) { Level level = levels.get(name); if (level.intLevel() != intLevel) { throw new IllegalArgumentException(Level + name + has already been defined.); } ordinal = level.ordinal; } This allows multiple Levels with the same name/intLevel to be instantiated, which prevents equality testing (level == Level.OFF) from being 100% deterministic. It should really be this: if (levels.containsKey(name)) { throw new IllegalArgumentException(Level + name + has already been defined.); } - I think we should make all of the methods of Level final. Custom levels shouldn't be able to change their behavior, IMO. Alternatively, if we don't make Level abstract, we should make it final. - Level has no JavaDoc. The Level constants in Level have no JavaDoc. That needs to be fixed. - I'm still not convinced StdLevel/StandardLevel is necessary. It seems like an anti-pattern to me. From what I can tell (please let me know if I'm missing something), StdLevel's entire purpose is to allow us to still switch on the standard levels. I think that's a bad reason to create an enum whose constants mirror Level. The primary problem with the StdLevel is that the conversion from a Level to a StdLevel in many cases happens __on every logging event__. That's going to be hugely inefficient. Really, when a custom Level is created, it should be created with an equivalent standard Level (or
Re: Enums and Custom Levels - completed.
Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.com wrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the originating level class be included in the classpath. I'm thinking about socketreceiver and to a lesser extent logfilepatternreceiver. Scott On Jan 26, 2014 7:28 AM, Scott Deboy scott.de...@gmail.com wrote: So I assume we could build on this by adding the ability to generate these custom levels from the config, with no user provided class required? On Jan 26, 2014 12:58 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name=“” category=“Level”) for them to be usable during configuration. Are their any objections to me checking this in? I’ll be doing the commit at around noon Pacific Daylight Time if I don’t hear any. Ralph On Jan 25, 2014, at 7:08 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I am working on the implementation of custom levels now. I should have it done today. Ralph On Jan 24, 2014, at 7:07 PM, Remko Popma remko.po...@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? Remko On Saturday, January 25, 2014, Gary Gregory garydgreg...@gmail.com wrote: On Fri, Jan 24, 2014 at 11:48 AM, Remko Popma remko.po...@gmail.com wrote: Gary, 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 alternative. 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?
Re: Enums and Custom Levels - completed.
By the way, there may be a small concurrency bug in the Level.values() static method. This may be better: public static Level[] values() { CollectionLevel values = Level.levels.values(); return values.toArray(new Level[values.size()]); // use value collection size, not map size } On Mon, Jan 27, 2014 at 7:43 AM, Matt Sicker boa...@gmail.com wrote: +1 to everything Nick said. On 26 January 2014 16:40, Nick Williams nicho...@nicholaswilliams.netwrote: I would be OK with getting rid of the ordinal. It makes it less enum-like, but I agree that the ordinal really has little purpose now. The intLevel is more important. Here may be the best approach I can think of for calculating the StandardLevel-equivalent on instantiation: public static Level OFF = new Level(OFF, 0, StandardLevel.OFF) {}; ... public static Level ALL = new Level(ALL, Integer.MAX_VALUE, StandardLevel.ALL); ... private Level(String name, int intLevel, StandardLevel standardLevel) { // this is the only c-tor standard levels use // same logic as current constructor this.standardLevel = standardLevel; } protected Level(String name, int intLevel) { // this is the only c-tor custom levels use this(name, intLevel, Level.calculateStandardLevel(intLevel)); } public enum StandardLevel { OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL } Thoughts? N On Jan 26, 2014, at 4:02 PM, Ralph Goers wrote: I do have one other comment. You mention that the ordinal value isn’t guaranteed because the levels might be instantiated in a different order each time. An alternative wold be to just get rid of the ordinal. It isn’t used anywhere by anything and when custom values are added they will be added after the standard levels, which is correct but might not be what you would expect. Eliminating that would allow the static initialization to stay as it is and get rid of the need for synchronization in the constructor. Ralph On Jan 26, 2014, at 12:41 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Some (ok, a lot of) feedback: - `private static ConcurrentMapString, Level levels` should be final. - `private static Object constructorLock` should be final. In fact, code inspection flags this as a warning since code synchronizes on it. - The standard Level constants should be instantiated in a static initializer like in my original code. Otherwise the order they are instantiated in is unpredictable, and DEBUG (for example) may even have a different ordinal each time the JVM starts. - Level isn't abstract. However, you use `new Level(xxx, n) {}` (brackets) for Level.OFF, ExtendedLevels.NOTE, and ExtendedLevels.DETAIL, but you use `new Level(xxx, n)` (no brackets) for other levels. IMO, Level should be abstract (so that there's always exactly one instance of every class that extends Level, just like a real enum), and the levels should all use {} to construct. However, if we don't make Level abstract, then we should remove {} from OFF, NOTE, and DETAIL because it's unnecessary. - The way StdLevel appears in the middle of Level separates its static fields from its instance fields, constructor, and methods. It makes it difficult to read. I have to scroll pass StdLevel to see the rest of Level. Can we please move StdLevel to the bottom of Level? - This is more personal preference, but I don't like abbreviating things in class names. What is Std? We may know, but does everyone? To someone unfamiliar with English, Standard is easy to translate, but they have to first figure out that Std is short for Std. Can be please un-abbreviate this to StandardLevel? - I disagree with this approach: if (levels.containsKey(name)) { Level level = levels.get(name); if (level.intLevel() != intLevel) { throw new IllegalArgumentException(Level + name + has already been defined.); } ordinal = level.ordinal; } This allows multiple Levels with the same name/intLevel to be instantiated, which prevents equality testing (level == Level.OFF) from being 100% deterministic. It should really be this: if (levels.containsKey(name)) { throw new IllegalArgumentException(Level + name + has already been defined.); } - I think we should make all of the methods of Level final. Custom levels shouldn't be able to change their behavior, IMO. Alternatively, if we don't make Level abstract, we should make it final. - Level has no JavaDoc. The Level constants in Level have no JavaDoc. That needs to be fixed. - I'm still not convinced StdLevel/StandardLevel is necessary. It seems like an anti-pattern to me. From what I can tell (please let me know if I'm missing something), StdLevel's entire purpose is to allow us to still switch on
Re: Enums and Custom Levels - completed.
I agree. The circumstance that could cause a problem here would be rare, but not impossible. We should use Remko's code here. Nick On Jan 26, 2014, at 5:20 PM, Remko Popma wrote: By the way, there may be a small concurrency bug in the Level.values() static method. This may be better: public static Level[] values() { CollectionLevel values = Level.levels.values(); return values.toArray(new Level[values.size()]); // use value collection size, not map size } On Mon, Jan 27, 2014 at 7:43 AM, Matt Sicker boa...@gmail.com wrote: +1 to everything Nick said. On 26 January 2014 16:40, Nick Williams nicho...@nicholaswilliams.net wrote: I would be OK with getting rid of the ordinal. It makes it less enum-like, but I agree that the ordinal really has little purpose now. The intLevel is more important. Here may be the best approach I can think of for calculating the StandardLevel-equivalent on instantiation: public static Level OFF = new Level(OFF, 0, StandardLevel.OFF) {}; ... public static Level ALL = new Level(ALL, Integer.MAX_VALUE, StandardLevel.ALL); ... private Level(String name, int intLevel, StandardLevel standardLevel) { // this is the only c-tor standard levels use // same logic as current constructor this.standardLevel = standardLevel; } protected Level(String name, int intLevel) { // this is the only c-tor custom levels use this(name, intLevel, Level.calculateStandardLevel(intLevel)); } public enum StandardLevel { OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL } Thoughts? N On Jan 26, 2014, at 4:02 PM, Ralph Goers wrote: I do have one other comment. You mention that the ordinal value isn’t guaranteed because the levels might be instantiated in a different order each time. An alternative wold be to just get rid of the ordinal. It isn’t used anywhere by anything and when custom values are added they will be added after the standard levels, which is correct but might not be what you would expect. Eliminating that would allow the static initialization to stay as it is and get rid of the need for synchronization in the constructor. Ralph On Jan 26, 2014, at 12:41 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Some (ok, a lot of) feedback: - `private static ConcurrentMapString, Level levels` should be final. - `private static Object constructorLock` should be final. In fact, code inspection flags this as a warning since code synchronizes on it. - The standard Level constants should be instantiated in a static initializer like in my original code. Otherwise the order they are instantiated in is unpredictable, and DEBUG (for example) may even have a different ordinal each time the JVM starts. - Level isn't abstract. However, you use `new Level(xxx, n) {}` (brackets) for Level.OFF, ExtendedLevels.NOTE, and ExtendedLevels.DETAIL, but you use `new Level(xxx, n)` (no brackets) for other levels. IMO, Level should be abstract (so that there's always exactly one instance of every class that extends Level, just like a real enum), and the levels should all use {} to construct. However, if we don't make Level abstract, then we should remove {} from OFF, NOTE, and DETAIL because it's unnecessary. - The way StdLevel appears in the middle of Level separates its static fields from its instance fields, constructor, and methods. It makes it difficult to read. I have to scroll pass StdLevel to see the rest of Level. Can we please move StdLevel to the bottom of Level? - This is more personal preference, but I don't like abbreviating things in class names. What is Std? We may know, but does everyone? To someone unfamiliar with English, Standard is easy to translate, but they have to first figure out that Std is short for Std. Can be please un-abbreviate this to StandardLevel? - I disagree with this approach: if (levels.containsKey(name)) { Level level = levels.get(name); if (level.intLevel() != intLevel) { throw new IllegalArgumentException(Level + name + has already been defined.); } ordinal = level.ordinal; } This allows multiple Levels with the same name/intLevel to be instantiated, which prevents equality testing (level == Level.OFF) from being 100% deterministic. It should really be this: if (levels.containsKey(name)) { throw new IllegalArgumentException(Level + name + has already been defined.); } - I think we should make all of the methods of Level final. Custom levels shouldn't be able to change their behavior, IMO. Alternatively, if we don't make Level abstract, we should make it final. - Level has no JavaDoc. The Level constants in Level
Re: Enums and Custom Levels - completed.
Yes that's what I was thinking. Scott On Jan 26, 2014 3:18 PM, Remko Popma remko.po...@gmail.com wrote: Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.comwrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven't done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the originating level class be included in the classpath. I'm thinking about socketreceiver and to a lesser extent logfilepatternreceiver. Scott On Jan 26, 2014 7:28 AM, Scott Deboy scott.de...@gmail.com wrote: So I assume we could build on this by adding the ability to generate these custom levels from the config, with no user provided class required? On Jan 26, 2014 12:58 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick's extensible enum class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name= category=Level) for them to be usable during configuration. Are their any objections to me checking this in? I'll be doing the commit at around noon Pacific Daylight Time if I don't hear any. Ralph On Jan 25, 2014, at 7:08 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I am working on the implementation of custom levels now. I should have it done today. Ralph On Jan 24, 2014, at 7:07 PM, Remko Popma remko.po...@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? Remko On Saturday, January 25, 2014, Gary Gregory garydgreg...@gmail.com wrote: On Fri, Jan 24, 2014 at 11:48 AM, Remko Popma remko.po...@gmail.com wrote: Gary, 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 alternative. 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
[jira] [Updated] (LOG4J2-513) Use more OSGi-friendly class loading mechanisms.
[ https://issues.apache.org/jira/browse/LOG4J2-513?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Matt Sicker updated LOG4J2-513: --- Attachment: 0002-Refactor-class-loader-usage-in-LogManager.patch 0001-Fix-weird-usage-of-StatusLogger.patch Here's what I've got so far. As I mentioned in a TODO comment, the bundle activator part would be better implemented using a declarative service (using the Felix annotations would be the easiest way) or blueprints. However, this is still a significant improvement in OSGi support. I'm completely open to better names for anything here as LoggerContextFactoryContext seems a bit ridiculous. :) Use more OSGi-friendly class loading mechanisms. Key: LOG4J2-513 URL: https://issues.apache.org/jira/browse/LOG4J2-513 Project: Log4j 2 Issue Type: Sub-task Components: API Affects Versions: 2.0-rc1 Environment: OSGi Reporter: Matt Sicker Labels: api, bundle, classloader, osgi Attachments: 0001-Fix-weird-usage-of-StatusLogger.patch, 0002-Refactor-class-loader-usage-in-LogManager.patch See for instance [here|http://njbartlett.name/2012/10/23/dreaded-thread-context-classloader.html]. Currently, o.a.l.l.util.ProviderUtil has a findClassLoader() method that depends on using the thread context class loader (TCCL). Now this method may work in certain environments, but once you're in an OSGi environment, class loaders are far more modular thanks to each bundle getting its own class loader. The thread context class loader is oftentimes not the correct one in such an environment. I'll do more research on being compatible with OSGi without depending on OSGi. In the meantime, this ticket will have to do. -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
[jira] [Created] (LOG4J2-515) Support OSGi bundles without requiring OSGi dependencies.
Matt Sicker created LOG4J2-515: -- Summary: Support OSGi bundles without requiring OSGi dependencies. Key: LOG4J2-515 URL: https://issues.apache.org/jira/browse/LOG4J2-515 Project: Log4j 2 Issue Type: Epic Components: API, Appenders, Configurators, Core, Filters, Layouts, Receivers Affects Versions: 2.0-rc1 Environment: OSGi, non-OSGi Reporter: Matt Sicker In order to properly support OSGi, we need to use a combination of ideas. # Packages and modules should be as coherent as possible. This makes bundling them into bundles and services significantly easier. Plus, it's a good idea anyway. # Use [Felix SCR annotations|http://felix.apache.org/documentation/subprojects/apache-felix-maven-scr-plugin/scr-annotations.html] in order to support more advanced OSGi concepts without requiring an explicit dependency on OSGi. This way, the annotations can be discarded or ignored by non-OSGi environments. # Provide more bundles. The core bundles, while a good start, could be further modularized. # Don't rely on class loader hacks. Instead, methods that need to use a class loader should always include a ClassLoader parameter. Class loader hacks can be used in centralized locations as a fallback mechanism where no advanced class loaders are provided. -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
[jira] [Commented] (LOG4J2-400) Provide Appender-Bundles
[ https://issues.apache.org/jira/browse/LOG4J2-400?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13882482#comment-13882482 ] Matt Sicker commented on LOG4J2-400: Linking this to an epic for OSGi support. Provide Appender-Bundles Key: LOG4J2-400 URL: https://issues.apache.org/jira/browse/LOG4J2-400 Project: Log4j 2 Issue Type: Improvement Components: Appenders, Core Affects Versions: 2.0-beta9 Environment: OSGi R4 / R5 (Apache Felix 4.x) Reporter: Roland Weiglhofer Priority: Critical Labels: Appender, Core, Dependency, OSGi, PluginManager, lightweight, optional Instead of deploying all appenders in the core fragment, it would be much better if the customer can choose which appender he wants to provide. It's easy to hive the appender off in a separate bundle fragment. The host bundle is the API bundle. The Plugin Manager (core fragment) finds the deployed appenders in the classpath of the host bundle. The PluginManager should parse the class path in a separate thread (Startup-Hook) and only once at the start of the host bundle, but not for each call (when a consumer bundle aquires a logger). Make package-imports optional (Import-Package*;resolution:=optional/Import-Package) This reduces the number of dependencies and reduces the startup time of the whole system. One possible solution for the Plugin Manager is to use the reflections plugin during the maven build process. This plugin lists all classes of a project within a xml file. This file can be marked as a bundle resource and is stored within the appender bundle fragment. The idea is that each appender fragment has its own class list. Because the bundle host (log4j2 core) sees all resources of its fragments it can load these class lists at runtime. Thus, the Plugin Manager gets only those appenders that are installed within deployed bundle fragements. The class list is created during the build process, the plugin manager must not parse the classpath at runtime. Log4j2 uses a xml parser by default. An additional new dependency to a xml-parser library is not required. plugin groupIdorg.reflections/groupId artifactIdreflections-maven/artifactId version0.9.8/version executions execution goals goalreflections/goal /goals phaseprocess-classes/phase /execution /executions configuration destinations${project.basedir}/META-INF/reflections/${project.artifactId}-reflections.xml/destinations /configuration /plugin -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Enums and Custom Levels - completed.
Generating a logger /interface/ is going to be hard. Sure, writing the code automatically will be a piece of cake. But then what do we do with that code? The user needs to program against it. So we have to have a command-line utility or Maven/Ant plug-in to generate the source pre-compile. However, since the vast majority of users are using IDEs, those IDEs will still warn them about the interface not existing until they have run the utility to generate the source. I think a better approach would be to allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void(Marker, Message) void(Marker, Message, Throwable t) void(Marker, Object) void(Marker, Object, Throwable t) void(Marker, String) void(Marker, String, Object...) void(Marker, String throwable) void(Message) void(Message, Throwable t) void(Object) void(Object, Throwable t) void(String) void(String, Object...) void(String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Make sense? N On Jan 26, 2014, at 5:32 PM, Scott Deboy wrote: Yes that's what I was thinking. Scott On Jan 26, 2014 3:18 PM, Remko Popma remko.po...@gmail.com wrote: Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.com wrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the originating level class be included in the classpath. I'm thinking about socketreceiver and to a lesser extent logfilepatternreceiver. Scott On Jan 26, 2014 7:28 AM, Scott Deboy scott.de...@gmail.com wrote: So I assume we could build on this by adding the ability to generate these custom levels from the config, with no user provided class required? On Jan 26, 2014 12:58 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name=“” category=“Level”) for them to be usable during configuration. Are their any objections to me checking this in? I’ll be doing the commit at around noon Pacific Daylight Time if I don’t hear any. Ralph On Jan 25, 2014, at 7:08 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I am working on the implementation of custom levels now. I should have it done today. Ralph
Re: Enums and Custom Levels - completed.
Don't annotation processing plugins work well in IDEs? Either way, there's a maven plugin already available for doing that, and javac has some sort of support for it already. Also, I'm still advocating for using a real enum for Level while providing a Level interface for all the relevant methods. And can't getCustomLogger also provide a default method that uses the getClassName method? On 26 January 2014 17:51, Nick Williams nicho...@nicholaswilliams.netwrote: Generating a logger /interface/ is going to be hard. Sure, writing the code automatically will be a piece of cake. But then what do we do with that code? The user needs to program against it. So we have to have a command-line utility or Maven/Ant plug-in to generate the source pre-compile. However, since the vast majority of users are using IDEs, those IDEs will still warn them about the interface not existing until they have run the utility to generate the source. I think a better approach would be to allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void(Marker, Message) void(Marker, Message, Throwable t) void(Marker, Object) void(Marker, Object, Throwable t) void(Marker, String) void(Marker, String, Object...) void(Marker, String throwable) void(Message) void(Message, Throwable t) void(Object) void(Object, Throwable t) void(String) void(String, Object...) void(String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Make sense? N On Jan 26, 2014, at 5:32 PM, Scott Deboy wrote: Yes that's what I was thinking. Scott On Jan 26, 2014 3:18 PM, Remko Popma remko.po...@gmail.com wrote: Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.comwrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the originating level class be included in the classpath. I'm thinking about socketreceiver and to a lesser extent logfilepatternreceiver. Scott On Jan 26, 2014 7:28 AM, Scott Deboy scott.de...@gmail.com wrote: So I assume we could build on this by adding the ability to generate these custom levels from the config, with no user provided class required? On Jan 26, 2014 12:58 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom
Re: Enums and Custom Levels - completed.
I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott On Jan 26, 2014 3:52 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Generating a logger /interface/ is going to be hard. Sure, writing the code automatically will be a piece of cake. But then what do we do with that code? The user needs to program against it. So we have to have a command-line utility or Maven/Ant plug-in to generate the source pre-compile. However, since the vast majority of users are using IDEs, those IDEs will still warn them about the interface not existing until they have run the utility to generate the source. I think a better approach would be to allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void(Marker, Message) void(Marker, Message, Throwable t) void(Marker, Object) void(Marker, Object, Throwable t) void(Marker, String) void(Marker, String, Object...) void(Marker, String throwable) void(Message) void(Message, Throwable t) void(Object) void(Object, Throwable t) void(String) void(String, Object...) void(String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Make sense? N On Jan 26, 2014, at 5:32 PM, Scott Deboy wrote: Yes that's what I was thinking. Scott On Jan 26, 2014 3:18 PM, Remko Popma remko.po...@gmail.com wrote: Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.comwrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the originating level class be included in the classpath. I'm thinking about socketreceiver and to a lesser extent logfilepatternreceiver. Scott On Jan 26, 2014 7:28 AM, Scott Deboy scott.de...@gmail.com wrote: So I assume we could build on this by adding the ability to generate these custom levels from the config, with no user provided class required? On Jan 26, 2014 12:58 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name=“” category=“Level”) for
Re: Enums and Custom Levels - completed.
I think this is very similar to my most recent commit. Since you are OK with removing the ordinal I am going to do that along with fix the problem Remko mentioned. Ralph On Jan 26, 2014, at 2:40 PM, Nick Williams nicho...@nicholaswilliams.net wrote: I would be OK with getting rid of the ordinal. It makes it less enum-like, but I agree that the ordinal really has little purpose now. The intLevel is more important. Here may be the best approach I can think of for calculating the StandardLevel-equivalent on instantiation: public static Level OFF = new Level(OFF, 0, StandardLevel.OFF) {}; ... public static Level ALL = new Level(ALL, Integer.MAX_VALUE, StandardLevel.ALL); ... private Level(String name, int intLevel, StandardLevel standardLevel) { // this is the only c-tor standard levels use // same logic as current constructor this.standardLevel = standardLevel; } protected Level(String name, int intLevel) { // this is the only c-tor custom levels use this(name, intLevel, Level.calculateStandardLevel(intLevel)); } public enum StandardLevel { OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL } Thoughts? N On Jan 26, 2014, at 4:02 PM, Ralph Goers wrote: I do have one other comment. You mention that the ordinal value isn’t guaranteed because the levels might be instantiated in a different order each time. An alternative wold be to just get rid of the ordinal. It isn’t used anywhere by anything and when custom values are added they will be added after the standard levels, which is correct but might not be what you would expect. Eliminating that would allow the static initialization to stay as it is and get rid of the need for synchronization in the constructor. Ralph On Jan 26, 2014, at 12:41 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Some (ok, a lot of) feedback: - `private static ConcurrentMapString, Level levels` should be final. - `private static Object constructorLock` should be final. In fact, code inspection flags this as a warning since code synchronizes on it. - The standard Level constants should be instantiated in a static initializer like in my original code. Otherwise the order they are instantiated in is unpredictable, and DEBUG (for example) may even have a different ordinal each time the JVM starts. - Level isn't abstract. However, you use `new Level(xxx, n) {}` (brackets) for Level.OFF, ExtendedLevels.NOTE, and ExtendedLevels.DETAIL, but you use `new Level(xxx, n)` (no brackets) for other levels. IMO, Level should be abstract (so that there's always exactly one instance of every class that extends Level, just like a real enum), and the levels should all use {} to construct. However, if we don't make Level abstract, then we should remove {} from OFF, NOTE, and DETAIL because it's unnecessary. - The way StdLevel appears in the middle of Level separates its static fields from its instance fields, constructor, and methods. It makes it difficult to read. I have to scroll pass StdLevel to see the rest of Level. Can we please move StdLevel to the bottom of Level? - This is more personal preference, but I don't like abbreviating things in class names. What is Std? We may know, but does everyone? To someone unfamiliar with English, Standard is easy to translate, but they have to first figure out that Std is short for Std. Can be please un-abbreviate this to StandardLevel? - I disagree with this approach: if (levels.containsKey(name)) { Level level = levels.get(name); if (level.intLevel() != intLevel) { throw new IllegalArgumentException(Level + name + has already been defined.); } ordinal = level.ordinal; } This allows multiple Levels with the same name/intLevel to be instantiated, which prevents equality testing (level == Level.OFF) from being 100% deterministic. It should really be this: if (levels.containsKey(name)) { throw new IllegalArgumentException(Level + name + has already been defined.); } - I think we should make all of the methods of Level final. Custom levels shouldn't be able to change their behavior, IMO. Alternatively, if we don't make Level abstract, we should make it final. - Level has no JavaDoc. The Level constants in Level have no JavaDoc. That needs to be fixed. - I'm still not convinced StdLevel/StandardLevel is necessary. It seems like an anti-pattern to me. From what I can tell (please let me know if I'm missing something), StdLevel's entire purpose is to allow us to still switch on the standard levels. I think that's a bad reason to create an enum whose constants mirror Level. The primary problem with the StdLevel is that the conversion from a Level to a StdLevel in many cases happens __on every
[jira] [Commented] (LOG4J2-461) ERROR StatusLogger Unable to locate a logging implementation, using SimpleLogger
[ https://issues.apache.org/jira/browse/LOG4J2-461?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13882483#comment-13882483 ] Matt Sicker commented on LOG4J2-461: This might be a class loader issue if Android does weird things like OSGi does. I'll take a look into the issue if that turns out to be the case. ERROR StatusLogger Unable to locate a logging implementation, using SimpleLogger - Key: LOG4J2-461 URL: https://issues.apache.org/jira/browse/LOG4J2-461 Project: Log4j 2 Issue Type: Bug Components: API Affects Versions: 2.0-beta9 Environment: Android Reporter: Gaurav Kapoor Priority: Blocker ERROR StatusLogger Unable to locate a logging implementation, using SimpleLogger Code: Logger LOG = LogManager.getLogger(MainActivity.class); LOG.error(Test Log4j2); {code} ?xml version=1.0 encoding=UTF-8? Configuration Appenders Console name=STDOUT target=SYSTEM_OUT PatternLayout pattern=%d %-5p [%t] %C{2} (%F:%L) - %m%n/ /Console /Appenders Loggers Logger name=hello level=info/ Root level=trace AppenderRef ref=STDOUT/ /Root /Loggers /Configuration {code} -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Enums and Custom Levels - completed.
My first implementation used a real enum that implemented a Level interface. I have to agree with Nick that what is currently committed is simpler. Ralph On Jan 26, 2014, at 4:00 PM, Matt Sicker boa...@gmail.com wrote: Don't annotation processing plugins work well in IDEs? Either way, there's a maven plugin already available for doing that, and javac has some sort of support for it already. Also, I'm still advocating for using a real enum for Level while providing a Level interface for all the relevant methods. And can't getCustomLogger also provide a default method that uses the getClassName method? On 26 January 2014 17:51, Nick Williams nicho...@nicholaswilliams.net wrote: Generating a logger /interface/ is going to be hard. Sure, writing the code automatically will be a piece of cake. But then what do we do with that code? The user needs to program against it. So we have to have a command-line utility or Maven/Ant plug-in to generate the source pre-compile. However, since the vast majority of users are using IDEs, those IDEs will still warn them about the interface not existing until they have run the utility to generate the source. I think a better approach would be to allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void(Marker, Message) void(Marker, Message, Throwable t) void(Marker, Object) void(Marker, Object, Throwable t) void(Marker, String) void(Marker, String, Object...) void(Marker, String throwable) void(Message) void(Message, Throwable t) void(Object) void(Object, Throwable t) void(String) void(String, Object...) void(String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Make sense? N On Jan 26, 2014, at 5:32 PM, Scott Deboy wrote: Yes that's what I was thinking. Scott On Jan 26, 2014 3:18 PM, Remko Popma remko.po...@gmail.com wrote: Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.com wrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the originating level class be included in the classpath. I'm thinking about socketreceiver and to a lesser extent logfilepatternreceiver. Scott On Jan 26, 2014 7:28 AM, Scott Deboy scott.de...@gmail.com wrote: So I assume we could build on this by adding the ability to generate these custom levels from the config, with no user
Re: Enums and Custom Levels - completed.
Oh, actually I used an Interface for Level and an enum for the standard levels, so I didn’t try what you are suggesting. I don’t see how what you are proposing would work since all the Logger methods take a Level. If Level is an enum then only the values defined in it can be used, regardless of whatever interface it might implement. Ralph On Jan 26, 2014, at 4:10 PM, Ralph Goers ralph.go...@dslextreme.com wrote: My first implementation used a real enum that implemented a Level interface. I have to agree with Nick that what is currently committed is simpler. Ralph On Jan 26, 2014, at 4:00 PM, Matt Sicker boa...@gmail.com wrote: Don't annotation processing plugins work well in IDEs? Either way, there's a maven plugin already available for doing that, and javac has some sort of support for it already. Also, I'm still advocating for using a real enum for Level while providing a Level interface for all the relevant methods. And can't getCustomLogger also provide a default method that uses the getClassName method? On 26 January 2014 17:51, Nick Williams nicho...@nicholaswilliams.net wrote: Generating a logger /interface/ is going to be hard. Sure, writing the code automatically will be a piece of cake. But then what do we do with that code? The user needs to program against it. So we have to have a command-line utility or Maven/Ant plug-in to generate the source pre-compile. However, since the vast majority of users are using IDEs, those IDEs will still warn them about the interface not existing until they have run the utility to generate the source. I think a better approach would be to allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void(Marker, Message) void(Marker, Message, Throwable t) void(Marker, Object) void(Marker, Object, Throwable t) void(Marker, String) void(Marker, String, Object...) void(Marker, String throwable) void(Message) void(Message, Throwable t) void(Object) void(Object, Throwable t) void(String) void(String, Object...) void(String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Make sense? N On Jan 26, 2014, at 5:32 PM, Scott Deboy wrote: Yes that's what I was thinking. Scott On Jan 26, 2014 3:18 PM, Remko Popma remko.po...@gmail.com wrote: Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.com wrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as
Re: Enums and Custom Levels - completed.
If the explicit values of the enum aren't used, then the logger methods that take a level would still work just fine. That's with the funky T extends EnumT Level generic, too, right? On 26 January 2014 18:14, Ralph Goers ralph.go...@dslextreme.com wrote: Oh, actually I used an Interface for Level and an enum for the standard levels, so I didn’t try what you are suggesting. I don’t see how what you are proposing would work since all the Logger methods take a Level. If Level is an enum then only the values defined in it can be used, regardless of whatever interface it might implement. Ralph On Jan 26, 2014, at 4:10 PM, Ralph Goers ralph.go...@dslextreme.com wrote: My first implementation used a real enum that implemented a Level interface. I have to agree with Nick that what is currently committed is simpler. Ralph On Jan 26, 2014, at 4:00 PM, Matt Sicker boa...@gmail.com wrote: Don't annotation processing plugins work well in IDEs? Either way, there's a maven plugin already available for doing that, and javac has some sort of support for it already. Also, I'm still advocating for using a real enum for Level while providing a Level interface for all the relevant methods. And can't getCustomLogger also provide a default method that uses the getClassName method? On 26 January 2014 17:51, Nick Williams nicho...@nicholaswilliams.netwrote: Generating a logger /interface/ is going to be hard. Sure, writing the code automatically will be a piece of cake. But then what do we do with that code? The user needs to program against it. So we have to have a command-line utility or Maven/Ant plug-in to generate the source pre-compile. However, since the vast majority of users are using IDEs, those IDEs will still warn them about the interface not existing until they have run the utility to generate the source. I think a better approach would be to allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void(Marker, Message) void(Marker, Message, Throwable t) void(Marker, Object) void(Marker, Object, Throwable t) void(Marker, String) void(Marker, String, Object...) void(Marker, String throwable) void(Message) void(Message, Throwable t) void(Object) void(Object, Throwable t) void(String) void(String, Object...) void(String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Make sense? N On Jan 26, 2014, at 5:32 PM, Scott Deboy wrote: Yes that's what I was thinking. Scott On Jan 26, 2014 3:18 PM, Remko Popma remko.po...@gmail.com wrote: Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.comwrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it.
Re: Enums and Custom Levels - completed.
Please read my message again. I talk about wrapping not extending. Gary Original message From: Remko Popma remko.po...@gmail.com Date:01/26/2014 18:17 (GMT-05:00) To: Log4J Developers List log4j-dev@logging.apache.org Subject: Re: Enums and Custom Levels - completed. Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.com wrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the originating level class be included in the classpath. I'm thinking about socketreceiver and to a lesser extent logfilepatternreceiver. Scott On Jan 26, 2014 7:28 AM, Scott Deboy scott.de...@gmail.com wrote: So I assume we could build on this by adding the ability to generate these custom levels from the config, with no user provided class required? On Jan 26, 2014 12:58 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name=“” category=“Level”) for them to be usable during configuration. Are their any objections to me checking this in? I’ll be doing the commit at around noon Pacific Daylight Time if I don’t hear any. Ralph On Jan 25, 2014, at 7:08 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I am working on the implementation of custom levels now. I should have it done today. Ralph On Jan 24, 2014, at 7:07 PM, Remko Popma remko.po...@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? Remko On Saturday, January 25, 2014, Gary Gregory garydgreg...@gmail.com wrote: On Fri, Jan 24, 2014 at 11:48 AM, Remko Popma remko.po...@gmail.com wrote: Gary, 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 alternative. 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
[jira] [Created] (LOG4J2-516) As a developer using OSGi, I want to use Log4J as my OSGi Log Service
Matt Sicker created LOG4J2-516: -- Summary: As a developer using OSGi, I want to use Log4J as my OSGi Log Service Key: LOG4J2-516 URL: https://issues.apache.org/jira/browse/LOG4J2-516 Project: Log4j 2 Issue Type: Story Components: Core Environment: Felix, Equinox, OSGi Reporter: Matt Sicker See [the javadocs|http://www.osgi.org/javadoc/r5/cmpn/org/osgi/service/log/package-summary.html] for some details. I'd like to be able to import the log service bundle and be able to use Log4J as the backend if it has been registered in OSGi. This would require a module that adapts the logging infrastructure to OSGi's logging service. I think that would be a good addition to the bundles exported. -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Enums and Custom Levels - completed.
Sorry if I misread. Any mechanism that supports custom levels and gets as close as possible to the ease of use of the built-in logger interface is fine with me. On Monday, January 27, 2014, Gary Gregory garydgreg...@gmail.com wrote: Please read my message again. I talk about wrapping not extending. Gary Original message From: Remko Popma Date:01/26/2014 18:17 (GMT-05:00) To: Log4J Developers List Subject: Re: Enums and Custom Levels - completed. Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.comwrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the originating level class be included in the classpath. I'm thinking about socketreceiver and to a lesser extent logfilepatternreceiver. Scott On Jan 26, 2014 7:28 AM, Scott Deboy scott.de...@gmail.com wrote: So I assume we could build on this by adding the ability to generate these custom levels from the config, with no user provided class required? On Jan 26, 2014 12:58 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I have completed the work on custom levels. It uses a variation of Nick’s “extensible enum” class. The major difference with what he proposed is that the custom enums must be declared in a class annotated with @Plugin(name=“” category=“Level”) for them to be usable during configuration. Are their any objections to me checking this in? I’ll be doing the commit at around noon Pacific Daylight Time if I don’t hear any. Ralph On Jan 25, 2014, at 7:08 AM, Ralph Goers ralph.go...@dslextreme.com wrote: I am working on the implementation of custom levels now. I should have it done today. Ralph On Jan 24, 2014, at 7:07 PM, Remko Popma remko.po...@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 crea
Re: Enums and Custom Levels - completed.
I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(“DIAG”), “hello world”); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott On Jan 26, 2014 3:52 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Generating a logger /interface/ is going to be hard. Sure, writing the code automatically will be a piece of cake. But then what do we do with that code? The user needs to program against it. So we have to have a command-line utility or Maven/Ant plug-in to generate the source pre-compile. However, since the vast majority of users are using IDEs, those IDEs will still warn them about the interface not existing until they have run the utility to generate the source. I think a better approach would be to allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void(Marker, Message) void(Marker, Message, Throwable t) void(Marker, Object) void(Marker, Object, Throwable t) void(Marker, String) void(Marker, String, Object...) void(Marker, String throwable) void(Message) void(Message, Throwable t) void(Object) void(Object, Throwable t) void(String) void(String, Object...) void(String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Make sense? N On Jan 26, 2014, at 5:32 PM, Scott Deboy wrote: Yes that's what I was thinking. Scott On Jan 26, 2014 3:18 PM, Remko Popma remko.po...@gmail.com wrote: Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.com wrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the originating level class be included in the classpath. I'm thinking about socketreceiver and to a lesser extent logfilepatternreceiver. Scott On Jan 26, 2014 7:28 AM,
Re: Enums and Custom Levels - completed.
Couldn't we no-op instead of throw if the same identical level were registered? If those levels were then added to the same custom level class from the config, could we use that single class in the logger calls? On Jan 26, 2014 5:15 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(DIAG), hello world); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott On Jan 26, 2014 3:52 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Generating a logger /interface/ is going to be hard. Sure, writing the code automatically will be a piece of cake. But then what do we do with that code? The user needs to program against it. So we have to have a command-line utility or Maven/Ant plug-in to generate the source pre-compile. However, since the vast majority of users are using IDEs, those IDEs will still warn them about the interface not existing until they have run the utility to generate the source. I think a better approach would be to allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void(Marker, Message) void(Marker, Message, Throwable t) void(Marker, Object) void(Marker, Object, Throwable t) void(Marker, String) void(Marker, String, Object...) void(Marker, String throwable) void(Message) void(Message, Throwable t) void(Object) void(Object, Throwable t) void(String) void(String, Object...) void(String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Make sense? N On Jan 26, 2014, at 5:32 PM, Scott Deboy wrote: Yes that's what I was thinking. Scott On Jan 26, 2014 3:18 PM, Remko Popma remko.po...@gmail.com wrote: Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.comwrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven't done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels?
Re: Enums and Custom Levels - completed.
I think I am missing something. First, void(Marker, Message) isn’t a valid method signature so I am not sure what you are really intending. It looks like you specifically did not add the level to the method name and are planning on getting it from the annotation? If so, I don’t see how that works. Once there is an interface it is easy to generate a wrapper logger that uses a proxy to implement the methods. If they are named something like void diag(String msg) then there is no need to annotate them. Ralph On Jan 26, 2014, at 3:51 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Generating a logger /interface/ is going to be hard. Sure, writing the code automatically will be a piece of cake. But then what do we do with that code? The user needs to program against it. So we have to have a command-line utility or Maven/Ant plug-in to generate the source pre-compile. However, since the vast majority of users are using IDEs, those IDEs will still warn them about the interface not existing until they have run the utility to generate the source. I think a better approach would be to allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void(Marker, Message) void(Marker, Message, Throwable t) void(Marker, Object) void(Marker, Object, Throwable t) void(Marker, String) void(Marker, String, Object...) void(Marker, String throwable) void(Message) void(Message, Throwable t) void(Object) void(Object, Throwable t) void(String) void(String, Object...) void(String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Make sense? N On Jan 26, 2014, at 5:32 PM, Scott Deboy wrote: Yes that's what I was thinking. Scott On Jan 26, 2014 3:18 PM, Remko Popma remko.po...@gmail.com wrote: Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.com wrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the originating level class be included in the classpath. I'm thinking about socketreceiver and to a lesser extent logfilepatternreceiver. Scott On Jan 26, 2014 7:28 AM, Scott Deboy scott.de...@gmail.com wrote: So I assume we could build on this by adding the ability to generate these custom levels from the config, with no user provided class required? On Jan 26, 2014 12:58 AM, Ralph Goers ralph.go...@dslextreme.com wrote:
Re: Enums and Custom Levels - completed.
Sorry, I was leaving the method names off because the user can name the methods whatever they want to. They aren't important to the signature as far as Log4j is concerned. You /could/ get the level name from the method name, yes. Using an annotation would allow the user to have a constant, perhaps named DIAG, with a different method name, perhaps named `diagnostic`. Nick On Jan 26, 2014, at 7:25 PM, Ralph Goers wrote: I think I am missing something. First, void(Marker, Message) isn’t a valid method signature so I am not sure what you are really intending. It looks like you specifically did not add the level to the method name and are planning on getting it from the annotation? If so, I don’t see how that works. Once there is an interface it is easy to generate a wrapper logger that uses a proxy to implement the methods. If they are named something like void diag(String msg) then there is no need to annotate them. Ralph On Jan 26, 2014, at 3:51 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Generating a logger /interface/ is going to be hard. Sure, writing the code automatically will be a piece of cake. But then what do we do with that code? The user needs to program against it. So we have to have a command-line utility or Maven/Ant plug-in to generate the source pre-compile. However, since the vast majority of users are using IDEs, those IDEs will still warn them about the interface not existing until they have run the utility to generate the source. I think a better approach would be to allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void(Marker, Message) void(Marker, Message, Throwable t) void(Marker, Object) void(Marker, Object, Throwable t) void(Marker, String) void(Marker, String, Object...) void(Marker, String throwable) void(Message) void(Message, Throwable t) void(Object) void(Object, Throwable t) void(String) void(String, Object...) void(String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Make sense? N On Jan 26, 2014, at 5:32 PM, Scott Deboy wrote: Yes that's what I was thinking. Scott On Jan 26, 2014 3:18 PM, Remko Popma remko.po...@gmail.com wrote: Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.com wrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support for that wherever you want it. Level.StdLevel.getStdLevel() is the method used to do that. Ralph On Jan 26, 2014, at 7:45 AM, Scott Deboy scott.de...@gmail.com wrote: Are these serialization-wise going to be the same as standard levels? Receivers and apps like Chainsaw would benefit from not requiring the
Re: Enums and Custom Levels - completed.
Why would we want that? It is inconsistent with how we currently use Levels and I think it could lead to confusion. What I think should happen is that this Logger wrapper is also where the custom level should be declared. Ralph On Jan 26, 2014, at 5:32 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Sorry, I was leaving the method names off because the user can name the methods whatever they want to. They aren't important to the signature as far as Log4j is concerned. You /could/ get the level name from the method name, yes. Using an annotation would allow the user to have a constant, perhaps named DIAG, with a different method name, perhaps named `diagnostic`. Nick On Jan 26, 2014, at 7:25 PM, Ralph Goers wrote: I think I am missing something. First, void(Marker, Message) isn’t a valid method signature so I am not sure what you are really intending. It looks like you specifically did not add the level to the method name and are planning on getting it from the annotation? If so, I don’t see how that works. Once there is an interface it is easy to generate a wrapper logger that uses a proxy to implement the methods. If they are named something like void diag(String msg) then there is no need to annotate them. Ralph On Jan 26, 2014, at 3:51 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Generating a logger /interface/ is going to be hard. Sure, writing the code automatically will be a piece of cake. But then what do we do with that code? The user needs to program against it. So we have to have a command-line utility or Maven/Ant plug-in to generate the source pre-compile. However, since the vast majority of users are using IDEs, those IDEs will still warn them about the interface not existing until they have run the utility to generate the source. I think a better approach would be to allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void(Marker, Message) void(Marker, Message, Throwable t) void(Marker, Object) void(Marker, Object, Throwable t) void(Marker, String) void(Marker, String, Object...) void(Marker, String throwable) void(Message) void(Message, Throwable t) void(Object) void(Object, Throwable t) void(String) void(String, Object...) void(String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Make sense? N On Jan 26, 2014, at 5:32 PM, Scott Deboy wrote: Yes that's what I was thinking. Scott On Jan 26, 2014 3:18 PM, Remko Popma remko.po...@gmail.com wrote: Scott, The way I interpreted Gary's idea was that based on user-specified custom levels, we would generate an extension of the Logger interface that has a method for each of the custom levels (well, actually 14 methods for each level :-) ). I haven't really thought about how users would specify their custom levels, as long as the tool can know what methods to generate. We could go one step further and generate the Level subclass from configuration as well. I suppose that would entail adding a new Levels element, with sub-elements like Level name=DETAIL intLevel=450 /... Is that what you are thinking of? I would be fine with that too, but would like to first focus on generating the extended Logger interface. On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy scott.de...@gmail.com wrote: Is there a way to generate code/update the Levels enumeration so a new Level class isn't required? Would be great to be able to use logger.detail(Detail message); Is that what you're thinking of, Remko? On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: I haven’t done anything to directly do that. However, custom levels need to be mapped to the standard levels in several places. It would be simple to add support
Re: Enums and Custom Levels - completed.
I think I must be misunderstanding the part about “If those levels were added…”. I don’t understand how a level can be added to a class from the config such that it is usable by a programmer at compile time. Ralph On Jan 26, 2014, at 5:24 PM, Scott Deboy scott.de...@gmail.com wrote: Couldn't we no-op instead of throw if the same identical level were registered? If those levels were then added to the same custom level class from the config, could we use that single class in the logger calls? On Jan 26, 2014 5:15 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(“DIAG”), “hello world”); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott
[jira] [Updated] (LOG4J2-316) Logo Contest Submissions
[ https://issues.apache.org/jira/browse/LOG4J2-316?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] James Devenish updated LOG4J2-316: -- Attachment: Log4j-rectangular.svg Log4j-rectangular.png Attached rectangular logo with '2' as coffee cup handle !Log4j-rectangular.png|thumbnail! Logo Contest Submissions Key: LOG4J2-316 URL: https://issues.apache.org/jira/browse/LOG4J2-316 Project: Log4j 2 Issue Type: Task Reporter: Christian Grobmeier Assignee: Christian Grobmeier Attachments: CarloMatti-Concept.jpg, Log4J2-Attitude.png, Log4J2-Selected.png, Log4j-circular-more.png, Log4j-circular-more.svg, Log4j-circular.png, Log4j-circular.svg, Log4j-combined.png, Log4j-galactica.png, Log4j-rectangular.png, Log4j-rectangular.svg, Log4j-textured.png, Log4j_logo.png, Micah_log4j_icon.png, a_new_log4j2-logo.png, apache-log4j-2.png, apache_log4j2_logo.png, l4j.png, l4j.svg, log4-SE.png, log4.png, log4J2-logo-B.png, log4J2-logo.png, log4J2_Lila.png, log4J2_Orange_Grün.png, log4J2_Schwartz.png, log4J_bunt.png, log4j-2-rnm.png, log4j-2.png, log4j-apache.png, log4j-asap.png, log4j-designmantic.com-1.PNG, log4j-designmantic.com-2.PNG, log4j-designmantic.com-3.PNG, log4j-designmantic.com-4.PNG, log4j-designmantic.com-5.PNG, log4j-designmantic.com-6.PNG, log4j-designmantic.com-7.PNG, log4j-designmantic.com-8.PNG, log4j-stepuk.png, log4j.png, log4j.png, log4j.svg, log4j2(Pasha_G).png, log4j2(logo).png, log4j2(logo)_1.png, log4j2-b.svg, log4j2_e-id.nl.jpg, log4j2_e-id.nl.svg, log4j_2.svg, log4j_idea.jpg, log4j_logo.png, log4j_murdy_1.png, log4j_murdy_10.png, log4j_murdy_11.png, log4j_murdy_11_types.png, log4j_murdy_2.png, log4j_murdy_3.png, log4j_murdy_4.png, log4j_murdy_6.png, log4j_murdy_7.png, log4j_murdy_8.png, log4j_murdy_9.png, logo-log4j-circle.png, logo-log4j-eruption.png, logo-m-nostrokes-condensed.png, logo-m-nostrokes-condensed.svg, logo-m-nostrokes.png, logo-m-nostrokes.svg, logo-m.png, logo-m.svg, logoprop_coffeesteam_131022NS.png, logoprop_monogram_131022NS.png, logoprop_stacked-lj_131022NS.png, tmp_140123_0205221834269922.png h4. Log4J logo contest Log4j 2.0 is looking for a new logo! After 12 years, the Log4j project is getting ready for a brand new major release: version 2.0. This new major version is a reboot of this project in many ways: it is not only time to change the version number to 2.0 but also time to refresh the Log4j logo. Log4j 2 is very different from Log4j 1. Log4j 2 is more reliable and faster than its predecessor and comparable frameworks. The team has grown after years of stagnation and there is now a lot of activity on our lists. We are now approaching the 2.0 release after eight beta releases. With our new logo, we want to show the Java community that Log4j is back. We would like to open participation to the community to create this new logo. h4. HOW TO PARTICIPATE Attach your entries to the Jira: https://issues.apache.org/jira/browse/LOG4J2-316 You can submit as many entries as you like. You must license your Logo under the Apache License 2.0. -The contest will last one month from the date of the announcement.- *UPDATE: The contest ends on 31.01.2014.* If your Logo is accepted, you must sign an ICLA: http://www.apache.org/licenses/icla.txt While we will accept PNG image formats for the contest, we prefer vector based formats (SVG). You can convert pixel-based formats produced with Gimp or Photoshop to SVG with free tools like Inkscape (http://inkscape.org) Please note that a logo should not contain too many details. h4. HOW THE WINNING LOGO IS CHOSEN We invite everyone to vote on the mailing lists. The votes of Apache Logging Committers are binding. If the community submits more than 10 Logos, voting will proceed in two rounds. In the first round, the 10 logos with the most +1 votes graduate to round two. In the second round, the logo with the most +1 will win the contest. The majority of the Apache Logging PMC can veto a logo. We will accept the logo when all votes are successful and the ICLA of the logo contributor is on file. Please ask questions on the dev mailing list. The Log4j team -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
NDN:
Sorry. Your message could not be delivered to: internet,PackerCollegiate (The name was not found at the remote site. Check that the name has been entered correctly.)
Re: Enums and Custom Levels - a few minor changes
I modified Level to be final and have a private constructor. I added a static method named getOrCreateLevel. Custom extensions should use that method to create the static reference. This allows the new Level to be declared in multiple places without a problem as they will all get the same Level instance. I also removed the ordinal and the synchronization associated with it. Ralph On Jan 26, 2014, at 2:40 PM, Nick Williams nicho...@nicholaswilliams.net wrote: I would be OK with getting rid of the ordinal. It makes it less enum-like, but I agree that the ordinal really has little purpose now. The intLevel is more important. Here may be the best approach I can think of for calculating the StandardLevel-equivalent on instantiation: public static Level OFF = new Level(OFF, 0, StandardLevel.OFF) {}; ... public static Level ALL = new Level(ALL, Integer.MAX_VALUE, StandardLevel.ALL); ... private Level(String name, int intLevel, StandardLevel standardLevel) { // this is the only c-tor standard levels use // same logic as current constructor this.standardLevel = standardLevel; } protected Level(String name, int intLevel) { // this is the only c-tor custom levels use this(name, intLevel, Level.calculateStandardLevel(intLevel)); } public enum StandardLevel { OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL } Thoughts? N - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Enums and Custom Levels - completed.
Now Level can't be used in an annotation. Since it supports string names for levels, should I just use Level.toLevel? On 26 January 2014 19:55, Ralph Goers ralph.go...@dslextreme.com wrote: I think I must be misunderstanding the part about “If those levels were added…”. I don’t understand how a level can be added to a class from the config such that it is usable by a programmer at compile time. Ralph On Jan 26, 2014, at 5:24 PM, Scott Deboy scott.de...@gmail.com wrote: Couldn't we no-op instead of throw if the same identical level were registered? If those levels were then added to the same custom level class from the config, could we use that single class in the logger calls? On Jan 26, 2014 5:15 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(“DIAG”), “hello world”); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott -- Matt Sicker boa...@gmail.com
Re: Enums and Custom Levels - completed.
I got lost in the discussion. Can someone please clarify... Is the custom logging interface a nice-to-have or a requirement of the system? I was hoping simply someone could write this (pseudocode below): logger.log(MyCustomLevels.LEVEL1, message); ...so no different interface should be required, right? Can't someone just pass in their log level directly without using one of the named-log-level convenience methods? On Sun, Jan 26, 2014 at 8:37 PM, Matt Sicker boa...@gmail.com wrote: Now Level can't be used in an annotation. Since it supports string names for levels, should I just use Level.toLevel? On 26 January 2014 19:55, Ralph Goers ralph.go...@dslextreme.com wrote: I think I must be misunderstanding the part about “If those levels were added…”. I don’t understand how a level can be added to a class from the config such that it is usable by a programmer at compile time. Ralph On Jan 26, 2014, at 5:24 PM, Scott Deboy scott.de...@gmail.com wrote: Couldn't we no-op instead of throw if the same identical level were registered? If those levels were then added to the same custom level class from the config, could we use that single class in the logger calls? On Jan 26, 2014 5:15 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(“DIAG”), “hello world”); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott -- Matt Sicker boa...@gmail.com -- Cheers, Paul
Re: Enums and Custom Levels - completed.
There are two separate discussions going on here, so it's easy to get lost. We should probably split discussions again. Discussion 1: The finer details of custom levels. I'm fine with using a static factory method and making the constructor private, but I'm not a big fan of the name. Just sounds awkward. Unfortunately, I can't come up with anything better. Discussion 2: A wrapper / extended interface for logging using these custom levels. Yes, Paul, users can just do this: logger.log(MyCustomLevels.LEVEL1, message); That is already supported by making Level extensible. However, some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be a nice-to-have as you call it: logger.note(message); logger.diag(message); etc. We're discussing options to make this possible. However, it is not a requirement to enable custom levels. Custom levels are now already possible. Any objections to breaking discussion 2 off into another thread? Nick On Jan 26, 2014, at 8:46 PM, Paul Benedict wrote: I got lost in the discussion. Can someone please clarify... Is the custom logging interface a nice-to-have or a requirement of the system? I was hoping simply someone could write this (pseudocode below): logger.log(MyCustomLevels.LEVEL1, message); ...so no different interface should be required, right? Can't someone just pass in their log level directly without using one of the named-log-level convenience methods? On Sun, Jan 26, 2014 at 8:37 PM, Matt Sicker boa...@gmail.com wrote: Now Level can't be used in an annotation. Since it supports string names for levels, should I just use Level.toLevel? On 26 January 2014 19:55, Ralph Goers ralph.go...@dslextreme.com wrote: I think I must be misunderstanding the part about “If those levels were added…”. I don’t understand how a level can be added to a class from the config such that it is usable by a programmer at compile time. Ralph On Jan 26, 2014, at 5:24 PM, Scott Deboy scott.de...@gmail.com wrote: Couldn't we no-op instead of throw if the same identical level were registered? If those levels were then added to the same custom level class from the config, could we use that single class in the logger calls? On Jan 26, 2014 5:15 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(“DIAG”), “hello world”); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott -- Matt Sicker boa...@gmail.com -- Cheers, Paul
Re: Enums and Custom Levels - completed.
Yes, logger.log(MyCustomLEvels.LEVEL1, “message”); works right now. See the ExtendedLevels class in log4j-core test as an example on how to declare the level. I think several of us think that finding a way to make it easy to create extended logger methods would be very nice, but I don’t believe it is a requirement. Ralph On Jan 26, 2014, at 6:46 PM, Paul Benedict pbened...@apache.org wrote: I got lost in the discussion. Can someone please clarify... Is the custom logging interface a nice-to-have or a requirement of the system? I was hoping simply someone could write this (pseudocode below): logger.log(MyCustomLevels.LEVEL1, message); ...so no different interface should be required, right? Can't someone just pass in their log level directly without using one of the named-log-level convenience methods? On Sun, Jan 26, 2014 at 8:37 PM, Matt Sicker boa...@gmail.com wrote: Now Level can't be used in an annotation. Since it supports string names for levels, should I just use Level.toLevel? On 26 January 2014 19:55, Ralph Goers ralph.go...@dslextreme.com wrote: I think I must be misunderstanding the part about “If those levels were added…”. I don’t understand how a level can be added to a class from the config such that it is usable by a programmer at compile time. Ralph On Jan 26, 2014, at 5:24 PM, Scott Deboy scott.de...@gmail.com wrote: Couldn't we no-op instead of throw if the same identical level were registered? If those levels were then added to the same custom level class from the config, could we use that single class in the logger calls? On Jan 26, 2014 5:15 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(“DIAG”), “hello world”); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott -- Matt Sicker boa...@gmail.com -- Cheers, Paul
Re: Enums and Custom Levels - completed.
If you break off into another thread, I'll be watching; I'll throw in my 2 cents on how to make a custom Logger interface once that occurs. On Sun, Jan 26, 2014 at 9:01 PM, Ralph Goers ralph.go...@dslextreme.comwrote: Yes, logger.log(MyCustomLEvels.LEVEL1, “message”); works right now. See the ExtendedLevels class in log4j-core test as an example on how to declare the level. I think several of us think that finding a way to make it easy to create extended logger methods would be very nice, but I don’t believe it is a requirement. Ralph On Jan 26, 2014, at 6:46 PM, Paul Benedict pbened...@apache.org wrote: I got lost in the discussion. Can someone please clarify... Is the custom logging interface a nice-to-have or a requirement of the system? I was hoping simply someone could write this (pseudocode below): logger.log(MyCustomLevels.LEVEL1, message); ...so no different interface should be required, right? Can't someone just pass in their log level directly without using one of the named-log-level convenience methods? On Sun, Jan 26, 2014 at 8:37 PM, Matt Sicker boa...@gmail.com wrote: Now Level can't be used in an annotation. Since it supports string names for levels, should I just use Level.toLevel? On 26 January 2014 19:55, Ralph Goers ralph.go...@dslextreme.com wrote: I think I must be misunderstanding the part about “If those levels were added…”. I don’t understand how a level can be added to a class from the config such that it is usable by a programmer at compile time. Ralph On Jan 26, 2014, at 5:24 PM, Scott Deboy scott.de...@gmail.com wrote: Couldn't we no-op instead of throw if the same identical level were registered? If those levels were then added to the same custom level class from the config, could we use that single class in the logger calls? On Jan 26, 2014 5:15 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(“DIAG”), “hello world”); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott -- Matt Sicker boa...@gmail.com -- Cheers, Paul -- Cheers, Paul
Re: Enums and Custom Levels - a few minor changes
The switch in o.a.l.Category.getEffectiveLevel() in log4j-1.2-api is missing the FATAL level (and perhaps OFF also). Is this intentional? On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I modified Level to be final and have a private constructor. I added a static method named getOrCreateLevel. Custom extensions should use that method to create the static reference. This allows the new Level to be declared in multiple places without a problem as they will all get the same Level instance. I also removed the ordinal and the synchronization associated with it. Ralph On Jan 26, 2014, at 2:40 PM, Nick Williams nicho...@nicholaswilliams.netjavascript:; wrote: I would be OK with getting rid of the ordinal. It makes it less enum-like, but I agree that the ordinal really has little purpose now. The intLevel is more important. Here may be the best approach I can think of for calculating the StandardLevel-equivalent on instantiation: public static Level OFF = new Level(OFF, 0, StandardLevel.OFF) {}; ... public static Level ALL = new Level(ALL, Integer.MAX_VALUE, StandardLevel.ALL); ... private Level(String name, int intLevel, StandardLevel standardLevel) { // this is the only c-tor standard levels use // same logic as current constructor this.standardLevel = standardLevel; } protected Level(String name, int intLevel) { // this is the only c-tor custom levels use this(name, intLevel, Level.calculateStandardLevel(intLevel)); } public enum StandardLevel { OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL } Thoughts? N - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.orgjavascript:; For additional commands, e-mail: log4j-dev-h...@logging.apache.orgjavascript:;
Re: Enums and Custom Levels - completed.
No objections on spawning a separate thread for discussion 2. I also am not in love with the method name but it does describe what it does. If anyone has any ideas on a better name please suggest it (we are talking about the getOrCreateLevel method name). Ralph On Jan 26, 2014, at 6:59 PM, Nick Williams nicho...@nicholaswilliams.net wrote: There are two separate discussions going on here, so it's easy to get lost. We should probably split discussions again. Discussion 1: The finer details of custom levels. I'm fine with using a static factory method and making the constructor private, but I'm not a big fan of the name. Just sounds awkward. Unfortunately, I can't come up with anything better. Discussion 2: A wrapper / extended interface for logging using these custom levels. Yes, Paul, users can just do this: logger.log(MyCustomLevels.LEVEL1, message); That is already supported by making Level extensible. However, some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be a nice-to-have as you call it: logger.note(message); logger.diag(message); etc. We're discussing options to make this possible. However, it is not a requirement to enable custom levels. Custom levels are now already possible. Any objections to breaking discussion 2 off into another thread? Nick On Jan 26, 2014, at 8:46 PM, Paul Benedict wrote: I got lost in the discussion. Can someone please clarify... Is the custom logging interface a nice-to-have or a requirement of the system? I was hoping simply someone could write this (pseudocode below): logger.log(MyCustomLevels.LEVEL1, message); ...so no different interface should be required, right? Can't someone just pass in their log level directly without using one of the named-log-level convenience methods? On Sun, Jan 26, 2014 at 8:37 PM, Matt Sicker boa...@gmail.com wrote: Now Level can't be used in an annotation. Since it supports string names for levels, should I just use Level.toLevel? On 26 January 2014 19:55, Ralph Goers ralph.go...@dslextreme.com wrote: I think I must be misunderstanding the part about “If those levels were added…”. I don’t understand how a level can be added to a class from the config such that it is usable by a programmer at compile time. Ralph On Jan 26, 2014, at 5:24 PM, Scott Deboy scott.de...@gmail.com wrote: Couldn't we no-op instead of throw if the same identical level were registered? If those levels were then added to the same custom level class from the config, could we use that single class in the logger calls? On Jan 26, 2014 5:15 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(“DIAG”), “hello world”); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott -- Matt Sicker boa...@gmail.com -- Cheers, Paul
Re: Enums and Custom Levels - a few minor changes
You mentioned that before and I didn’t check since it has been that way from the beginning. Yes it looks like a bug to me. Ralph On Jan 26, 2014, at 7:06 PM, Remko Popma remko.po...@gmail.com wrote: The switch in o.a.l.Category.getEffectiveLevel() in log4j-1.2-api is missing the FATAL level (and perhaps OFF also). Is this intentional? On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I modified Level to be final and have a private constructor. I added a static method named getOrCreateLevel. Custom extensions should use that method to create the static reference. This allows the new Level to be declared in multiple places without a problem as they will all get the same Level instance. I also removed the ordinal and the synchronization associated with it. Ralph On Jan 26, 2014, at 2:40 PM, Nick Williams nicho...@nicholaswilliams.net wrote: I would be OK with getting rid of the ordinal. It makes it less enum-like, but I agree that the ordinal really has little purpose now. The intLevel is more important. Here may be the best approach I can think of for calculating the StandardLevel-equivalent on instantiation: public static Level OFF = new Level(OFF, 0, StandardLevel.OFF) {}; ... public static Level ALL = new Level(ALL, Integer.MAX_VALUE, StandardLevel.ALL); ... private Level(String name, int intLevel, StandardLevel standardLevel) { // this is the only c-tor standard levels use // same logic as current constructor this.standardLevel = standardLevel; } protected Level(String name, int intLevel) { // this is the only c-tor custom levels use this(name, intLevel, Level.calculateStandardLevel(intLevel)); } public enum StandardLevel { OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL } Thoughts? N - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Enums and Custom Levels - a few minor changes
Understood. I can't commit from work but I can fix this when I get home tonight. On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: You mentioned that before and I didn’t check since it has been that way from the beginning. Yes it looks like a bug to me. Ralph On Jan 26, 2014, at 7:06 PM, Remko Popma remko.po...@gmail.comjavascript:_e({}, 'cvml', 'remko.po...@gmail.com'); wrote: The switch in o.a.l.Category.getEffectiveLevel() in log4j-1.2-api is missing the FATAL level (and perhaps OFF also). Is this intentional? On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.comjavascript:_e({}, 'cvml', 'ralph.go...@dslextreme.com'); wrote: I modified Level to be final and have a private constructor. I added a static method named getOrCreateLevel. Custom extensions should use that method to create the static reference. This allows the new Level to be declared in multiple places without a problem as they will all get the same Level instance. I also removed the ordinal and the synchronization associated with it. Ralph On Jan 26, 2014, at 2:40 PM, Nick Williams nicho...@nicholaswilliams.net wrote: I would be OK with getting rid of the ordinal. It makes it less enum-like, but I agree that the ordinal really has little purpose now. The intLevel is more important. Here may be the best approach I can think of for calculating the StandardLevel-equivalent on instantiation: public static Level OFF = new Level(OFF, 0, StandardLevel.OFF) {}; ... public static Level ALL = new Level(ALL, Integer.MAX_VALUE, StandardLevel.ALL); ... private Level(String name, int intLevel, StandardLevel standardLevel) { // this is the only c-tor standard levels use // same logic as current constructor this.standardLevel = standardLevel; } protected Level(String name, int intLevel) { // this is the only c-tor custom levels use this(name, intLevel, Level.calculateStandardLevel(intLevel)); } public enum StandardLevel { OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL } Thoughts? N - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Enums and Custom Levels - completed.
How about Level.forName()? On 26 January 2014 21:06, Ralph Goers ralph.go...@dslextreme.com wrote: No objections on spawning a separate thread for discussion 2. I also am not in love with the method name but it does describe what it does. If anyone has any ideas on a better name please suggest it (we are talking about the getOrCreateLevel method name). Ralph On Jan 26, 2014, at 6:59 PM, Nick Williams nicho...@nicholaswilliams.net wrote: There are two separate discussions going on here, so it's easy to get lost. We should probably split discussions again. Discussion 1: The finer details of custom levels. I'm fine with using a static factory method and making the constructor private, but I'm not a big fan of the name. Just sounds awkward. Unfortunately, I can't come up with anything better. Discussion 2: A wrapper / extended interface for logging using these custom levels. Yes, Paul, users can just do this: logger.log(MyCustomLevels.LEVEL1, message); That is already supported by making Level extensible. However, some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be a nice-to-have as you call it: logger.note(message); logger.diag(message); etc. We're discussing options to make this possible. However, it is not a requirement to enable custom levels. Custom levels are now already possible. Any objections to breaking discussion 2 off into another thread? Nick On Jan 26, 2014, at 8:46 PM, Paul Benedict wrote: I got lost in the discussion. Can someone please clarify... Is the custom logging interface a nice-to-have or a requirement of the system? I was hoping simply someone could write this (pseudocode below): logger.log(MyCustomLevels.LEVEL1, message); ...so no different interface should be required, right? Can't someone just pass in their log level directly without using one of the named-log-level convenience methods? On Sun, Jan 26, 2014 at 8:37 PM, Matt Sicker boa...@gmail.com wrote: Now Level can't be used in an annotation. Since it supports string names for levels, should I just use Level.toLevel? On 26 January 2014 19:55, Ralph Goers ralph.go...@dslextreme.com wrote: I think I must be misunderstanding the part about “If those levels were added…”. I don’t understand how a level can be added to a class from the config such that it is usable by a programmer at compile time. Ralph On Jan 26, 2014, at 5:24 PM, Scott Deboy scott.de...@gmail.com wrote: Couldn't we no-op instead of throw if the same identical level were registered? If those levels were then added to the same custom level class from the config, could we use that single class in the logger calls? On Jan 26, 2014 5:15 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(“DIAG”), “hello world”); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott -- Matt Sicker boa...@gmail.com -- Cheers, Paul -- Matt Sicker boa...@gmail.com
Re: ApacheCon CFP
I would like to attend but I’m not sure I can. Ralph On Jan 25, 2014, at 11:11 AM, Christian Grobmeier grobme...@gmail.com wrote: Hi folks, I would like to remind you ApacheCon is happening in April 2014. If you would like to submit your talk, now is the chance. I think it would be great to have somebody presenting our Logging frameworks. I will not be there unfortunately. Regards, Christian --- http://www.grobmeier.de The Zen Programmer: http://bit.ly/12lC6DL @grobmeier GPG: 0xA5CC90DB - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Using Custom Levels with a Custom/Wrapper Interface
Here's a split-off thread for discussing how we can make using custom levels easier. Some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be nice to have: logger.note(message); logger.diag(message); etc. We're to discuss how best to approach this. My proposal (from previous email): Allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void [methodName](Marker, Message) void [methodName](Marker, Message, Throwable t) void [methodName](Marker, Object) void [methodName](Marker, Object, Throwable t) void [methodName](Marker, String) void [methodName](Marker, String, Object...) void [methodName](Marker, String throwable) void [methodName](Message) void [methodName](Message, Throwable t) void [methodName](Object) void [methodName](Object, Throwable t) void [methodName](String) void [methodName](String, Object...) void [methodName](String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Others have suggested deriving the level name from the method name instead of using an annotation. That's a viable alternative. Matt Sicker asked: And can't getCustomLogger also provide a default method that uses the getClassName method? I think you misunderstand the purpose of the ClassT argument. It has nothing to do with the logger name--it's the class of the Logger interface to automatically implement. Nick - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Using Custom Levels with a Custom/Wrapper Interface
If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Here's a split-off thread for discussing how we can make using custom levels easier. Some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be nice to have: logger.note(message); logger.diag(message); etc. We're to discuss how best to approach this. My proposal (from previous email): Allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void [methodName](Marker, Message) void [methodName](Marker, Message, Throwable t) void [methodName](Marker, Object) void [methodName](Marker, Object, Throwable t) void [methodName](Marker, String) void [methodName](Marker, String, Object...) void [methodName](Marker, String throwable) void [methodName](Message) void [methodName](Message, Throwable t) void [methodName](Object) void [methodName](Object, Throwable t) void [methodName](String) void [methodName](String, Object...) void [methodName](String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Others have suggested deriving the level name from the method name instead of using an annotation. That's a viable alternative. Matt Sicker asked: And can't getCustomLogger also provide a default method that uses the getClassName method? I think you misunderstand the purpose of the ClassT argument. It has nothing to do with the logger name--it's the class of the Logger interface to automatically implement. Nick - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Using Custom Levels with a Custom/Wrapper Interface
It would not be possible to do this strictly through configuration because the user needs a compiled interface to code against. Where is that compiled interface to come from? Nick On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Here's a split-off thread for discussing how we can make using custom levels easier. Some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be nice to have: logger.note(message); logger.diag(message); etc. We're to discuss how best to approach this. My proposal (from previous email): Allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void [methodName](Marker, Message) void [methodName](Marker, Message, Throwable t) void [methodName](Marker, Object) void [methodName](Marker, Object, Throwable t) void [methodName](Marker, String) void [methodName](Marker, String, Object...) void [methodName](Marker, String throwable) void [methodName](Message) void [methodName](Message, Throwable t) void [methodName](Object) void [methodName](Object, Throwable t) void [methodName](String) void [methodName](String, Object...) void [methodName](String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Others have suggested deriving the level name from the method name instead of using an annotation. That's a viable alternative. Matt Sicker asked: And can't getCustomLogger also provide a default method that uses the getClassName method? I think you misunderstand the purpose of the ClassT argument. It has nothing to do with the logger name--it's the class of the Logger interface to automatically implement. Nick - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Enums and Custom Levels - completed.
Level.forName wouldn't work--it's not just for name, it's for the name /and/ the level. But it must be unique by the name. For that matter, what are we to do in the following situation? Level.getOrCreate(DIAG, 150); ... Level.getOrCreate(DIAG, 250); They're not going to get what they expect in both cases. Nick On Jan 26, 2014, at 9:28 PM, Matt Sicker wrote: How about Level.forName()? On 26 January 2014 21:06, Ralph Goers ralph.go...@dslextreme.com wrote: No objections on spawning a separate thread for discussion 2. I also am not in love with the method name but it does describe what it does. If anyone has any ideas on a better name please suggest it (we are talking about the getOrCreateLevel method name). Ralph On Jan 26, 2014, at 6:59 PM, Nick Williams nicho...@nicholaswilliams.net wrote: There are two separate discussions going on here, so it's easy to get lost. We should probably split discussions again. Discussion 1: The finer details of custom levels. I'm fine with using a static factory method and making the constructor private, but I'm not a big fan of the name. Just sounds awkward. Unfortunately, I can't come up with anything better. Discussion 2: A wrapper / extended interface for logging using these custom levels. Yes, Paul, users can just do this: logger.log(MyCustomLevels.LEVEL1, message); That is already supported by making Level extensible. However, some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be a nice-to-have as you call it: logger.note(message); logger.diag(message); etc. We're discussing options to make this possible. However, it is not a requirement to enable custom levels. Custom levels are now already possible. Any objections to breaking discussion 2 off into another thread? Nick On Jan 26, 2014, at 8:46 PM, Paul Benedict wrote: I got lost in the discussion. Can someone please clarify... Is the custom logging interface a nice-to-have or a requirement of the system? I was hoping simply someone could write this (pseudocode below): logger.log(MyCustomLevels.LEVEL1, message); ...so no different interface should be required, right? Can't someone just pass in their log level directly without using one of the named-log-level convenience methods? On Sun, Jan 26, 2014 at 8:37 PM, Matt Sicker boa...@gmail.com wrote: Now Level can't be used in an annotation. Since it supports string names for levels, should I just use Level.toLevel? On 26 January 2014 19:55, Ralph Goers ralph.go...@dslextreme.com wrote: I think I must be misunderstanding the part about “If those levels were added…”. I don’t understand how a level can be added to a class from the config such that it is usable by a programmer at compile time. Ralph On Jan 26, 2014, at 5:24 PM, Scott Deboy scott.de...@gmail.com wrote: Couldn't we no-op instead of throw if the same identical level were registered? If those levels were then added to the same custom level class from the config, could we use that single class in the logger calls? On Jan 26, 2014 5:15 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(“DIAG”), “hello world”); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott -- Matt Sicker boa...@gmail.com -- Cheers, Paul -- Matt Sicker boa...@gmail.com
Re: Enums and Custom Levels - completed.
I second my suggestion! On 26 January 2014 21:44, Ralph Goers ralph.go...@dslextreme.com wrote: My first gut reaction was confusion over Class.forName(). But then in thinking about it that name does behave a lot like what Class.forName() does, except with a Level. So I think I do like it better than the current name. Any other thoughts or opinions? Ralph On Jan 26, 2014, at 7:28 PM, Matt Sicker boa...@gmail.com wrote: How about Level.forName()? On 26 January 2014 21:06, Ralph Goers ralph.go...@dslextreme.com wrote: No objections on spawning a separate thread for discussion 2. I also am not in love with the method name but it does describe what it does. If anyone has any ideas on a better name please suggest it (we are talking about the getOrCreateLevel method name). Ralph On Jan 26, 2014, at 6:59 PM, Nick Williams nicho...@nicholaswilliams.net wrote: There are two separate discussions going on here, so it's easy to get lost. We should probably split discussions again. Discussion 1: The finer details of custom levels. I'm fine with using a static factory method and making the constructor private, but I'm not a big fan of the name. Just sounds awkward. Unfortunately, I can't come up with anything better. Discussion 2: A wrapper / extended interface for logging using these custom levels. Yes, Paul, users can just do this: logger.log(MyCustomLevels.LEVEL1, message); That is already supported by making Level extensible. However, some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be a nice-to-have as you call it: logger.note(message); logger.diag(message); etc. We're discussing options to make this possible. However, it is not a requirement to enable custom levels. Custom levels are now already possible. Any objections to breaking discussion 2 off into another thread? Nick On Jan 26, 2014, at 8:46 PM, Paul Benedict wrote: I got lost in the discussion. Can someone please clarify... Is the custom logging interface a nice-to-have or a requirement of the system? I was hoping simply someone could write this (pseudocode below): logger.log(MyCustomLevels.LEVEL1, message); ...so no different interface should be required, right? Can't someone just pass in their log level directly without using one of the named-log-level convenience methods? On Sun, Jan 26, 2014 at 8:37 PM, Matt Sicker boa...@gmail.com wrote: Now Level can't be used in an annotation. Since it supports string names for levels, should I just use Level.toLevel? On 26 January 2014 19:55, Ralph Goers ralph.go...@dslextreme.comwrote: I think I must be misunderstanding the part about “If those levels were added…”. I don’t understand how a level can be added to a class from the config such that it is usable by a programmer at compile time. Ralph On Jan 26, 2014, at 5:24 PM, Scott Deboy scott.de...@gmail.com wrote: Couldn't we no-op instead of throw if the same identical level were registered? If those levels were then added to the same custom level class from the config, could we use that single class in the logger calls? On Jan 26, 2014 5:15 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(“DIAG”), “hello world”); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott -- Matt Sicker boa...@gmail.com -- Cheers, Paul -- Matt Sicker boa...@gmail.com -- Matt Sicker boa...@gmail.com
Re: Using Custom Levels with a Custom/Wrapper Interface
The JPA criteria API manages to generate a Foo_ class for the entity class Foo, and that seems to work out fine. On 26 January 2014 21:45, Nick Williams nicho...@nicholaswilliams.netwrote: It would not be possible to do this strictly through configuration because the user needs a compiled interface to code against. Where is that compiled interface to come from? Nick On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Here's a split-off thread for discussing how we can make using custom levels easier. Some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be nice to have: logger.note(message); logger.diag(message); etc. We're to discuss how best to approach this. My proposal (from previous email): Allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void [methodName](Marker, Message) void [methodName](Marker, Message, Throwable t) void [methodName](Marker, Object) void [methodName](Marker, Object, Throwable t) void [methodName](Marker, String) void [methodName](Marker, String, Object...) void [methodName](Marker, String throwable) void [methodName](Message) void [methodName](Message, Throwable t) void [methodName](Object) void [methodName](Object, Throwable t) void [methodName](String) void [methodName](String, Object...) void [methodName](String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Others have suggested deriving the level name from the method name instead of using an annotation. That's a viable alternative. Matt Sicker asked: And can't getCustomLogger also provide a default method that uses the getClassName method? I think you misunderstand the purpose of the ClassT argument. It has nothing to do with the logger name--it's the class of the Logger interface to automatically implement. Nick - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org -- Matt Sicker boa...@gmail.com
Re: Using Custom Levels with a Custom/Wrapper Interface
I am going to have to echo what Nick said. If you can think of a way to make logger.log(SomeClass.SomeLevel, “hello world”); work without actually creating SomeClass then please share! Ralph On Jan 26, 2014, at 7:45 PM, Nick Williams nicho...@nicholaswilliams.net wrote: It would not be possible to do this strictly through configuration because the user needs a compiled interface to code against. Where is that compiled interface to come from? Nick On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Here's a split-off thread for discussing how we can make using custom levels easier. Some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be nice to have: logger.note(message); logger.diag(message); etc. We're to discuss how best to approach this. My proposal (from previous email): Allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void [methodName](Marker, Message) void [methodName](Marker, Message, Throwable t) void [methodName](Marker, Object) void [methodName](Marker, Object, Throwable t) void [methodName](Marker, String) void [methodName](Marker, String, Object...) void [methodName](Marker, String throwable) void [methodName](Message) void [methodName](Message, Throwable t) void [methodName](Object) void [methodName](Object, Throwable t) void [methodName](String) void [methodName](String, Object...) void [methodName](String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Others have suggested deriving the level name from the method name instead of using an annotation. That's a viable alternative. Matt Sicker asked: And can't getCustomLogger also provide a default method that uses the getClassName method? I think you misunderstand the purpose of the ClassT argument. It has nothing to do with the logger name--it's the class of the Logger interface to automatically implement. Nick - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Enums and Custom Levels - completed.
Perhaps if we called the priority or ordinal power, then we'd have a great time with the naming scheme? On 26 January 2014 21:46, Nick Williams nicho...@nicholaswilliams.netwrote: Level.forName wouldn't work--it's not just for name, it's for the name /and/ the level. But it must be unique by the name. For that matter, what are we to do in the following situation? Level.getOrCreate(DIAG, 150); ... Level.getOrCreate(DIAG, 250); They're not going to get what they expect in both cases. Nick On Jan 26, 2014, at 9:28 PM, Matt Sicker wrote: How about Level.forName()? On 26 January 2014 21:06, Ralph Goers ralph.go...@dslextreme.com wrote: No objections on spawning a separate thread for discussion 2. I also am not in love with the method name but it does describe what it does. If anyone has any ideas on a better name please suggest it (we are talking about the getOrCreateLevel method name). Ralph On Jan 26, 2014, at 6:59 PM, Nick Williams nicho...@nicholaswilliams.net wrote: There are two separate discussions going on here, so it's easy to get lost. We should probably split discussions again. Discussion 1: The finer details of custom levels. I'm fine with using a static factory method and making the constructor private, but I'm not a big fan of the name. Just sounds awkward. Unfortunately, I can't come up with anything better. Discussion 2: A wrapper / extended interface for logging using these custom levels. Yes, Paul, users can just do this: logger.log(MyCustomLevels.LEVEL1, message); That is already supported by making Level extensible. However, some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be a nice-to-have as you call it: logger.note(message); logger.diag(message); etc. We're discussing options to make this possible. However, it is not a requirement to enable custom levels. Custom levels are now already possible. Any objections to breaking discussion 2 off into another thread? Nick On Jan 26, 2014, at 8:46 PM, Paul Benedict wrote: I got lost in the discussion. Can someone please clarify... Is the custom logging interface a nice-to-have or a requirement of the system? I was hoping simply someone could write this (pseudocode below): logger.log(MyCustomLevels.LEVEL1, message); ...so no different interface should be required, right? Can't someone just pass in their log level directly without using one of the named-log-level convenience methods? On Sun, Jan 26, 2014 at 8:37 PM, Matt Sicker boa...@gmail.com wrote: Now Level can't be used in an annotation. Since it supports string names for levels, should I just use Level.toLevel? On 26 January 2014 19:55, Ralph Goers ralph.go...@dslextreme.comwrote: I think I must be misunderstanding the part about “If those levels were added…”. I don’t understand how a level can be added to a class from the config such that it is usable by a programmer at compile time. Ralph On Jan 26, 2014, at 5:24 PM, Scott Deboy scott.de...@gmail.com wrote: Couldn't we no-op instead of throw if the same identical level were registered? If those levels were then added to the same custom level class from the config, could we use that single class in the logger calls? On Jan 26, 2014 5:15 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(“DIAG”), “hello world”); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott -- Matt Sicker boa...@gmail.com -- Cheers, Paul -- Matt Sicker boa...@gmail.com -- Matt Sicker boa...@gmail.com
Re: Enums and Custom Levels - completed.
I disagree - you are getting the Level that matches the name, so forName does describe what is happening. See the Javadoc on the second question. The intValue is ignored unless the Level is created. Yes, that could lead to some problems if there are conflicts, but I think returning the registered level is better than throwing an exception. Ralph On Jan 26, 2014, at 7:46 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Level.forName wouldn't work--it's not just for name, it's for the name /and/ the level. But it must be unique by the name. For that matter, what are we to do in the following situation? Level.getOrCreate(DIAG, 150); ... Level.getOrCreate(DIAG, 250); They're not going to get what they expect in both cases. Nick On Jan 26, 2014, at 9:28 PM, Matt Sicker wrote: How about Level.forName()? On 26 January 2014 21:06, Ralph Goers ralph.go...@dslextreme.com wrote: No objections on spawning a separate thread for discussion 2. I also am not in love with the method name but it does describe what it does. If anyone has any ideas on a better name please suggest it (we are talking about the getOrCreateLevel method name). Ralph On Jan 26, 2014, at 6:59 PM, Nick Williams nicho...@nicholaswilliams.net wrote: There are two separate discussions going on here, so it's easy to get lost. We should probably split discussions again. Discussion 1: The finer details of custom levels. I'm fine with using a static factory method and making the constructor private, but I'm not a big fan of the name. Just sounds awkward. Unfortunately, I can't come up with anything better. Discussion 2: A wrapper / extended interface for logging using these custom levels. Yes, Paul, users can just do this: logger.log(MyCustomLevels.LEVEL1, message); That is already supported by making Level extensible. However, some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be a nice-to-have as you call it: logger.note(message); logger.diag(message); etc. We're discussing options to make this possible. However, it is not a requirement to enable custom levels. Custom levels are now already possible. Any objections to breaking discussion 2 off into another thread? Nick On Jan 26, 2014, at 8:46 PM, Paul Benedict wrote: I got lost in the discussion. Can someone please clarify... Is the custom logging interface a nice-to-have or a requirement of the system? I was hoping simply someone could write this (pseudocode below): logger.log(MyCustomLevels.LEVEL1, message); ...so no different interface should be required, right? Can't someone just pass in their log level directly without using one of the named-log-level convenience methods? On Sun, Jan 26, 2014 at 8:37 PM, Matt Sicker boa...@gmail.com wrote: Now Level can't be used in an annotation. Since it supports string names for levels, should I just use Level.toLevel? On 26 January 2014 19:55, Ralph Goers ralph.go...@dslextreme.com wrote: I think I must be misunderstanding the part about “If those levels were added…”. I don’t understand how a level can be added to a class from the config such that it is usable by a programmer at compile time. Ralph On Jan 26, 2014, at 5:24 PM, Scott Deboy scott.de...@gmail.com wrote: Couldn't we no-op instead of throw if the same identical level were registered? If those levels were then added to the same custom level class from the config, could we use that single class in the logger calls? On Jan 26, 2014 5:15 PM, Ralph Goers ralph.go...@dslextreme.com wrote: I am certain I could create a LevelPlugin that would allow you to define one or more Levels in the configuration, but to use that Level the user would have to code: logger.log(Level.toLevel(“DIAG”), “hello world”); In order to directly reference the level it has to be declared as a static from somewhere and it can only be instantiated a single time, so creating it from the configuration will prevent that. Ralph On Jan 26, 2014, at 4:03 PM, Scott Deboy scott.de...@gmail.com wrote: I have one goal: to remove my request for new built in levels by allowing the levels to be defined strictly via configuration. I agree there may be some hurdles but that's my goal. I'd like to avoid the requirement that users provide their own level implementation or use a different API. Scott -- Matt Sicker boa...@gmail.com -- Cheers, Paul -- Matt Sicker boa...@gmail.com
[jira] [Updated] (LOG4J2-512) Log4j2 need to support Asynchronous Servlets/ Servlet 3.0 while automatically starting, and configurable to initialize and de-initialize loggers from the code
[ https://issues.apache.org/jira/browse/LOG4J2-512?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Chandra Sekhar Kakarla updated LOG4J2-512: -- Description: Async servlet (async-supported=true) using with log4j2 breaks the async chain because it does not support async. All element in the chain must support async in order to use async. Implementation is required to support async servlets(async-supportd=true) it may be automatic or configurable initialization. ( this Issue may be dependent on the issue https://issues.apache.org/jira/browse/LOG4J2-270 ) Initialization and de-initialization of the logger must be configurable in the java code/config files, to re-load the logger with different properties, that will help the application to reduce re-start burden when it need to use different properties. was: Async servlet (async-supported=true) using with log4j2 breaks the async chain because it does not support async. All element in the chain must support async in order to use async. Implementation is required to support async servlets(async-supportd=true) it may be automatic or configurable initialization. Initialization and de-initialization of the logger must be configurable in the java code/config files, to re-load the logger with different properties, that will help the application to reduce re-start burden when it need to use different properties. Log4j2 need to support Asynchronous Servlets/ Servlet 3.0 while automatically starting, and configurable to initialize and de-initialize loggers from the code Key: LOG4J2-512 URL: https://issues.apache.org/jira/browse/LOG4J2-512 Project: Log4j 2 Issue Type: Sub-task Components: Configurators, Core, Documentation, Filters Affects Versions: 2.0-beta8, 2.0-beta9 Reporter: Chandra Sekhar Kakarla Labels: asynchronous, configuration, destroy, filters, initialization, listener, log4j2, log4j2.xml, restart, servlet, servlet-context Original Estimate: 466h Remaining Estimate: 466h Async servlet (async-supported=true) using with log4j2 breaks the async chain because it does not support async. All element in the chain must support async in order to use async. Implementation is required to support async servlets(async-supportd=true) it may be automatic or configurable initialization. ( this Issue may be dependent on the issue https://issues.apache.org/jira/browse/LOG4J2-270 ) Initialization and de-initialization of the logger must be configurable in the java code/config files, to re-load the logger with different properties, that will help the application to reduce re-start burden when it need to use different properties. -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Using Custom Levels with a Custom/Wrapper Interface
I actually thought that Nick's idea was the answer to that: users create a custom interface, something like this: public interface MyLogger extends Logger { @LoggingLevel(name=DIAG) void diag(String message); // optional other methods } They get an instance of this interface by calling: LogManager.getCustomLogger(MyLogger.class); LogManager has access to the processed configuration. The config has LevelsLevel name=DIAG intValue=450 elements. During configuration processing, the custom Level instances are created and registered, so on the first call to LogManager.getCustomLogger(MyLogger.class), the MyLogger instance is created and cached. Also, at this point the annotations are parsed to see what Level instance the MyLogger implementation will pass to the Logger.log(Level, String) method when the diag method is called. What is still open in this scenario is how the instance is created. Proxy? Or generate source compile? Or use a byte code library? On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I am going to have to echo what Nick said. If you can think of a way to make logger.log(SomeClass.SomeLevel, “hello world”); work without actually creating SomeClass then please share! Ralph On Jan 26, 2014, at 7:45 PM, Nick Williams nicho...@nicholaswilliams.netjavascript:_e({}, 'cvml', 'nicho...@nicholaswilliams.net'); wrote: It would not be possible to do this strictly through configuration because the user needs a compiled interface to code against. Where is that compiled interface to come from? Nick On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams nicho...@nicholaswilliams.netjavascript:_e({}, 'cvml', 'nicho...@nicholaswilliams.net'); wrote: Here's a split-off thread for discussing how we can make using custom levels easier. Some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be nice to have: logger.note(message); logger.diag(message); etc. We're to discuss how best to approach this. My proposal (from previous email): Allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void [methodName](Marker, Message) void [methodName](Marker, Message, Throwable t) void [methodName](Marker, Object) void [methodName](Marker, Object, Throwable t) void [methodName](Marker, String) void [methodName](Marker, String, Object...) void [methodName](Marker, String throwable) void [methodName](Message) void [methodName](Message, Throwable t) void [methodName](Object) void [methodName](Object, Throwable t) void [methodName](String) void [methodName](String, Object...) void [methodName](String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Others have suggested deriving the level name from the method name instead of using an annotation. That's a viable alternative. Matt Sicker asked: And can't getCustomLogger also provide a default method that uses the getClassName method? I think you misunderstand the purpose of the ClassT argument. It has nothing to do with the logger name--it's the class of the Logger interface to automatically implement. Nick - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.orgjavascript:_e({}, 'cvml', 'log4j-dev-unsubscr...@logging.apache.org'); For additional commands, e-mail: log4j-dev-h...@logging.apache.orgjavascript:_e({}, 'cvml',
[jira] [Updated] (LOG4J2-512) Log4j2 need to support Asynchronous Servlets/ Servlet 3.0 while automatically starting, and configurable to initialize and de-initialize loggers from the code
[ https://issues.apache.org/jira/browse/LOG4J2-512?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Chandra Sekhar Kakarla updated LOG4J2-512: -- Affects Version/s: 2.0-beta8 Log4j2 need to support Asynchronous Servlets/ Servlet 3.0 while automatically starting, and configurable to initialize and de-initialize loggers from the code Key: LOG4J2-512 URL: https://issues.apache.org/jira/browse/LOG4J2-512 Project: Log4j 2 Issue Type: Sub-task Components: Configurators, Core, Documentation, Filters Affects Versions: 2.0-beta8, 2.0-beta9 Reporter: Chandra Sekhar Kakarla Labels: asynchronous, configuration, destroy, filters, initialization, listener, log4j2, log4j2.xml, restart, servlet, servlet-context Original Estimate: 466h Remaining Estimate: 466h Async servlet (async-supported=true) using with log4j2 breaks the async chain because it does not support async. All element in the chain must support async in order to use async. Implementation is required to support async servlets(async-supportd=true) it may be automatic or configurable initialization. Initialization and de-initialization of the logger must be configurable in the java code/config files, to re-load the logger with different properties, that will help the application to reduce re-start burden when it need to use different properties. -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Using Custom Levels with a Custom/Wrapper Interface
Scott would like users to add a level definition to the logging configuration and have everything else happen auto-magically. That would happen at run-time which is a bit late since the methods need to be available at compile time. I believe Scott said he would be fine if users had to do logger.log(SomeClass.SomeLevel, “message); but even that requires “SomeClass” to be available at compile time. So what Scott says he would like and what Nick is proposing are two different things. Ralph On Jan 26, 2014, at 8:09 PM, Remko Popma remko.po...@gmail.com wrote: I actually thought that Nick's idea was the answer to that: users create a custom interface, something like this: public interface MyLogger extends Logger { @LoggingLevel(name=DIAG) void diag(String message); // optional other methods } They get an instance of this interface by calling: LogManager.getCustomLogger(MyLogger.class); LogManager has access to the processed configuration. The config has LevelsLevel name=DIAG intValue=450 elements. During configuration processing, the custom Level instances are created and registered, so on the first call to LogManager.getCustomLogger(MyLogger.class), the MyLogger instance is created and cached. Also, at this point the annotations are parsed to see what Level instance the MyLogger implementation will pass to the Logger.log(Level, String) method when the diag method is called. What is still open in this scenario is how the instance is created. Proxy? Or generate source compile? Or use a byte code library? On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I am going to have to echo what Nick said. If you can think of a way to make logger.log(SomeClass.SomeLevel, “hello world”); work without actually creating SomeClass then please share! Ralph On Jan 26, 2014, at 7:45 PM, Nick Williams nicho...@nicholaswilliams.net wrote: It would not be possible to do this strictly through configuration because the user needs a compiled interface to code against. Where is that compiled interface to come from? Nick On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Here's a split-off thread for discussing how we can make using custom levels easier. Some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be nice to have: logger.note(message); logger.diag(message); etc. We're to discuss how best to approach this. My proposal (from previous email): Allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void [methodName](Marker, Message) void [methodName](Marker, Message, Throwable t) void [methodName](Marker, Object) void [methodName](Marker, Object, Throwable t) void [methodName](Marker, String) void [methodName](Marker, String, Object...) void [methodName](Marker, String throwable) void [methodName](Message) void [methodName](Message, Throwable t) void [methodName](Object) void [methodName](Object, Throwable t) void [methodName](String) void [methodName](String, Object...) void [methodName](String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented again, and then instantiate/cache the logger instance like normal. Others have suggested deriving the level name from the method name instead of using an annotation. That's a viable alternative. Matt Sicker asked: And can't getCustomLogger also provide a default method that uses the
Re: Using Custom Levels with a Custom/Wrapper Interface
Yes, I would like to declare in the config: Level: NOTICE, value: 232 And in Java code be able to use logger.notice(some message). But I think that'd require invokedynamic..which would probably require..javassist/ASM? I'd be ok with anything that's really close to that :) Scott On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: Scott would like users to add a level definition to the logging configuration and have everything else happen auto-magically. That would happen at run-time which is a bit late since the methods need to be available at compile time. I believe Scott said he would be fine if users had to do logger.log(SomeClass.SomeLevel, message); but even that requires SomeClass to be available at compile time. So what Scott says he would like and what Nick is proposing are two different things. Ralph On Jan 26, 2014, at 8:09 PM, Remko Popma remko.po...@gmail.com wrote: I actually thought that Nick's idea was the answer to that: users create a custom interface, something like this: public interface MyLogger extends Logger { @LoggingLevel(name=DIAG) void diag(String message); // optional other methods } They get an instance of this interface by calling: LogManager.getCustomLogger(MyLogger.class); LogManager has access to the processed configuration. The config has LevelsLevel name=DIAG intValue=450 elements. During configuration processing, the custom Level instances are created and registered, so on the first call to LogManager.getCustomLogger(MyLogger.class), the MyLogger instance is created and cached. Also, at this point the annotations are parsed to see what Level instance the MyLogger implementation will pass to the Logger.log(Level, String) method when the diag method is called. What is still open in this scenario is how the instance is created. Proxy? Or generate source compile? Or use a byte code library? On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I am going to have to echo what Nick said. If you can think of a way to make logger.log(SomeClass.SomeLevel, hello world); work without actually creating SomeClass then please share! Ralph On Jan 26, 2014, at 7:45 PM, Nick Williams nicho...@nicholaswilliams.net wrote: It would not be possible to do this strictly through configuration because the user needs a compiled interface to code against. Where is that compiled interface to come from? Nick On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Here's a split-off thread for discussing how we can make using custom levels easier. Some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be nice to have: logger.note(message); logger.diag(message); etc. We're to discuss how best to approach this. My proposal (from previous email): Allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void [methodName](Marker, Message) void [methodName](Marker, Message, Throwable t) void [methodName](Marker, Object) void [methodName](Marker, Object, Throwable t) void [methodName](Marker, String) void [methodName](Marker, String, Object...) void [methodName](Marker, String throwable) void [methodName](Message) void [methodName](Message, Throwable t) void [methodName](Object) void [methodName](Object, Throwable t) void [methodName](String) void [methodName](String, Object...) void [methodName](String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, String) T extends Logger T getCustomLogger(ClassT loggerClass, String, MessageFactory) The user can then obtain such a logger like so, etc.: MyLogger logger = LogManager.getCustomLogger(MyLogger.class); Log4j will generate an implementation of MyLogger that extends the default implementation, cache that implementation so that it doesn't have to be implemented
Re: Using Custom Levels with a Custom/Wrapper Interface
Sure, but what's wrong with the idea? The user provide their own interface, so that interface exists at compile time. The interface uses annotations, so it does not need to explicitly refer to a custom Level instance. Only the /implementation/ needs to know about the custom Level instances, and the implementation could be generated at runtime (I hope :-) ). On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: Scott would like users to add a level definition to the logging configuration and have everything else happen auto-magically. That would happen at run-time which is a bit late since the methods need to be available at compile time. I believe Scott said he would be fine if users had to do logger.log(SomeClass.SomeLevel, “message); but even that requires “SomeClass” to be available at compile time. So what Scott says he would like and what Nick is proposing are two different things. Ralph On Jan 26, 2014, at 8:09 PM, Remko Popma remko.po...@gmail.com wrote: I actually thought that Nick's idea was the answer to that: users create a custom interface, something like this: public interface MyLogger extends Logger { @LoggingLevel(name=DIAG) void diag(String message); // optional other methods } They get an instance of this interface by calling: LogManager.getCustomLogger(MyLogger.class); LogManager has access to the processed configuration. The config has LevelsLevel name=DIAG intValue=450 elements. During configuration processing, the custom Level instances are created and registered, so on the first call to LogManager.getCustomLogger(MyLogger.class), the MyLogger instance is created and cached. Also, at this point the annotations are parsed to see what Level instance the MyLogger implementation will pass to the Logger.log(Level, String) method when the diag method is called. What is still open in this scenario is how the instance is created. Proxy? Or generate source compile? Or use a byte code library? On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I am going to have to echo what Nick said. If you can think of a way to make logger.log(SomeClass.SomeLevel, “hello world”); work without actually creating SomeClass then please share! Ralph On Jan 26, 2014, at 7:45 PM, Nick Williams nicho...@nicholaswilliams.net wrote: It would not be possible to do this strictly through configuration because the user needs a compiled interface to code against. Where is that compiled interface to come from? Nick On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Here's a split-off thread for discussing how we can make using custom levels easier. Some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be nice to have: logger.note(message); logger.diag(message); etc. We're to discuss how best to approach this. My proposal (from previous email): Allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void [methodName](Marker, Message) void [methodName](Marker, Message, Throwable t) void [methodName](Marker, Object) void [methodName](Marker, Object, Throwable t) void [met
Re: Using Custom Levels with a Custom/Wrapper Interface
In addition to the above, we could provide a tool to generate a MyLogger interface with 14 method signatures for each custom Level name. This would be an offline tool that users would use only once. But this tool is optional... On Monday, January 27, 2014, Remko Popma remko.po...@gmail.com wrote: Sure, but what's wrong with the idea? The user provide their own interface, so that interface exists at compile time. The interface uses annotations, so it does not need to explicitly refer to a custom Level instance. Only the /implementation/ needs to know about the custom Level instances, and the implementation could be generated at runtime (I hope :-) ). On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: Scott would like users to add a level definition to the logging configuration and have everything else happen auto-magically. That would happen at run-time which is a bit late since the methods need to be available at compile time. I believe Scott said he would be fine if users had to do logger.log(SomeClass.SomeLevel, “message); but even that requires “SomeClass” to be available at compile time. So what Scott says he would like and what Nick is proposing are two different things. Ralph On Jan 26, 2014, at 8:09 PM, Remko Popma remko.po...@gmail.com wrote: I actually thought that Nick's idea was the answer to that: users create a custom interface, something like this: public interface MyLogger extends Logger { @LoggingLevel(name=DIAG) void diag(String message); // optional other methods } They get an instance of this interface by calling: LogManager.getCustomLogger(MyLogger.class); LogManager has access to the processed configuration. The config has LevelsLevel name=DIAG intValue=450 elements. During configuration processing, the custom Level instances are created and registered, so on the first call to LogManager.getCustomLogger(MyLogger.class), the MyLogger instance is created and cached. Also, at this point the annotations are parsed to see what Level instance the MyLogger implementation will pass to the Logger.log(Level, String) method when the diag method is called. What is still open in this scenario is how the instance is created. Proxy? Or generate source compile? Or use a byte code library? On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I am going to have to echo what Nick said. If you can think of a way to make logger.log(SomeClass.SomeLevel, “hello world”); work without actually creating SomeClass then please share! Ralph On Jan 26, 2014, at 7:45 PM, Nick Williams nicho...@nicholaswilliams.net wrote: It would not be possible to do this strictly through configuration because the user needs a compiled interface to code against. Where is that compiled interface to come from? Nick On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Here's a split-off thread for discussing how we can make using custom levels easier. Some on the team have expressed a desire to make it even easier. Given hypoth
Re: Levels added in revision 1560602
Not to rehash this issue, but I wanted to clarify what can be vetoed, for future reference. I'm only bringing this up to make it clear, unless there is a 'technical justification', a veto is invalid. In my opinion, there was no 'technical justification' for requesting removal of the new levels, just a preference (since the technical solution for providing the levels was already in place). http://www.apache.org/foundation/glossary.html#Veto ...Vetos may not be overridden nor voted down, and only cease to apply when the committer who issued the veto withdraws it. All vetos must be accompanied by a valid technical justification; a veto without such a justification is invalid; in case of doubt, deciding whether a technical justification is valid is up to the PMC Scott On 1/25/14, Gary Gregory garydgreg...@gmail.com wrote: On Sat, Jan 25, 2014 at 5:10 AM, Christian Grobmeier grobme...@gmail.comwrote: Thanks a lot Gary for the great response. Now I understand you better. Thank you Christian. I created the branch https://svn.apache.org/repos/asf/logging/log4j/log4j2/branches/new-levelsfor those who want to a have easy look. Gary On 25 Jan 2014, at 2:00, Ralph Goers wrote: I have the same problem with your use of NOTICE as I did with CONFIG. If I want to see startup and shutdown log events I MUST also get warning messages, which isn’t necessarily what I want. For startup, shutdown configuration Markers should be used. That doesn’t mean I probably couldn’t come up with a separate use case for the level though. In the end we might be able to solve everything using markers. Log levels are some kind of convenient methods for me (ok, a little more). We need to keep balance between them. I think DIAG might be really useful. At the moment I use Markers with DEBUG to emulate DIAG. NOTICE: Using Markers might require more discipline by our users than using logger.notice(); Like: logger.debug(CONNECTIVITY, ); If the NOTICE recommendation would be to write everything related to connectivity on this level it it would make much sense to me. In example: - Java app connects to MQSeries with version $x. - Java app lost connection to database, but reconnects. - Java initiates call to the Paypal API successfully (but the actual communication is logged on debug / diag) That said, I am moving towards +1 for this change. I agree with your other usages. Ralph On Jan 24, 2014, at 2:22 PM, Gary Gregory garydgreg...@gmail.com wrote: Here is my usage: FATAL - Logged from main(String[]) methods when a checked exception is caught, also for unchecked exceptions in main(String[]) like IllegalArgumentException. You need to know if it is appropriate for your main(String[]) method to even throw an exception; if your class is never called from another Java app, then catch all exceptions and log them in main(String[]). Also consider using this pattern for methods that behave like main(String[]), for example in a Quartz job's execute method. Use before calling System.exit(int) with an error value (usually not 0). ERROR - Exceptions that the program cannot recover. For example: the app cannot connect to a database, so data cannot be read or written. A request needs to be re-submitted. WARN - Exceptions that the program can recover from. For example: a configuration file cannot be found, so some defaults kick in. If your app uses configuration by exception, then this level is not appropriate, use NOTICE instead. NOTICE (now I use INFO) - The app start up and shutdown banners. The kind of information mvn -version and java -version return. The server is starting, The server started, The server is shutting down, The server is down, goodbye.. This should be the level for production system. INFO - Describes what the application is doing, not too chatty. Useful for ops to tell the server is actually up and running, this is high-level heartbeat kind of data. So things like Processing request foo, Processed request bar. This should be the level on QA systems. DIAG (now DEBUG) - What a user may need to fix problems. In a business process app (workflow, we have a BPM app), there are the steps in the workflow (like high level transactions: account debited for user foo, accout credited, call logged with support, technician SMS sent, and so on.). This should be the level on development systems. DEBUG - What a developer needs to debug. Connecting to database for example. This is the bulk for debug data. VERBOSE (now DEBUG) - Hex dumps for wire-level communications. Contents of buffers going in and out of memory, in and out of files. When XSL transformations take place, log the input, the XSL being called, then the output. TRACE - method entry and method exit, nothing else. As you can see the DEBUG level is overloaded. This is the biggest problem. User debug info and internal product debug info are MIXED. Our users are confused, our
Re: Using Custom Levels with a Custom/Wrapper Interface
Nick, I thought that you meant that users would provide their own interface, like this: public interface MyLogger extends Logger { @LoggingLevel(name=DIAG) void diag(String message); // optional other methods } That way, this interface exists at compile time. On Monday, January 27, 2014, Nicholas Williams nicho...@nicholaswilliams.net wrote: Scott, invokedynamic and javassist...those are all /runtime/ things. The user needs Logger#notice to be available at compile time. Those are not compatible. Nick Sent from my iPhone, so please forgive brief replies and frequent typos On Jan 26, 2014, at 22:37, Scott Deboy scott.de...@gmail.com wrote: Yes, I would like to declare in the config: Level: NOTICE, value: 232 And in Java code be able to use logger.notice(some message). But I think that'd require invokedynamic..which would probably require..javassist/ASM? I'd be ok with anything that's really close to that :) Scott On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: Scott would like users to add a level definition to the logging configuration and have everything else happen auto-magically. That would happen at run-time which is a bit late since the methods need to be available at compile time. I believe Scott said he would be fine if users had to do logger.log(SomeClass.SomeLevel, message); but even that requires SomeClass to be available at compile time. So what Scott says he would like and what Nick is proposing are two different things. Ralph On Jan 26, 2014, at 8:09 PM, Remko Popma remko.po...@gmail.com wrote: I actually thought that Nick's idea was the answer to that: users create a custom interface, something like this: public interface MyLogger extends Logger { @LoggingLevel(name=DIAG) void diag(String message); // optional other methods } They get an instance of this interface by calling: LogManager.getCustomLogger(MyLogger.class); LogManager has access to the processed configuration. The config has LevelsLevel name=DIAG intValue=450 elements. During configuration processing, the custom Level instances are created and registered, so on the first call to LogManager.getCustomLogger(MyLogger.class), the MyLogger instance is created and cached. Also, at this point the annotations are parsed to see what Level instance the MyLogger implementation will pass to the Logger.log(Level, String) method when the diag method is called. What is still open in this scenario is how the instance is created. Proxy? Or generate source compile? Or use a byte code library? On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I am going to have to echo what Nick said. If you can think of a way to make logger.log(SomeClass.SomeLevel, hello world); work without actually creating SomeClass then please share! Ralph On Jan 26, 2014, at 7:45 PM, Nick Williams nicho...@nicholaswilliams.net wrote: It would not be possible to do this strictly through configuration because the user needs a compiled interface to code against. Where is that compiled interface to come from? Nick On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams
Re: Using Custom Levels with a Custom/Wrapper Interface
Could we leverage Rhino? :) Scott On 1/26/14, Nicholas Williams nicho...@nicholaswilliams.net wrote: Scott, invokedynamic and javassist...those are all /runtime/ things. The user needs Logger#notice to be available at compile time. Those are not compatible. Nick Sent from my iPhone, so please forgive brief replies and frequent typos On Jan 26, 2014, at 22:37, Scott Deboy scott.de...@gmail.com wrote: Yes, I would like to declare in the config: Level: NOTICE, value: 232 And in Java code be able to use logger.notice(some message). But I think that'd require invokedynamic..which would probably require..javassist/ASM? I'd be ok with anything that's really close to that :) Scott On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: Scott would like users to add a level definition to the logging configuration and have everything else happen auto-magically. That would happen at run-time which is a bit late since the methods need to be available at compile time. I believe Scott said he would be fine if users had to do logger.log(SomeClass.SomeLevel, message); but even that requires SomeClass to be available at compile time. So what Scott says he would like and what Nick is proposing are two different things. Ralph On Jan 26, 2014, at 8:09 PM, Remko Popma remko.po...@gmail.com wrote: I actually thought that Nick's idea was the answer to that: users create a custom interface, something like this: public interface MyLogger extends Logger { @LoggingLevel(name=DIAG) void diag(String message); // optional other methods } They get an instance of this interface by calling: LogManager.getCustomLogger(MyLogger.class); LogManager has access to the processed configuration. The config has LevelsLevel name=DIAG intValue=450 elements. During configuration processing, the custom Level instances are created and registered, so on the first call to LogManager.getCustomLogger(MyLogger.class), the MyLogger instance is created and cached. Also, at this point the annotations are parsed to see what Level instance the MyLogger implementation will pass to the Logger.log(Level, String) method when the diag method is called. What is still open in this scenario is how the instance is created. Proxy? Or generate source compile? Or use a byte code library? On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I am going to have to echo what Nick said. If you can think of a way to make logger.log(SomeClass.SomeLevel, hello world); work without actually creating SomeClass then please share! Ralph On Jan 26, 2014, at 7:45 PM, Nick Williams nicho...@nicholaswilliams.net wrote: It would not be possible to do this strictly through configuration because the user needs a compiled interface to code against. Where is that compiled interface to come from? Nick On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Here's a split-off thread for discussing how we can make using custom levels easier. Some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be nice to have: logger.note(message); logger.diag(message); etc. We're to discuss how best to approach this. My proposal (from previous email): Allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void [methodName](Marker, Message) void [methodName](Marker, Message, Throwable t) void [methodName](Marker, Object) void [methodName](Marker, Object, Throwable t) void [methodName](Marker, String) void [methodName](Marker, String, Object...) void [methodName](Marker, String throwable) void [methodName](Message) void [methodName](Message, Throwable t) void [methodName](Object) void [methodName](Object, Throwable t) void [methodName](String) void [methodName](String, Object...) void [methodName](String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass, Object) T extends Logger T getCustomLogger(ClassT loggerClass, Object, MessageFactory) T extends Logger T
Re: Using Custom Levels with a Custom/Wrapper Interface
Of course, they'd have to use rhino, or something else...which doesn't help. Where's duck typing when you need it :) On 1/26/14, Scott Deboy scott.de...@gmail.com wrote: Could we leverage Rhino? :) Scott On 1/26/14, Nicholas Williams nicho...@nicholaswilliams.net wrote: Scott, invokedynamic and javassist...those are all /runtime/ things. The user needs Logger#notice to be available at compile time. Those are not compatible. Nick Sent from my iPhone, so please forgive brief replies and frequent typos On Jan 26, 2014, at 22:37, Scott Deboy scott.de...@gmail.com wrote: Yes, I would like to declare in the config: Level: NOTICE, value: 232 And in Java code be able to use logger.notice(some message). But I think that'd require invokedynamic..which would probably require..javassist/ASM? I'd be ok with anything that's really close to that :) Scott On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: Scott would like users to add a level definition to the logging configuration and have everything else happen auto-magically. That would happen at run-time which is a bit late since the methods need to be available at compile time. I believe Scott said he would be fine if users had to do logger.log(SomeClass.SomeLevel, message); but even that requires SomeClass to be available at compile time. So what Scott says he would like and what Nick is proposing are two different things. Ralph On Jan 26, 2014, at 8:09 PM, Remko Popma remko.po...@gmail.com wrote: I actually thought that Nick's idea was the answer to that: users create a custom interface, something like this: public interface MyLogger extends Logger { @LoggingLevel(name=DIAG) void diag(String message); // optional other methods } They get an instance of this interface by calling: LogManager.getCustomLogger(MyLogger.class); LogManager has access to the processed configuration. The config has LevelsLevel name=DIAG intValue=450 elements. During configuration processing, the custom Level instances are created and registered, so on the first call to LogManager.getCustomLogger(MyLogger.class), the MyLogger instance is created and cached. Also, at this point the annotations are parsed to see what Level instance the MyLogger implementation will pass to the Logger.log(Level, String) method when the diag method is called. What is still open in this scenario is how the instance is created. Proxy? Or generate source compile? Or use a byte code library? On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I am going to have to echo what Nick said. If you can think of a way to make logger.log(SomeClass.SomeLevel, hello world); work without actually creating SomeClass then please share! Ralph On Jan 26, 2014, at 7:45 PM, Nick Williams nicho...@nicholaswilliams.net wrote: It would not be possible to do this strictly through configuration because the user needs a compiled interface to code against. Where is that compiled interface to come from? Nick On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Here's a split-off thread for discussing how we can make using custom levels easier. Some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be nice to have: logger.note(message); logger.diag(message); etc. We're to discuss how best to approach this. My proposal (from previous email): Allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void [methodName](Marker, Message) void [methodName](Marker, Message, Throwable t) void [methodName](Marker, Object) void [methodName](Marker, Object, Throwable t) void [methodName](Marker, String) void [methodName](Marker, String, Object...) void [methodName](Marker, String throwable) void [methodName](Message) void [methodName](Message, Throwable t) void [methodName](Object) void [methodName](Object, Throwable t) void [methodName](String) void [methodName](String, Object...) void [methodName](String throwable) Each method /must/ be annotated with @LoggingLevel(name = levelName). Now LogManager has a few new methods: T extends Logger T getCustomLogger(ClassT loggerClass) T extends Logger T getCustomLogger(ClassT loggerClass, Class?) T extends Logger T getCustomLogger(ClassT loggerClass, Class?, MessageFactory) T extends Logger T getCustomLogger(ClassT loggerClass,
Re: Using Custom Levels with a Custom/Wrapper Interface
Yes, I was saying that. But, unless I'm misunderstanding, Scott doesn't want the user to even have to write the interface. He wants them to just configure it and the interface become available magically. I was pointing out that there's a disconnect between when the configuration is used (runtime) and when the user needs the interface (compile time). Unless we provide a code-generation tool for the user to run from the command line or from Ant/Maven/Gradle, they're going to have to write the interface themselves. Nick Sent from my iPhone, so please forgive brief replies and frequent typos On Jan 26, 2014, at 22:49, Remko Popma remko.po...@gmail.com wrote: Nick, I thought that you meant that users would provide their own interface, like this: public interface MyLogger extends Logger { @LoggingLevel(name=DIAG) void diag(String message); // optional other methods } That way, this interface exists at compile time. On Monday, January 27, 2014, Nicholas Williams nicho...@nicholaswilliams.net wrote: Scott, invokedynamic and javassist...those are all /runtime/ things. The user needs Logger#notice to be available at compile time. Those are not compatible. Nick Sent from my iPhone, so please forgive brief replies and frequent typos On Jan 26, 2014, at 22:37, Scott Deboy scott.de...@gmail.com wrote: Yes, I would like to declare in the config: Level: NOTICE, value: 232 And in Java code be able to use logger.notice(some message). But I think that'd require invokedynamic..which would probably require..javassist/ASM? I'd be ok with anything that's really close to that :) Scott On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: Scott would like users to add a level definition to the logging configuration and have everything else happen auto-magically. That would happen at run-time which is a bit late since the methods need to be available at compile time. I believe Scott said he would be fine if users had to do logger.log(SomeClass.SomeLevel, message); but even that requires SomeClass to be available at compile time. So what Scott says he would like and what Nick is proposing are two different things. Ralph On Jan 26, 2014, at 8:09 PM, Remko Popma remko.po...@gmail.com wrote: I actually thought that Nick's idea was the answer to that: users create a custom interface, something like this: public interface MyLogger extends Logger { @LoggingLevel(name=DIAG) void diag(String message); // optional other methods } They get an instance of this interface by calling: LogManager.getCustomLogger(MyLogger.class); LogManager has access to the processed configuration. The config has LevelsLevel name=DIAG intValue=450 elements. During configuration processing, the custom Level instances are created and registered, so on the first call to LogManager.getCustomLogger(MyLogger.class), the MyLogger instance is created and cached. Also, at this point the annotations are parsed to see what Level instance the MyLogger implementation will pass to the Logger.log(Level, String) method when the diag method is called. What is still open in this scenario is how the instance is created. Proxy? Or generate source compile? Or use a byte code library? On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I am going to have to echo what Nick said. If you can think of a way to make logger.log(SomeClass.SomeLevel, hello world); work without actually creating SomeClass then please share! Ralph On Jan 26, 2014, at 7:45 PM, Nick Williams nicho...@nicholaswilliams.net wrote: It would not be possible to do this strictly through configuration because the user needs a compiled interface to code against. Where is that compiled interface to come from? Nick On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams
[jira] [Updated] (LOG4J2-33) Support Annotations
[ https://issues.apache.org/jira/browse/LOG4J2-33?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Matt Sicker updated LOG4J2-33: -- Attachment: 0001-Add-Loggable.patch Here's a patch that's inspired by the Loggable meta-library. I'm not too sure on the benefits of this yet, but the @Loggable annotation can be beefed up to support more things and such. Support Annotations --- Key: LOG4J2-33 URL: https://issues.apache.org/jira/browse/LOG4J2-33 Project: Log4j 2 Issue Type: New Feature Components: API Reporter: Ralph Goers Fix For: 0.1 Attachments: 0001-Add-Loggable.patch The Log4j API should support using annotations as provided in Java 6 so applications can use them instead of calls to logger APIs. This is especially useful for entering exiting type of events, but could be used wherever annotations are allowed. -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Using Custom Levels with a Custom/Wrapper Interface
If we go the run-once tool route, then you might as well use annotation processing. I think it would support everything necessary to generate the appropriate custom logger class. On 26 January 2014 23:00, Scott Deboy scott.de...@gmail.com wrote: Of course, they'd have to use rhino, or something else...which doesn't help. Where's duck typing when you need it :) On 1/26/14, Scott Deboy scott.de...@gmail.com wrote: Could we leverage Rhino? :) Scott On 1/26/14, Nicholas Williams nicho...@nicholaswilliams.net wrote: Scott, invokedynamic and javassist...those are all /runtime/ things. The user needs Logger#notice to be available at compile time. Those are not compatible. Nick Sent from my iPhone, so please forgive brief replies and frequent typos On Jan 26, 2014, at 22:37, Scott Deboy scott.de...@gmail.com wrote: Yes, I would like to declare in the config: Level: NOTICE, value: 232 And in Java code be able to use logger.notice(some message). But I think that'd require invokedynamic..which would probably require..javassist/ASM? I'd be ok with anything that's really close to that :) Scott On 1/26/14, Ralph Goers ralph.go...@dslextreme.com wrote: Scott would like users to add a level definition to the logging configuration and have everything else happen auto-magically. That would happen at run-time which is a bit late since the methods need to be available at compile time. I believe Scott said he would be fine if users had to do logger.log(SomeClass.SomeLevel, message); but even that requires SomeClass to be available at compile time. So what Scott says he would like and what Nick is proposing are two different things. Ralph On Jan 26, 2014, at 8:09 PM, Remko Popma remko.po...@gmail.com wrote: I actually thought that Nick's idea was the answer to that: users create a custom interface, something like this: public interface MyLogger extends Logger { @LoggingLevel(name=DIAG) void diag(String message); // optional other methods } They get an instance of this interface by calling: LogManager.getCustomLogger(MyLogger.class); LogManager has access to the processed configuration. The config has LevelsLevel name=DIAG intValue=450 elements. During configuration processing, the custom Level instances are created and registered, so on the first call to LogManager.getCustomLogger(MyLogger.class), the MyLogger instance is created and cached. Also, at this point the annotations are parsed to see what Level instance the MyLogger implementation will pass to the Logger.log(Level, String) method when the diag method is called. What is still open in this scenario is how the instance is created. Proxy? Or generate source compile? Or use a byte code library? On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: I am going to have to echo what Nick said. If you can think of a way to make logger.log(SomeClass.SomeLevel, hello world); work without actually creating SomeClass then please share! Ralph On Jan 26, 2014, at 7:45 PM, Nick Williams nicho...@nicholaswilliams.net wrote: It would not be possible to do this strictly through configuration because the user needs a compiled interface to code against. Where is that compiled interface to come from? Nick On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: If there is a way to support this strictly through configuration that would be ideal. I'm trying to find a way to remove my request for additional built in levels but through configuration instead of adding them ourselves. Scott Scott On Jan 26, 2014 7:38 PM, Nick Williams nicho...@nicholaswilliams.net wrote: Here's a split-off thread for discussing how we can make using custom levels easier. Some on the team have expressed a desire to make it even easier. Given hypothetical custom levels DIAG and NOTE, the following would be nice to have: logger.note(message); logger.diag(message); etc. We're to discuss how best to approach this. My proposal (from previous email): Allow the user to define an interface that /must/ extend Logger. That interface may contain any methods that match the following signatures (the interface must have at least one method and there is no limit to the number of methods it may have): void [methodName](Marker, Message) void [methodName](Marker, Message, Throwable t) void [methodName](Marker, Object) void [methodName](Marker, Object, Throwable t) void [methodName](Marker, String) void [methodName](Marker, String, Object...) void [methodName](Marker, String throwable) void [methodName](Message) void [methodName](Message, Throwable t) void [methodName](Object) void [methodName](Object, Throwable t) void [methodName](String) void [methodName](String, Object...)
[jira] [Updated] (LOG4J2-512) Log4j2 need to support Asynchronous Servlets/ Servlet 3.0 while automatically starting, and configurable to initialize and de-initialize loggers
[ https://issues.apache.org/jira/browse/LOG4J2-512?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Chandra Sekhar Kakarla updated LOG4J2-512: -- Summary: Log4j2 need to support Asynchronous Servlets/ Servlet 3.0 while automatically starting, and configurable to initialize and de-initialize loggers (was: Log4j2 need to support Asynchronous Servlets/ Servlet 3.0 while automatically starting, and configurable to initialize and de-initialize loggers from the code) Log4j2 need to support Asynchronous Servlets/ Servlet 3.0 while automatically starting, and configurable to initialize and de-initialize loggers Key: LOG4J2-512 URL: https://issues.apache.org/jira/browse/LOG4J2-512 Project: Log4j 2 Issue Type: Sub-task Components: Configurators, Core, Documentation, Filters Affects Versions: 2.0-beta8, 2.0-beta9 Reporter: Chandra Sekhar Kakarla Labels: asynchronous, configuration, destroy, filters, initialization, listener, log4j2, log4j2.xml, restart, servlet, servlet-context Original Estimate: 466h Remaining Estimate: 466h Async servlet (async-supported=true) using with log4j2 breaks the async chain because it does not support async. All element in the chain must support async in order to use async. Implementation is required to support async servlets(async-supportd=true) it may be automatic or configurable initialization. ( this Issue may be dependent on the issue https://issues.apache.org/jira/browse/LOG4J2-270 ) Initialization and de-initialization of the logger must be configurable in the java code/config files, to re-load the logger with different properties, that will help the application to reduce re-start burden when it need to use different properties. -- This message was sent by Atlassian JIRA (v6.1.5#6160) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: GA?
I'd like to fix LOG4J-412 and 448, but neither of them are showstoppers IMHO . Remko On Monday, January 27, 2014, Ralph Goers ralph.go...@dslextreme.com wrote: Since we are having good discussions I would also like to find out what are blockers to a GA release. My list includes: 1. The fix Nick is working on to allow Servlet initialization to be disabled from automatically happening in a 3.0 container. 2. Support for programmatic configuration of Loggers. I planned on working on that this weekend but worked on the custom levels instead. While I believe better support for OSGi is necessary I don’t believe we will be able to do that for GA. Are there any other Jira issues or features that anybody else feels is required? Ralph - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.orgjavascript:; For additional commands, e-mail: log4j-dev-h...@logging.apache.orgjavascript:;