-3

Kestrel in ASP.NET 5 Core MVC application in Debian writes escape codes to /var/log/syslog text file like

Apr  5 22:02:21 ew kestrel-store[31907]: #033[40m#033[32minfo#033[39m#033[22m#033[49m: Microsoft.Hosting.Lifetime[0]
Apr  5 22:02:21 ew kestrel-store[31907]:       Now listening on: http://localhost:5000
Apr  5 22:02:21 ew kestrel-store[31907]: #033[40m#033[32minfo#033[39m#033[22m#033[49m: Microsoft.Hosting.Lifetime[0]
Apr  5 22:02:21 ew kestrel-store[31907]:       Application started. Press Ctrl+C to shut down.
Apr  5 22:02:21 ew kestrel-store[31907]: #033[40m#033[32minfo#033[39m#033[22m#033[49m: Microsoft.Hosting.Lifetime[0]
Apr  5 22:02:21 ew kestrel-store[31907]:       Hosting environment: Production
Apr  5 22:02:21 ew kestrel-store[31907]: #033[40m#033[32minfo#033[39m#033[22m#033[49m: Microsoft.Hosting.Lifetime[0]
Apr  5 22:02:21 ew kestrel-store[31907]:       Content root path: /var/www/store5

This file is read by MVC controller and sent to user in view.

How to convert this file to html (for example, using colored or italic lines) or remove escape codes from file so that file is easier to read ? Or how to force kestrel output plain text without escape codes ?

Controller code:

public IActionResult Syslog()
{
    return new ContentResult()
    {
        Content = FileToStr("/var/log/syslog")
    };
}

static string FileToStr(string cFileName)
{
    StreamReader oReader = File.OpenText(cFileName);
    string lcString = oReader.ReadToEnd();
    oReader.Close();
    return lcString;
}

Escape sequence is defined as:

  1. One \x1b
  2. One [
  3. Zero or more parameter bytes 0x30-0x3f
  4. Zero or more intermediate bytes 0x20-0x2f
  5. One final byte 0x40-0x7f

Update

Code in answer adds span to start of every line and does not remove escape sequences:

<span style="color: blue">Apr  8 00:00:05 ew rsyslogd:  [origin software="rsyslogd" swVersion="8.1901.0" x-pid="573" x-info="https://www.rsyslog.com"] rsyslogd was HUPed</span>
<span style="color: blue">Apr  8 00:00:05 ew systemd[1]: logrotate.service: Succeeded.</span>
<span style="color: blue">Apr  8 00:00:05 ew systemd[1]: Started Rotate log files.</span>
<span style="color: blue">Apr  8 00:00:10 ew colord[1172]: failed to get session [pid 23699]: No data available</span>
<span style="color: blue">Apr  8 00:00:12 ew colord[1172]: failed to get session [pid 23699]: No data available</span>
<span style="color: blue">Apr  8 00:00:14 ew colord[1172]: failed to get session [pid 23699]: No data available</span>
<span style="color: blue">Apr  8 00:05:01 ew CRON[23838]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)</span>
<span style="color: blue">Apr  8 00:15:01 ew CRON[24082]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)</span>
<span style="color: blue">Apr  8 00:17:01 ew CRON[24128]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)</span>
<span style="color: blue">Apr  8 00:21:49 ew kestrel-store[22413]: #033[40m#033[32minfo#033[39m#033[22m#033[49m: WebOptimizer.AssetMiddleware[1000]</span>
<span style="color: blue">Apr  8 00:21:49 ew kestrel-store[22413]:       Request started for '/c/version.js'</span>
<span style="color: blue">Apr  8 00:21:49 ew kestrel-store[22413]: #033[41m#033[30mfail#033[39m#033[22m#033[49m: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]</span>
<span style="color: blue">Apr  8 00:21:49 ew kestrel-store[22413]:       An unhandled exception has occurred while executing the request.</span>

Expected output is:

enter image description here

