Rambling thoughts: I use the term message as the message string from the log event (probably after parameters has been processed.)
- Add to PatternLayout a %ansiMessage, use that instead of %m and the layout will rewrite the message as an ANSI message. Use that on a file layout and you get ANSI codes in your file. - Add to PatternLayout a %htmlMessage, use that instead of %m and the layout will rewrite the message as an HTML fragment. The produced HTML would not be a whole HTML document, just a fragment that fits in an HTML page/ More general: Add to PatternLayout a %styledMessage, use that instead of %m and: - A console appends rewrites the message as an ANSI message. - An HTML layout rewrites the message as an HTML fragment. The message syntax is TDB. My focus in on the console appender but thinking about HTML as well helps consider a more general solution (I hope). Gary On Sat, Jun 25, 2016 at 2:51 PM, Paul Benedict <[email protected]> wrote: > Do you guys have a policy like HTML for ignoring unknown tags/styles when > parsing a message? So if a message is, for example, "Hey {%s color:red}", > and the formatter doesn't support colors, it completely ignores the > "color:red" token? I am implying a backward and forward compatibility. > > Cheers, > Paul > > On Sat, Jun 25, 2016 at 2:16 PM, Gary Gregory <[email protected]> > wrote: > >> I meant something like (b). I used the word "render" to try to convey a >> different concept form "formatting" a message with its parameter. An >> appender knows how to render a formatted message on itself. >> >> The question is how to get no styles on certain appenders and layouts >> seem to be one good place to do it if I set up that layout for just the one >> appender that needs it. >> >> Gary >> ? >> >> 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]> >> 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]> >>> 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]> >>> 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]> >>>> 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)? >>>> 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]> >>>> 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]> >>>>> 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(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 >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> 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 >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> 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 >>>> >>>> >>>> >>> >> > -- 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
