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

ColoredConsole - Log message not colored "strange characters" before and after message #4480

Closed
DaveSenn opened this issue Jun 30, 2021 · 4 comments

Comments

@DaveSenn
Copy link

NLog version:
NLog: 4.7.10
NLog.Extensions.Hosting: 1.7.3

Platform:
.NET 5 (5.0.7) - Console Application
Win10x64 21H1

Current NLog config (xml or C#, if relevant)

<?xml version="1.0" encoding="utf-8"?>

<nlog
  xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  autoReload="true"
  internalLogFile="C:\Log\App\NlogInternalLog.log"
  internalLogToConsole="false"
  internalLogToConsoleError="false"
  internalLogLevel="Warn">

  <extensions>
    <add assembly="NLog.Web.AspNetCore" />
  </extensions>

  <variable name="appName" value="App" />
  <variable name="logDirRoot" value="C:\Log\" />

  <targets>
    <!-- async file target for defaultFile  -->
    <target name="detailLogTarget" xsi:type="AsyncWrapper" overflowAction="Block" queueLimit="50000"
            batchSize="1000" timeToSleepBetweenBatches="0">
      <target xsi:type="File"
              optimizeBufferReuse="true"
              archiveAboveSize="20971520"
              archiveEvery="None"
              archiveNumbering="Sequence"
              fileAttributes="NotContentIndexed"
              encoding="utf-8"
              writeBom="true"
              lineEnding="LF"
              keepFileOpen="true"
              openFileCacheTimeout="30"
              concurrentWrites="false"
              bufferSize="65536"
              autoFlush="true"
              cleanupFileName="false"
              fileName="${logDirRoot}/${appName}/${appName}_${machinename}_${assembly-version}_${date:format=yyyy-MM-dd}.log"
              layout="${longdate}  ${pad:padding=5:padCharacter=0:inner=${threadid}}  !${pad:padding=-5:padCharacter= :inner=${level}}  ${message}  [${logger:shortName=true}]  ${event-properties:EventId} ${event-properties:EventId_Id}  ${aspnet-request-method} ${aspnet-request-url} ${aspnet-request-querystring} ${activityid:whenEmpty=${mdlc:item=RequestId:whenEmpty=${aspnet-TraceIdentifier}}} ${aspnet-TraceIdentifier:ignoreActivityId=true} ${aspnet-request-ip}
${onexception:inner=${newline}${exception:innerFormat=ToString,StackTrace:maxInnerExceptionLevel=20:format=ToString,StackTrace}}">
      </target>
    </target>
    <!--End async file target for defaultFile-->

    <!-- Console target -->
    <target name="consoleAsyncWrapper" xsi:type="AsyncWrapper" overflowAction="Block" queueLimit="50000"
            batchSize="1000" timeToSleepBetweenBatches="0">
      <target xsi:type="ColoredConsole" optimizeBufferReuse="true" detectConsoleAvailable="true"
              enableAnsiOutput="true"
              layout="${pad:padding=3:padCharacter=0:inner=${threadid}}  ${date:format=ss.ffff}  !${pad:padding=-5:padCharacter= :inner=${level}}  ${message}  [${logger:shortName=true}]
${onexception:inner=${newline}${exception:innerFormat=ToString,StackTrace:maxInnerExceptionLevel=20:format=ToString,StackTrace}}">
      </target>
    </target>
  </targets>

  <!--All logging rules (mapping between loggers and targets)-->
  <rules>
    <logger name="*" minlevel="Debug" writeTo="detailLogTarget"></logger>
    <logger name="*" minlevel="Debug" writeTo="consoleAsyncWrapper"></logger>
  </rules>
</nlog>

- Did you checked the Internal log?
No errors in log.

- Are there any workarounds? yes/no
I don't know any.

- What is the current result?
When running the application from VS or using the standard windows cmd/powershell shell the log messages are not displayed in color (see screenshot):
nocolor

Please note the "←[35m0" and "←[0m" at the start and end of the log entry.

Coloring works in ConEmu:
color

- What is the expected result?
Color output should work in all shells.

@welcome
Copy link

welcome bot commented Jun 30, 2021

Hi! Thanks for opening your first issue here! Please make sure to follow the issue template - so we could help you better!

@snakefoot
Copy link
Contributor

snakefoot commented Jun 30, 2021

You can enable global support for ANSI color codes by enabling Windows 10 VT (Virtual Terminal):

[HKEY_CURRENT_USER\Console]
"VirtualTerminalLevel"=dword:00000001

Alternative your application can call EnableVirtualTerminal() very early in the application:

    static class WindowsConsole
    {
        public static void EnableVirtualTerminal()
        {
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                return;

            var stdout = GetStdHandle(StandardOutputHandleId);
            if (stdout != (IntPtr)InvalidHandleValue && GetConsoleMode(stdout, out var mode))
            {
                SetConsoleMode(stdout, mode | EnableVirtualTerminalProcessingMode);
            }
        }

        const int StandardOutputHandleId = -11;
        const uint EnableVirtualTerminalProcessingMode = 4;
        const long InvalidHandleValue = -1;

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr GetStdHandle(int handleId);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool GetConsoleMode(IntPtr handle, out uint mode);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool SetConsoleMode(IntPtr handle, uint mode);
    }

But yes it is very annoying ANSI-Coloring is not just working out of the box everywhere. Maybe Windows 11 will be different.

See also: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences

@DaveSenn
Copy link
Author

I was still bothered by this "not working"... I found my problem:

enableAnsiOutput="true" was set on my target... setting this value to false results in correct output coloring without changing anything else.
I also tested the regestry key...which works as well

@snakefoot
Copy link
Contributor

Yes if you stop using enableAnsiOutput="true" then it will fallback to legacy Windows Console Coloring.

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

No branches or pull requests

2 participants