Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change console color per property #101

Open
apenni opened this issue Aug 15, 2020 · 2 comments
Open

Change console color per property #101

apenni opened this issue Aug 15, 2020 · 2 comments

Comments

@apenni
Copy link

apenni commented Aug 15, 2020

I'm looking for a way to set the console color per-property but this does not appear easy to do out-of-the-box.
The context is Serilog's Level text is not really nice-looking when abbreviated. "Information" is too long, and if abbreviated to "Info", then Serilog displays weird level names like "Eror" or "debu".
To counteract this I wrote my own Level enricher, however it no longer colorizes the console based on the level.
I could not find any easy way to do this, so I instead overrode the LogEventProperty with a custom wrapper to change the console color on Render:

        class ConsoleLogEventPropertyValue : LogEventPropertyValue
        {
            private readonly LogEventPropertyValue Value;
            private readonly ConsoleColor Color;

            public ConsoleLogEventPropertyValue(LogEventPropertyValue value, ConsoleColor color)
            {
                Value = value;
                Color = color;
            }

            public override void Render(TextWriter output, string format = null, IFormatProvider formatProvider = null)
            {
                var originalColor = Console.BackgroundColor;
                Console.BackgroundColor = Color;
                Value.Render(output, format, formatProvider);
                Console.BackgroundColor = originalColor;
            }
        }

        class ConsoleLogEventProperty : LogEventProperty
        {
            public ConsoleLogEventProperty(LogEventProperty property, ConsoleColor color)
                : base(property.Name, new ConsoleLogEventPropertyValue(property.Value, color))
            {
            }
        }

There are a few issues with this though:

  1. when Render is called, the value is rendered to the TextWriter, but it is not rendered to the console. This means setting the console color for the duration of Render doesn't actually affect when the text is written to console.

  2. I can work around this by leaving the console color set on calling Render (this is not great because ideally you want to reset the color, but it appears Serilog already resets the color on moving to the next property anyways). The trouble with this is that the rendered text is quoted, so whereas the level was previously rendered Error, not it is rendered "Error". From what I can tell Serilog does this because of the wrapped ConsoleLogEventPropertyValue. It's doing nothing but forwarding calls to the underlying value, so from this I surmise that the sink is actually reasoning about the type and not just the value and this affects whether quotations are emitted around the value.

Anyways, it'd be great not to have to go to these lengths just to get back the default coloring and to provide a mechanism for specifying coloring for each property.

@nblumhardt
Copy link
Member

Hi! Thanks for the message. Unfortunately I can't see any way to implement this in the short-term; if you're using this in one project only, copying in/forking the relevant console sink code and modifying it there will be your best bet. HTH!

@loop-evgeny
Copy link

I would also love to see something like this. I'm trying to migrate an application from NLog to Serilog, using Serilog.Sinks.Console 4.0.0. We have NLog configuration like this:

    <target name="logconsole" xsi:type="ColoredConsole" layout="...">
      <highlight-row condition="starts-with('${message}', 'START:')" foregroundColor="DarkGreen" />
      <highlight-row condition="starts-with('${message}', 'SUCCESS:')" foregroundColor="Green" />
      <highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" />
      <highlight-row condition="level == LogLevel.Error" foregroundColor="DarkRed" />
      ...

If there was some way to set the color per property I think that would allow migrating the NLog behavior (with some changes to the logging code to set the property).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants