What if we keep the same or similar syntax but with Log4j2 imports, and we
use it to build a custom Message?

So, this java code logger.info(ansi().fg(RED).a("Hello").fg(CYAN).a("
World").reset());
would result in a JansiMessage containing a "Hello" string associated with
a RED object, and a " World" string associated with the CYAN object. At
this stage, nothing is rendered yet.

The Console Appender's PatternLayout, when the Jansi option is enabled,
could call JansiMessage.generateJansiFormattedMessage() which contains the
escape codes for the console.

The File Appender's PatternLayout does not have the Jansi option enabled,
so the normal Message.getFormattedMessage() is called, resulting in the
plain string "Hello World".

One key consideration is that all the objects used to build the message
should be in the Log4j API namespace to avoid any dependency on Jansi at
the API level. (But things like RED etc can be inner classes of
JansiMessage. Static imports can make this painless to use.)


On Tue, Jun 21, 2016 at 3:59 AM, Paul Benedict <[email protected]> wrote:

> It's pretty cool. Yes, a generalized syntax is very nice. Do your best to
> make the syntax general -- and if for, for whatever reason, an appender
> needs something more explicit/specific, those options can just be provided
> by the appender's custom parsing.
>
> Cheers,
> Paul
>
> On Mon, Jun 20, 2016 at 1:44 PM, Gary Gregory <[email protected]>
> wrote:
>
>> I think like the idea of having a special syntax for colors, for
>> rendering of styles in general actually, because we could have this
>> implemented for the Jansi+Console appender, for the HTML appender, and you
>> could also imagine an RTF appender.
>>
>> Gary
>>
>> On Thu, Jun 16, 2016 at 12:59 PM, Gary Gregory <[email protected]>
>> wrote:
>>
>>> On Thu, Jun 16, 2016 at 12:48 PM, Paul Benedict <[email protected]>
>>> wrote:
>>>
>>>> I imagine parsing the placeholder is going to be expensive (relatively
>>>> speaking). It is an extra cost.
>>>>
>>>
>>> We already support different ways to paramaterize messages [1]: {}, %s
>>> (and family), java.text.MessageFormat, and so on. Each has its different
>>> overhead.
>>>
>>> This could be a variation of the ParameterizedMessage class for example.
>>> Or maybe an extension of to one or more other message types.
>>>
>>> Gary
>>>
>>> [1] https://logging.apache.org/log4j/2.x/manual/messages.html
>>>
>>>
>>>> I advise devising a new interface that appenders can implement to
>>>> receive the parsed tokens. If the interface is missing, no parsing
>>>> in-between is necessary. Otherwise, send the tokens to the appender as a
>>>> callback for it to make the necessary modifications -- such as setting the
>>>> color.
>>>>
>>>> Cheers,
>>>> Paul
>>>>
>>>> On Thu, Jun 16, 2016 at 1:53 PM, Gary Gregory <[email protected]>
>>>> wrote:
>>>>
>>>>>
>>>>> On Jun 16, 2016 11:25 AM, "Paul Benedict" <[email protected]>
>>>>> wrote:
>>>>> >
>>>>> > Are you asking me for blue sky thinking, perhaps something like this:
>>>>> > log.info("Hello, {color:green}, how are you?", "Gary");
>>>>> >
>>>>> > For this example, I took the {} placeholder and added some context.
>>>>>
>>>>> Ok yes, that's what I was talking about. Also:
>>>>>
>>>>> log.info("Hello {color:green Gary}, how are you?");
>>>>>
>>>>> Gary
>>>>> >
>>>>> > Cheers,
>>>>> > Paul
>>>>> >
>>>>> > On Thu, Jun 16, 2016 at 1:22 PM, Gary Gregory <
>>>>> [email protected]> wrote:
>>>>> >>
>>>>> >> On Thu, Jun 16, 2016 at 11:04 AM, Paul Benedict <
>>>>> [email protected]> wrote:
>>>>> >>>
>>>>> >>> I think color falls into the category of formatting. By that, I
>>>>> mean to state that colors shouldn't be hardcoded into messages :-) That
>>>>> should belong to the actual formatter... template string or appender
>>>>> configuration.
>>>>> >>
>>>>> >>
>>>>> >> What would that look like? I do not see how do to that without
>>>>> creating a lot of custom code.
>>>>> >>
>>>>> >> Gary
>>>>> >>
>>>>> >>>
>>>>> >>>
>>>>> >>> Cheers,
>>>>> >>> Paul
>>>>> >>>
>>>>> >>> On Thu, Jun 16, 2016 at 12:58 PM, Gary Gregory <
>>>>> [email protected]> wrote:
>>>>> >>>>
>>>>> >>>> On Thu, Jun 16, 2016 at 10:39 AM, Gary Gregory <
>>>>> [email protected]> wrote:
>>>>> >>>>>
>>>>> >>>>> On Wed, Jun 15, 2016 at 10:50 PM, Gary Gregory <
>>>>> [email protected]> wrote:
>>>>> >>>>>>
>>>>> >>>>>> Hi All,
>>>>> >>>>>>
>>>>> >>>>>> See color messages in Maven 3.4.0-SNAPSHOT made me think of the
>>>>> following.
>>>>> >>>>>>
>>>>> >>>>>> Right now, with Jansi on the CP, I can say:
>>>>> >>>>>>
>>>>> >>>>>> import static org.fusesource.jansi.Ansi.*;
>>>>> >>>>>> import static org.fusesource.jansi.Ansi.Color.*;
>>>>> >>>>>> ...
>>>>> >>>>>> logger.info(ansi().fg(RED).a("Hello").fg(CYAN).a("
>>>>> World").reset());
>>>>> >>>>>>
>>>>> >>>>>> and the right thing happens on the console.
>>>>> >>>>>>
>>>>> >>>>>> If I also have a file appender, I get the escape codes in the
>>>>> file, which I do not think most people would want.
>>>>> >>>>>>
>>>>> >>>>>> The question is, how can we make it simple for users to have
>>>>> their cake and eat it too?
>>>>> >>>>>>
>>>>> >>>>>> With a special Message implementation?
>>>>> >>>>>>
>>>>> >>>>>> Thoughts?
>>>>> >>>>>
>>>>> >>>>>
>>>>> >>>>> One way would be to have the non-a() methods (plus reset())
>>>>> become no-ops when not using a console appender. But how? We could have a
>>>>> subclass of JAnsi's Ansi class that gets used. Anyway, I'm just rambling.
>>>>> >>>>
>>>>> >>>>
>>>>> >>>> Still rambling, mostly so I have a place to look back for these
>>>>> notes:
>>>>> >>>>
>>>>> >>>> - nope, the reset() method would need to be noop'd.
>>>>> >>>> - Example of a color message:
>>>>> org.apache.logging.log4j.core.appender.ConsoleAppenderJAnsiMessageMain
>>>>> >>>> - JAnsi also supports a special syntax, for example:
>>>>> >>>>
>>>>> >>>> "@|red Hello|@ @|cyan World|@"
>>>>> >>>>
>>>>> >>>> but if use that like:
>>>>> >>>>
>>>>> >>>> logger.info("@|red Hello|@ @|cyan World|@");
>>>>> >>>>
>>>>> >>>> JAnsi rendering does not kick in unsurprisingly.
>>>>> >>>>
>>>>> >>>> Maybe the Console appender could make sure the JAnsi renderer is
>>>>> used (optional), so that
>>>>> >>>>
>>>>> >>>> logger.info(ansi().render("@|red Hello|@ @|green World|@");
>>>>> >>>>
>>>>> >>>> can become:
>>>>> >>>>
>>>>> >>>> logger.info("@|red Hello|@ @|green World|@");
>>>>> >>>>
>>>>> >>>> and then we can add a renderJansi option to the console appender
>>>>> but... the decorations still end up in a file appender so we are still in
>>>>> the same pickle.
>>>>> >>>>
>>>>> >>>> Thinking about a MessageRenderer (String render(String))
>>>>> interface with two impl: one that calls ansi().render(String) for console
>>>>> appenders (optionally, if renderJansi=true) and another that strips the
>>>>> decorations (but this feels heavy).
>>>>> >>>>
>>>>> >>>> More rambling:
>>>>> >>>>
>>>>> >>>> Instead of:
>>>>> >>>>
>>>>> >>>> logger.info(ansi().fg(RED).a("Hello").fg(CYAN).a("
>>>>> World").reset());
>>>>> >>>>
>>>>> >>>> say:
>>>>> >>>>
>>>>> >>>> logger.info((Ansi ansi) -> ansi.fg(RED).a("Hello").fg(CYAN).a("
>>>>> World").reset());
>>>>> >>>>
>>>>> >>>> Then we can pass in a custom Ansi subclass that only outputs the
>>>>> string bits, no escape codes.
>>>>> >>>>
>>>>> >>>> Gary
>>>>> >>>>
>>>>> >>>>>
>>>>> >>>>> Gary
>>>>> >>>>>
>>>>> >>>>>>
>>>>> >>>>>> Thank you,
>>>>> >>>>>> Gary
>>>>> >>>>>> --
>>>>> >>>>>> E-Mail: [email protected] | [email protected]
>>>>> >>>>>> 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
>>>>> >>>>>
>>>>> >>>>>
>>>>> >>>>>
>>>>> >>>>>
>>>>> >>>>> --
>>>>> >>>>> E-Mail: [email protected] | [email protected]
>>>>> >>>>> 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
>>>>> >>>>
>>>>> >>>>
>>>>> >>>>
>>>>> >>>>
>>>>> >>>> --
>>>>> >>>> E-Mail: [email protected] | [email protected]
>>>>> >>>> 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
>>>>> >>>
>>>>> >>>
>>>>> >>
>>>>> >>
>>>>> >>
>>>>> >> --
>>>>> >> E-Mail: [email protected] | [email protected]
>>>>> >> 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
>>>>> >
>>>>> >
>>>>>
>>>>
>>>>
>>>
>>>
>>> --
>>> E-Mail: [email protected] | [email protected]
>>> Java Persistence with Hibernate, Second Edition
>>> <http://www.manning.com/bauer3/>
>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>>> Spring Batch in Action <http://www.manning.com/templier/>
>>> Blog: http://garygregory.wordpress.com
>>> Home: http://garygregory.com/
>>> Tweet! http://twitter.com/GaryGregory
>>>
>>
>>
>>
>> --
>> E-Mail: [email protected] | [email protected]
>> Java Persistence with Hibernate, Second Edition
>> <http://www.manning.com/bauer3/>
>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>> Spring Batch in Action <http://www.manning.com/templier/>
>> Blog: http://garygregory.wordpress.com
>> Home: http://garygregory.com/
>> Tweet! http://twitter.com/GaryGregory
>>
>
>

Reply via email to