Andrus
  • 26,339
  • 60
  • 204
  • 378
  • Please give an idea, how the output should look like. – Andy A. Apr 06 '21 at 06:48
  • Maybe `green line` for green lines and `color:red´ for red lines. Or escape sequences should simply removed from output text – Andrus Apr 06 '21 at 08:05
  • Sure, but whitch line should be green and whitch blue and why? I think the problem is not how to format the lines but to find out whitch line and parts of the line should formatted. Eg. with an regex: Lines with `.*: #033` should be green so substitude em with `$&`... But I think this is not what youre looking for – Andy A. Apr 06 '21 at 08:53
  • Matching colors are described in https://stackoverflow.com/questions/4842424/list-of-ansi-color-escape-sequences . Yes, this is what I'm looking. Find sequence starting with escape character and discard it or convert line to html wrapping colored parts to span elements. It looks like sequences are variable length. Alternately looking for disabling outputting of escape sequences to syslog – Andrus Apr 06 '21 at 10:59
  • Maybe you can use a tiny **perl** script.Open the file and a new one, put html header in new file, read your textfile line by line and set them between a `...` and finally write the html footer. Quite easy, I think. – Andy A. Apr 06 '21 at 11:53
  • https://superuser.com/questions/380772/removing-ansi-color-codes-from-text-stream provides perl script. How convert this to C# so that invoking perl in not reqiuried – Andrus Apr 06 '21 at 15:15
  • @AndyU. I updated question and added escape sequence definiton and controller code. Maybe some c# regexp can used to clean it or even add html color styles. – Andrus Apr 06 '21 at 15:35
  • At moment I don't have a c# compiler... But it should be possible to use the expressions in c# too. Maybe there are a little differences (in lookarounds and with groupnames) – Andy A. Apr 07 '21 at 10:38
  • There are large number of online c# compilers, like https://rextester.com/ – Andrus Apr 07 '21 at 21:20
  • Please show an explicete example what should happen! So you don't want to mark a whole line. But what should the `` enclose? Should it start on a escape sequence and end on a corresponding one? If it should start at "[", then it might be easy, but what is about the others? – Andy A. Apr 09 '21 at 05:37
  • Added expected output to question. `` should used for green part. Green is started by escape sequence and ended by new escape sequence. Question contains reference to escape sequence specifications. Probably only green and red colors are used in log files. – Andrus Apr 09 '21 at 15:38

1 Answers1

0

Hope this is helpful. I used rextester.com write a formatted code. But tests with files doesn't work there.

Please correct this post if necessary. Also its not the shortest version, but I think its most clear.

//Rextester.Program.Main is the entry point for your code. Don't change it.
//Microsoft (R) Visual C# Compiler version 2.9.0.63208 (958f2354)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            using (var reader = new StreamReader(@"c:\your_input_file.txt"))
            using (var writer = new StreamWriter(@"c:\your_output_file.html"))
            {
                WriteHtmlHeader(writer);
                string line;
                while((line = reader.ReadLine()) != null)
                {
                    line = AddSpan(line);
                }
                WriteHtmlFooter(writer);
            }
        }
        
        private static void WriteHtmlHeader(StreamWriter outfile)
        {
            // writing all the header and the start of body...
            // you can take it from another file
        }
        
        private static void WriteHtmlFooter(StreamWriter outfile)
        {
            // writing the footer of your html file
        }
        
        private static string AddSpan(string line)
        {
            if (Regex.IsMatch(line, "\x1b"))
            {
                return AddStyledSpan(line, "color: green");
            }
            else if (Regex.IsMatch(line, "\["))
            {
                return AddStyledSpan(line, "color: blue");
            }
            // ...
            else
            {
                // Mark this span as error or standard
                return AddStyledSpan(line, "color: red");
            }
        }
            
        private static string AddStyledSpan(string line, string style)
        {
            return "<span style=\"" + style + "\">" + line + "</span>";
        }
    }
}

Hope this helps. Also look at regex101 - online regex tester and debuggex - regex visualization. (But use it carefully, regular expressions works somtimes different).

Andy A.
  • 1,392
  • 5
  • 15
  • 28
  • Line `else if (Regex.IsMatch(line, "["))` causes error `Invalid pattern '[' at offset 1. Unterminated [] set.` . `[` is invalid regexp – Andrus Apr 08 '21 at 09:55
  • In code in question only part of line (log entry type) is colored: `#033[40m#033[32minfo#033[39m#033[22m#033[49m:` info is green, error is red. It looks like code in answer tries to color whole line – Andrus Apr 08 '21 at 10:37
  • It adds span to start of every line and does not remove escape sequences. I updated question with output. – Andrus Apr 08 '21 at 20:42
  • To give examples what happen if using this code in your question is quite confusing. I set a comment on your question. – Andy A. Apr 09 '21 at 05:30