? Every appender accepts a Layout for rendering and they all use one. A File appender can use a Pattern layout, a JSON layout, etc. So it is incorrect to say any appender wants no rendering.
I think what you are really wanting is a way to either a) enhance the Message.getFormattedMessage() to process the styles in accordance with the Appender type or b) have the Appender process the styles after getFormattedMessage() is called. Architecturally, I like the idea of having the Message handle it but it may be harder to implement. Ralph > On Jun 24, 2016, at 12:22 PM, Gary Gregory <[email protected]> wrote: > > Since an HTML layout and a Console JAnsi layout need different interpretation > of the message string, why not allow each appender to do its own rendering? > Also, you want no rendering for other appenders like file, JMS, and so on. > > Gary > > On Jun 24, 2016 11:07 AM, "Ralph Goers" <[email protected] > <mailto:[email protected]>> wrote: > Yes. Of course the converter would need to be aware what the target is, which > I am not sure is currently available. In this case I would think you would > want to just enhance the %m converter to support these new plugins, rather > than creating a new message converter. > > If you didn’t want to have the output formatted differently depending on the > target I could see having the formatting being done in the Message. > > Ralph > >> On Jun 24, 2016, at 10:37 AM, Gary Gregory <[email protected] >> <mailto:[email protected]>> wrote: >> >> Thank you for the feedback. >> >> I can see that I could invent a new kind of %m converter that parses the >> message and does the coloring. I could have an ANSI kind of %m, an HTML %m, >> and so on. >> >> Gary >> >> On Jun 24, 2016 10:00 AM, "Ralph Goers" <[email protected] >> <mailto:[email protected]>> wrote: >> >> I am not sure I get this idea at all. First, I would expect that “styles” >> would be plugins much as converters are for the PatternLayout. But it isn’t >> clear to me at all why I would want or require a StyledMessage to do that. >> If you want to support “styles” then implement the support in the >> appropriate layouts. The message should just contain the information the >> styles need to render them. >> >> Also, is StyledMessage an Interface? If it is a class is it a >> ParameterizedMessage, SimpleMessage, etc, or are you planning on having a >> “Styled” version of each Message type. I am not in favor of that at all. >> >> I am also not sure how this handles the issue you mentioned at the start of >> this thread - that the color codes written to files don’t cause the colors >> to show up and only render properly on the console. >> >> Ralph >> >>> On Jun 24, 2016, at 8:43 AM, Gary Gregory <[email protected] >>> <mailto:[email protected]>> wrote: >>> >>> Another question is what should the syntax be for a StyledMessage? The same >>> as for a pattern layout >>> (https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout >>> <https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout>)? >>> Something else? Could it be simpler and still allow for parameters and >>> escaping? >>> >>> SyledMessageFactory factory = SyledMessageFactory.load( ...styles... ); >>> item = "pants"; >>> // Using pattern layout kind of format with parameter markers. >>> logger.error("Your {} are on {fire!}{criticalMassStyle}, >>> {notifying}{peacfulStyle}{}", item); >>> logger.error("Your %s are on {fire!}{criticalMassStyle}, >>> {notifying}{peacfulStyle}%s", item); >>> >>> Gary >>> >>> On Tue, Jun 21, 2016 at 6:39 PM, Remko Popma <[email protected] >>> <mailto:[email protected]>> wrote: >>> After thinking about it some more, I agree with you guys that the string >>> syntax seems like a better idea. >>> >>> >>> On Wednesday, 22 June 2016, Gary Gregory <[email protected] >>> <mailto:[email protected]>> wrote: >>> On Mon, Jun 20, 2016 at 4:14 PM, Remko Popma <[email protected] <>> >>> wrote: >>> 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 >>> <http://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. >>> >>> I would prefer to avoid a vendor specific message class and name. I think >>> the Maven folks are experiencing growing pains now that they have enabled >>> color within Maven messages. I think a StyledMessage would be the way to go. >>> >>> When a StyledMessage goes to a Console appender, JAnsi is used, when it >>> does to an HTML appender, HTML is used. Whether you build a StyledMessage >>> with a fluent API, a string syntax or both is another matter, but the >>> string syntax seems simplest. >>> >>> Gary >>> >>> >>> 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 >>> <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 <http://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 <http://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 >>> >>>>>> <http://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 <http://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 <http://logger.info/>(ansi().render("@|red Hello|@ @|green >>> >>>> World|@"); >>> >>>> >>> >>>> can become: >>> >>>> >>> >>>> logger.info <http://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 >>> >>>> <http://logger.info/>(ansi().fg(RED).a("Hello").fg(CYAN).a(" >>> >>>> World").reset()); >>> >>>> >>> >>>> say: >>> >>>> >>> >>>> logger.info <http://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 >>> >>>>>> <http://garygregory.wordpress.com/> >>> >>>>>> Home: http://garygregory.com/ <http://garygregory.com/> >>> >>>>>> Tweet! http://twitter.com/GaryGregory >>> >>>>>> <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 >>> >>>>> <http://garygregory.wordpress.com/> >>> >>>>> Home: http://garygregory.com/ <http://garygregory.com/> >>> >>>>> Tweet! http://twitter.com/GaryGregory <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 >>> >>>> <http://garygregory.wordpress.com/> >>> >>>> Home: http://garygregory.com/ <http://garygregory.com/> >>> >>>> Tweet! http://twitter.com/GaryGregory <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 >>> >> <http://garygregory.wordpress.com/> >>> >> Home: http://garygregory.com/ <http://garygregory.com/> >>> >> Tweet! http://twitter.com/GaryGregory <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 <http://garygregory.wordpress.com/> >>> Home: http://garygregory.com/ <http://garygregory.com/> >>> Tweet! http://twitter.com/GaryGregory <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 <http://garygregory.wordpress.com/> >>> Home: http://garygregory.com/ <http://garygregory.com/> >>> Tweet! http://twitter.com/GaryGregory <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 <http://garygregory.wordpress.com/> >>> Home: http://garygregory.com/ <http://garygregory.com/> >>> Tweet! http://twitter.com/GaryGregory <http://twitter.com/GaryGregory> >>> >>> >>> -- >>> E-Mail: [email protected] <mailto:[email protected]> | >>> [email protected] <mailto:[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 <http://garygregory.wordpress.com/> >>> Home: http://garygregory.com/ <http://garygregory.com/> >>> Tweet! http://twitter.com/GaryGregory <http://twitter.com/GaryGregory> >
