Without actually experimenting, I was thinking it might be difficult to make the full auto solution robust in all scenarios, so having an interface where users can completely determine their own mapping (option #2) is probably very nice to have.
Option #3 may be ideal (but the level mapper still needs to deal with the exceptional case where the code uses a custom level that is not defined in the config.) On Wednesday, September 10, 2014, Matt Sicker <[email protected]> wrote: > So far, I've implemented choice #2 to some extent. > > On 9 September 2014 23:47, Ralph Goers <[email protected] > <javascript:_e(%7B%7D,'cvml','[email protected]');>> wrote: > >> If I was implementing this I would take a custom JUL level and map it to >> the appropriate predefined JUL level. That would then map to a Log4j level. >> >> Ralph >> >> On Sep 9, 2014, at 9:19 PM, Remko Popma <[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');>> wrote: >> >> >> >> On Wednesday, September 10, 2014, Matt Sicker <[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');>> wrote: >> >>> There's actually a bit of an interesting challenge in converting from a >>> custom level in JUL to Log4j. JUL allows you to use any integer value >>> possible (not just non-negative ones). Also, their progression of level >>> values goes in reverse of ours. Thus, any level above 1000 (Level.SEVERE in >>> JUL) would need to be squeezed into the range of 1 to 99! Plus, >>> Integer.MAX_VALUE indicates StandardLevel.ALL, but Level.OFF in JUL. Then >>> there'd be the other way around, too. >>> >>> Darn! That makes things tricky indeed... >> Just throwing out some thoughts: >> >> 1. Full auto: We could have some mapping logic that converts the custom >> JUL int level to a log4j int that is between the mapped built-in levels. >> (TBD: how to avoid collisions if multiple custom levels are defined between >> built-in levels?) >> >> 2. Semi-auto: we define an interface that converts JUL levels to Log4j >> levels. We provide a default impl for the built-in levels. Users need to >> provide their own impl (or extend ours?) if they have custom JUL levels. >> (TBD: how does our default impl handle undefined custom JUL levels?) >> >> 3. Config only: this depends on >> https://issues.apache.org/jira/browse/LOG4J2-589 >> Custom log4j levels are defined in configuration. The log4j config file >> is loaded first, so the JUL bridge can convert custom levels using the name >> only. It can completely ignore the JUL int level. >> >> 4. Easiest: we (initially) don't support custom JUL levels. Unknown >> levels are converted to some ad hoc log4j level. Let's say, INFO, but we >> can decide to use any level. >> >> >> >>> As to those fields, I think we can probably drop them. LogRecord >>> dynamically calculates them from the Throwable stacktrace if necessary. We >>> do it faster. >>> >> >> Phew! >> >>> >>> On 9 September 2014 22:07, Matt Sicker <[email protected]> wrote: >>> >>>> What about the logp, entering, exiting, and throwing methods which all >>>> take a source class name and a source method name? Just ignore them? >>>> >>>> On 9 September 2014 21:40, Remko Popma <[email protected]> wrote: >>>> >>>>> My take would be to drop the seqNo and threadID integer, and for >>>>> level, check if its a built-in JUL level which can be translated to a >>>>> built-in log4j level. If it's not a built-in JUL level we can do a log4j >>>>> Level.forName() call to create that custom level in log4j as well. >>>>> Thoughts? >>>>> >>>>> Sent from my iPhone >>>>> >>>>> On 2014/09/10, at 11:07, Matt Sicker <[email protected]> wrote: >>>>> >>>>> I'm actually thinking of some sort of LogRecordMessage or similar >>>>> which takes a useful subset of LogRecord. >>>>> >>>>> On 9 September 2014 21:01, Matt Sicker <[email protected]> wrote: >>>>> >>>>>> I've got ranges in place to map to standard levels, but custom level >>>>>> support is currently done through the MDC. Should I use a MapMessage >>>>>> instead? Make a new Message type just for log4j-jul? There's metadata in >>>>>> some of these Logger methods that I'd like to include, but if the MDC >>>>>> isn't >>>>>> the best way to do that, then I'd prefer another way. I noticed that >>>>>> pax-logging does this for every log event to include some metadata about >>>>>> the OSGi bundle that made the log call, so I kept up the style. >>>>>> >>>>>> As to the static field, yes, I noticed that, too. It's only for a >>>>>> sequence number, and we have our own (better) way of doing that with >>>>>> on-demand sequencing (and using the AtomicXxx classes indeed) anyways. >>>>>> >>>>>> On 9 September 2014 20:39, Remko Popma <[email protected]> wrote: >>>>>> >>>>>>> Fro a performance point of view, it would be great if we could avoid >>>>>>> creating LogRecord instances. Not just from a GC perspective, but in >>>>>>> java6 >>>>>>> the LogRecord constructor synchronizes on a static variable(!): big >>>>>>> bottleneck. This is improved (using AtomicXxx) in java7. >>>>>>> >>>>>>> Also would great if we can avoid using the ThreadContext MDC for >>>>>>> every log event. (Its copy-on-write design is not a good match for this >>>>>>> usage...) >>>>>>> >>>>>>> Would there be a way to map custom JUL log levels to custom Log4j >>>>>>> levels? >>>>>>> >>>>>>> Sent from my iPhone >>>>>>> >>>>>>> On 2014/09/10, at 10:20, Matt Sicker <[email protected]> wrote: >>>>>>> >>>>>>> Actually, now that I look at it, I can just use an inner class with >>>>>>> ExtendedLoggerWrapper to get at those protected methods I mentioned. I >>>>>>> mean, that appears to be the point of it! Let me see if it does >>>>>>> everything >>>>>>> I needed. >>>>>>> >>>>>>> On 9 September 2014 20:08, Matt Sicker <[email protected]> wrote: >>>>>>> >>>>>>>> Now that I'm looking at this, what's the point of all the methods >>>>>>>> that take a FQCN instead of having just the ones in ExtendedLogger? >>>>>>>> I'm not >>>>>>>> sure why we didn't just use a field in AbstractLogger in the first >>>>>>>> place. >>>>>>>> >>>>>>>> On 9 September 2014 19:14, Matt Sicker <[email protected]> wrote: >>>>>>>> >>>>>>>>> I'm making some changes to log4j-jul to reduce redundant time >>>>>>>>> spent constructing a LogRecord that I don't even want to use most of >>>>>>>>> the >>>>>>>>> time. However, the ExtendedLogger interface (which I need to use at >>>>>>>>> the >>>>>>>>> very least so that I can set the fqcn to java.util.logging.Logger) >>>>>>>>> only >>>>>>>>> provides a single version of logMessage (unlike AbstractLogger which >>>>>>>>> has a >>>>>>>>> bunch), and several methods like catching(), throwing(), etc., all >>>>>>>>> depend >>>>>>>>> on protected methods in AbstractLogger that I'd rather not >>>>>>>>> re-implement. It >>>>>>>>> would be nice if I could just call the Logger methods I need, but >>>>>>>>> they all >>>>>>>>> get called with the wrong fqcn. >>>>>>>>> >>>>>>>>> Can we use a non-static final field that contains the fqcn? If I >>>>>>>>> could, I'd extend AbstractLogger myself, but I already have to extend >>>>>>>>> the >>>>>>>>> JUL Logger class (should have been an interface, grrr). Thus, I can't >>>>>>>>> rely >>>>>>>>> on AbstractLogger being the source of all these method calls. Unlike >>>>>>>>> the >>>>>>>>> other adapters, JUL provides more various logger calls than we even >>>>>>>>> have, >>>>>>>>> and I don't think ExtendedLogger was written with this scenario in >>>>>>>>> mind. >>>>>>>>> >>>>>>>>> I don't think this should be too large an impact of a change. I'm >>>>>>>>> going to push up a proposal, but feel free to veto it or offer some >>>>>>>>> suggestions! >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Matt Sicker <[email protected]> >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Matt Sicker <[email protected]> >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Matt Sicker <[email protected]> >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Matt Sicker <[email protected]> >>>>>> >>>>> >>>>> >>>>> >>>>> -- >>>>> Matt Sicker <[email protected]> >>>>> >>>>> >>>> >>>> >>>> -- >>>> Matt Sicker <[email protected]> >>>> >>> >>> >>> >>> -- >>> Matt Sicker <[email protected]> >>> >> >> > > > -- > Matt Sicker <[email protected] > <javascript:_e(%7B%7D,'cvml','[email protected]');>> >
